@cmdoss/walrus-site-builder-react 2.6.0 → 2.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +84 -63
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["allDomains: SuiNsDomain[]","cursor: string | null | undefined","mainPackage","domains","content","dynamicFields: DynamicFieldInfo[]","cursor: string | null","resources: ResourceData[]","result: ResourceData","assets: IAsset[]","content","title","description","link","item","sdk: IWalrusSiteBuilderSdk | undefined","title","link","description","siteMetadata: SiteMetadata","siteId","cursor: string | null | undefined","error","pricePerYear","totalPrice","paymentCoin:\n | ReturnType<typeof transaction.object>\n | typeof transaction.gas","registerParams: {\n domain: string\n years: number\n coinConfig: typeof coinConfig\n coin: typeof paymentCoin\n priceInfoObjectId?: string\n }","r","input","r","input","defaultIcons: Record<BannerVariant, ReactNode>","Banner: FC<BannerProps>","content","title","description","link","closeButton","Button: FC<ButtonProps>","FlickeringGrid: FC<FlickeringGridProps>","color","width","height","container","animationFrameId: number","gridParams: ReturnType<typeof setupCanvas>","Label: FC<LabelProps>","labelStyle","Textarea: FC<TextareaProps>","textareaStyle","Step: FC<StepProps>","styles.stepContainer","styles.stepIndicator","styles.stepIndicatorCompleted","styles.stepIndicatorActive","styles.stepIndicatorPending","styles.stepSpinner","styles.stepDot","styles.stepLine","styles.stepLineCompleted","styles.stepLinePending","styles.stepLabel","styles.stepLabelActive","styles.stepLabelInactive","title","Stepper: FC<StepperProps>","styles.stepperContainer","styles.stepperWrapper","ExtendTimeDialog: FC<ExtendTimeDialogProps>","cursor: string | null | undefined","styles.overlay","styles.content","styles.loadingOverlay","styles.loadingContent","styles.spinner","styles.header","styles.title","styles.description","styles.closeButton","styles.body","styles.formSection","styles.fieldGroup","styles.dateInputWrapper","styles.inputError","styles.infoText","styles.errorText","styles.summaryGrid","styles.summaryCard","styles.summaryHeader","styles.summaryContent","styles.summaryValue","styles.summarySubtext","styles.summaryError","styles.costSection","styles.costHeader","styles.estimatedBadge","styles.costContent","styles.costRow","styles.costLabel","styles.costValue","styles.costLoading","styles.costWarning","styles.costDivider","styles.costError","styles.footer","PublishMenu: FC<PublishMenuProps>","styles.content","styles.header","styles.title","styles.description","styles.link","styles.separator","styles.item","styles.footer","styles.buttonGroup","PublishModal: FC<PublishModalProps>","title","description","selectedDate","styles.overlay","styles.content","styles.title","styles.description","styles.twoColumnSection","styles.leftColumn","styles.previewContainer","styles.previewArea","styles.previewImageWrapper","styles.previewImage","styles.flickeringGrid","styles.maskLayer","styles.placeholderContent","styles.placeholderIcon","styles.editButton","styles.storageCostSection","styles.storageCostSummary","styles.storageCostLabel","styles.storageCostValue","styles.storageDetailsBox","styles.rightColumn","styles.metadataFields","styles.dialogRightColumn","styles.fieldLabel","styles.charCount","styles.section","styles.buttonGroup","styles.spinner","styles.dialogOverlay","styles.dialogContent","styles.dialogHeader","styles.dialogBodyTwoColumn","styles.uploadAreaSquare","styles.uploadPlaceholder","styles.dialogFooter","CardBackground: FC","SuiNSLogo: FC","DomainCardSvg: FC<DomainCardSvgProps>","RegisterSuiNsDialog: FC<RegisterSuiNsDialogProps>","styles.overlay","styles.content","styles.header","styles.title","styles.description","styles.body","SuiNsModal: FC<SuiNsModalProps>","styles.overlay","styles.content","styles.header","styles.title","styles.description","styles.body","styles.section","styles.sectionTitle","styles.domainList","styles.domainItem","styles.link","styles.loadingSpinner","styles.domainCardGrid","styles.domainCard","styles.domainCardBg","DomainCardSvg","styles.domainName","styles.domainExpiry","ThemeProvider: FC<ThemeProviderProps>","PublishButton: FC<Props>","PublishMenu","PublishModal","SuiNsModal","ExtendTimeDialog","UpdateMetadataModal: FC<UpdateMetadataModalProps>","description","e","error","styles.overlay","styles.content","styles.header","styles.title","styles.description","styles.closeButton","styles.loadingContainer","styles.spinner","styles.body","styles.fieldLabel","styles.optionalLabel","styles.uploadModeToggle","styles.uploadModeButtonActive","styles.uploadModeButton","styles.uploadArea","styles.previewImage","styles.uploadPlaceholder","styles.uploadHint","styles.errorText","styles.urlInputContainer","styles.imagePreview","styles.urlInputWrapper","styles.charCount","styles.warningBanner","styles.errorBanner","styles.footer"],"sources":["../src/lib/nonNull.ts","../src/queries/keys.ts","../src/queries/suins-domains.query.ts","../src/queries/walrus-site.query.ts","../src/queries/zenfs-files.query.ts","../src/stores/site-domain.store.ts","../src/stores/site-metadata.store.ts","../src/lib/result.ts","../src/stores/site-publishing.store.ts","../src/hooks/useTransactionExecutor.ts","../src/hooks/useSitePublishing.ts","../src/hooks/useEpochDuration.ts","../src/hooks/useSuiNsRegistration.ts","../src/hooks/useUpdateSiteMetadata.ts","../src/hooks/useZenFsWorkspace.ts","../src/queries/storage-cost.query.ts","../../../node_modules/.pnpm/@vanilla-extract+recipes@0.5.7_@vanilla-extract+css@1.18.0/node_modules/@vanilla-extract/recipes/dist/createRuntimeFn-166334d7.cjs.prod.js","../../../node_modules/.pnpm/@vanilla-extract+recipes@0.5.7_@vanilla-extract+css@1.18.0/node_modules/@vanilla-extract/recipes/createRuntimeFn/dist/vanilla-extract-recipes-createRuntimeFn.cjs.prod.js","../../../node_modules/.pnpm/@vanilla-extract+recipes@0.5.7_@vanilla-extract+css@1.18.0/node_modules/@vanilla-extract/recipes/dist/createRuntimeFn-2f250aaf.cjs.dev.js","../../../node_modules/.pnpm/@vanilla-extract+recipes@0.5.7_@vanilla-extract+css@1.18.0/node_modules/@vanilla-extract/recipes/createRuntimeFn/dist/vanilla-extract-recipes-createRuntimeFn.cjs.dev.js","../../../node_modules/.pnpm/@vanilla-extract+recipes@0.5.7_@vanilla-extract+css@1.18.0/node_modules/@vanilla-extract/recipes/createRuntimeFn/dist/vanilla-extract-recipes-createRuntimeFn.cjs.js","../src/components/ui/Banner.css.ts","../src/components/ui/Banner.tsx","../src/components/ui/Button.css.ts","../src/components/ui/Button.tsx","../src/components/ui/FlickeringGrid.css.ts","../src/components/ui/FlickeringGrid.tsx","../src/components/ui/Input.css.ts","../src/components/ui/Input.tsx","../src/components/ui/Stepper.css.ts","../src/components/ui/Stepper.tsx","../src/components/extend-time-dialog/ExtendTimeDialog.css.ts","../src/components/extend-time-dialog/ExtendTimeDialog.tsx","../src/components/publish-menu/PublishMenu.css.ts","../src/components/publish-menu/PublishMenu.tsx","../src/components/publish-modal/PublishModal.css.ts","../src/components/publish-modal/PublishModal.tsx","../src/components/suins-modal/DomainCardSvg.tsx","../src/components/suins-modal/SuiNsModal.css.ts","../src/components/suins-modal/RegisterSuiNsDialog.tsx","../src/components/suins-modal/SuiNsModal.tsx","../src/components/ThemeProvider.tsx","../src/components/PublishButton.tsx","../src/components/update-metadata-modal/UpdateMetadataModal.css.ts","../src/components/update-metadata-modal/UpdateMetadataModal.tsx"],"sourcesContent":["export function nonNull<T>(value: T | null | undefined): value is T {\n return value !== null && value !== undefined\n}\n","export const queryKeys = {\n suinsDomains: (address: string | undefined, network: string) =>\n ['suins-domains', address, network] as const,\n suinsDomainDetail: (name: string, network: string) =>\n ['suins-domain-detail', name, network] as const,\n walrusSite: (siteId: string | undefined) => ['walrus-site', siteId] as const,\n walrusSites: (address: string | undefined, network: string) =>\n ['walrus-sites', address, network] as const,\n storageCost: (fileSize: number | null, epochs: number) =>\n ['storage-cost', fileSize, epochs] as const\n} as const\n","import type { SuiClient } from '@mysten/sui/client'\nimport { mainPackage, SuinsClient } from '@mysten/suins'\nimport type { WalletAccount } from '@mysten/wallet-standard'\nimport { type QueryClient, useQueries, useQuery } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { nonNull } from '~/lib/nonNull'\nimport { queryKeys } from './keys'\n\nexport type SuiNsDomain = {\n name: string\n objectId: string\n expiresAt?: number\n}\n\nexport interface SuiNsDomainDetail {\n name: string\n avatar?: string\n expirationTimestampMs?: number\n nftId: string\n walrusSiteId?: string\n targetAddress?: string\n walrusSiteUrl: string\n}\n\nexport interface ISuiNsDomainQuery {\n isLoading: boolean\n isError: boolean\n data: Array<SuiNsDomainDetail>\n}\n\nexport function useSuiNsDomainsQuery(\n currentAccount: WalletAccount | null,\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n }\n): ISuiNsDomainQuery {\n const { suiClient, queryClient } = clients\n const { network } = suiClient\n const suinsClient = useMemo(\n () =>\n new SuinsClient({\n network: suiClient.network === 'mainnet' ? 'mainnet' : 'testnet',\n client: suiClient\n }),\n [suiClient]\n )\n\n const onchainDataQuery = useQuery(\n {\n queryKey: queryKeys.suinsDomains(currentAccount?.address, network),\n queryFn: async () => {\n if (!currentAccount?.address) return []\n\n try {\n let allDomains: SuiNsDomain[] = []\n let hasNextPage = true\n let cursor: string | null | undefined\n\n // Get the appropriate SuiNS package ID based on network\n const suinsPackageId =\n mainPackage[network as keyof typeof mainPackage]?.packageIdV1\n\n if (!suinsPackageId) {\n console.warn(`SuiNS not supported on network: ${network}`)\n return []\n }\n\n console.log('suinsPackageId', suinsPackageId)\n\n // Fetch all SuiNS domain NFTs owned by the address\n console.log(\n 'suinsPackageId',\n `${suinsPackageId}::suins_registration::SuinsRegistration`\n )\n while (hasNextPage) {\n const response = await suiClient.getOwnedObjects({\n owner: currentAccount.address,\n filter: {\n StructType: `${suinsPackageId}::suins_registration::SuinsRegistration`\n },\n options: { showContent: true, showType: true, showDisplay: true },\n cursor\n })\n\n console.log('response', response)\n\n // Extract domain data from the response\n const domains = response.data\n .filter(obj => obj.data?.content?.dataType === 'moveObject')\n .map(obj => {\n const content = obj.data?.content\n const fields =\n content && 'fields' in content\n ? (content.fields as Record<string, unknown>)\n : {}\n\n return {\n name: (fields?.domain_name as string) || '',\n objectId: obj.data?.objectId || '',\n expiresAt: fields?.expiration_timestamp_ms\n ? Number(fields.expiration_timestamp_ms)\n : undefined\n }\n })\n .filter(domain => domain.name) // Filter out any invalid entries\n\n allDomains = [...allDomains, ...domains]\n hasNextPage = response.hasNextPage\n cursor = response.nextCursor\n }\n\n return allDomains\n } catch (error) {\n console.error('Error fetching SuiNS domains:', error)\n return []\n }\n },\n enabled: !!currentAccount?.address,\n staleTime: 1000 * 60 * 5, // 5 minutes\n retry: 2,\n retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, 30000)\n },\n queryClient\n )\n\n // TODO: improve this with batching if supported by SuinsClient\n const domains = useQueries(\n {\n queries:\n onchainDataQuery.data?.map(domain => ({\n queryKey: queryKeys.suinsDomainDetail(domain.name, network),\n queryFn: async () => await suinsClient?.getNameRecord(domain.name),\n enabled: !!suinsClient && !!domain.name\n })) ?? []\n },\n queryClient\n )\n\n const isLoading = useMemo(\n () => onchainDataQuery.isLoading || domains.some(d => d.isLoading),\n [onchainDataQuery.isLoading, domains]\n )\n const isError = useMemo(\n () => onchainDataQuery.isError || domains.some(d => d.isError),\n [onchainDataQuery.isError, domains]\n )\n const data = useMemo(\n () =>\n domains\n .map(d => d.data)\n .filter(nonNull)\n .map(\n r =>\n <SuiNsDomainDetail>{\n name: r.name.slice(0, -4), // remove \".sui\" suffix\n avatar: r.avatar,\n expirationTimestampMs: Number(r.expirationTimestampMs),\n nftId: r.nftId,\n walrusSiteId: r.walrusSiteId,\n targetAddr: r.targetAddress,\n walrusSiteUrl:\n network === 'mainnet'\n ? `https://${r.name.slice(0, -4)}.wal.app`\n : `http://${r.name.slice(0, -4)}.localhost:3003`\n }\n ),\n [domains, network]\n )\n\n return { isLoading, isError, data }\n}\n","import { mainPackage } from '@cmdoss/walrus-site-builder'\nimport type {\n DynamicFieldInfo,\n ObjectResponseError,\n SuiClient\n} from '@mysten/sui/client'\nimport { type QueryClient, useQuery } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { queryKeys } from './keys'\n\ninterface WalrusSiteDisplayData {\n creator: string\n description: string\n image_url: string\n link: string\n project_url: string\n name: string\n}\n\ninterface ResourceChainValue {\n type: string\n fields: {\n blob_hash: string\n blob_id: string\n headers: {\n type: string\n fields: {\n contents: Array<{\n type: string\n fields: {\n key: string\n value: string\n }\n }>\n }\n }\n path: string\n range: null | unknown\n }\n}\n\ninterface ResourceData {\n blob_hash: string\n blob_id: string\n headers: { key: string; value: string }[]\n path: string\n // range: null | unknown // Not used currently\n}\n\ninterface WalrusSiteData extends WalrusSiteDisplayData {\n id: string\n resources: ResourceData[]\n}\n\nfunction handleError(error: ObjectResponseError): never {\n switch (error.code) {\n case 'deleted':\n throw new Error('Walrus site has been deleted')\n case 'notExists':\n throw new Error('Walrus site does not exist')\n case 'displayError':\n throw new Error('Failed to fetch Walrus site display data')\n case 'dynamicFieldNotFound':\n throw new Error('Walrus site dynamic field not found')\n default:\n throw new Error(`Unknown error when fetching Walrus site!`)\n }\n}\n\nasync function fetchSiteDynamicFields(\n suiClient: SuiClient,\n siteId: string\n): Promise<DynamicFieldInfo[]> {\n const dynamicFields: DynamicFieldInfo[] = []\n let cursor: string | null = null\n while (true) {\n const page = await suiClient.getDynamicFields({ parentId: siteId, cursor })\n cursor = page.nextCursor\n dynamicFields.push(...page.data)\n if (!page.hasNextPage) break\n }\n return dynamicFields\n}\n\nasync function fetchSiteResources(\n suiClient: SuiClient,\n siteId: string,\n packageId: string\n) {\n const dynamicFields = await fetchSiteDynamicFields(suiClient, siteId)\n\n // console.log('🔍 Dynamic fields found:', dynamicFields)\n\n const resourcePaths = dynamicFields\n .filter(f => f.objectType === `${packageId}::site::Resource`)\n .filter(r => r.name.type === `${packageId}::site::ResourcePath`)\n\n // console.log('🔍 Resource paths found:', resourcePaths)\n\n // Fetch resource details\n const resources: ResourceData[] = []\n for (const rp of resourcePaths) {\n const resObj = await suiClient.getObject({\n id: rp.objectId,\n options: { showContent: true }\n })\n\n if (resObj.data?.content?.dataType !== 'moveObject')\n throw new Error('Invalid resource object data type')\n\n const fields = resObj.data?.content?.fields\n if (Array.isArray(fields)) throw new Error('Invalid resource object fields')\n if (!('value' in fields))\n throw new Error('Invalid resource object fields value')\n\n // console.log('🔍 Resource object fields:', fields)\n\n const resourceValue = fields.value as ResourceChainValue\n const result: ResourceData = {\n blob_hash: resourceValue.fields.blob_hash,\n blob_id: resourceValue.fields.blob_id,\n headers: resourceValue.fields.headers.fields.contents.map(c => c.fields),\n path: resourceValue.fields.path\n }\n resources.push(result)\n }\n return resources\n}\n\nasync function fetchWalrusSiteData(\n suiClient: SuiClient,\n id: string,\n packageId: string\n): Promise<WalrusSiteData> {\n // console.log('🔍 Fetching Walrus site data for ID:', id, packageId)\n // Fetch site object and display data\n const objRes = await suiClient.getObject({\n id,\n options: { showDisplay: true }\n })\n\n const error = objRes.data?.display?.error ?? objRes.error\n if (error) handleError(error)\n\n const data = objRes.data?.display?.data\n if (!data) throw new Error('No data returned for Walrus site')\n const siteData = data as unknown as WalrusSiteDisplayData\n // console.log('🔍 Fetched Walrus site display data:', siteData)\n const resources = await fetchSiteResources(suiClient, id, packageId)\n // console.log('🔍 Fetched Walrus site resources:', resources)\n const finalSiteData = { id, ...siteData, resources }\n // console.log('🔍 Fetched Walrus site data:', finalSiteData)\n return finalSiteData\n}\n\nexport function useWalrusSiteQuery(\n id: string | undefined,\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n }\n) {\n const { network } = clients.suiClient\n const packageId = useMemo(\n () => mainPackage[network as keyof typeof mainPackage].packageId,\n [network]\n )\n\n return useQuery(\n {\n queryKey: queryKeys.walrusSite(id),\n queryFn: async () => {\n if (!id) throw new Error('No site ID provided')\n return fetchWalrusSiteData(clients.suiClient, id, packageId)\n },\n enabled: !!id\n },\n clients.queryClient\n )\n}\n\nasync function fetchWalrusSitesListPaginated(\n suiClient: SuiClient,\n address: string,\n packageId: string,\n limit?: number,\n cursorParam?: string | null\n): Promise<{\n sites: WalrusSiteData[]\n nextCursor: string | null\n hasNextPage: boolean\n}> {\n try {\n const response = await suiClient.getOwnedObjects({\n owner: address,\n filter: {\n StructType: `${packageId}::site::Site`\n },\n options: { showDisplay: true, showType: true },\n cursor: cursorParam,\n limit: limit || 50\n })\n\n // console.log('🔍 Response:', response)\n\n if (!response.data || response.data.length === 0) {\n return {\n sites: [],\n nextCursor: response.nextCursor || null,\n hasNextPage: response.hasNextPage\n }\n }\n\n const siteObjects = response.data\n .filter(obj => {\n // Filter for Site objects\n if (!obj.data) {\n console.warn('Object missing data:', obj)\n return false\n }\n\n // Check for display errors\n if (obj.data.display?.error) {\n console.warn(\n 'Display error for site:',\n obj.data.objectId,\n obj.data.display.error\n )\n return false\n }\n\n // Verify it's a Site type\n const type = obj.data.type\n if (!type || type !== `${packageId}::site::Site`) {\n return false\n }\n\n // Must have objectId\n if (!obj.data.objectId) {\n console.warn('Object missing objectId:', obj)\n return false\n }\n\n return true\n })\n .map(obj => {\n // obj.data is guaranteed to exist due to filter above\n if (!obj.data) return null\n\n // Access display data from obj.data.display.data\n const display = obj.data.display?.data\n if (!display) {\n console.warn('No display data for site:', obj.data.objectId)\n return null\n }\n\n const displayData = display as unknown as WalrusSiteDisplayData\n\n // Validate required fields\n if (!displayData.name) {\n console.warn('Site missing name:', obj.data.objectId)\n return null\n }\n\n return {\n id: obj.data.objectId,\n name: displayData.name,\n description: displayData.description || '',\n image_url: displayData.image_url || '',\n link: displayData.link || '',\n project_url: displayData.project_url || '',\n creator: displayData.creator || '',\n resources: [] as ResourceData[]\n }\n })\n .filter((site): site is WalrusSiteData => site !== null)\n\n return {\n sites: siteObjects,\n nextCursor: response.nextCursor || null,\n hasNextPage: response.hasNextPage\n }\n } catch (error) {\n console.error('Error fetching Walrus sites list:', error)\n throw error\n }\n}\n\nexport function useWalrusSitesQuery(\n address: string | undefined,\n options: {\n limit?: number\n cursor?: string | null\n },\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n }\n) {\n const { suiClient, queryClient } = clients\n const { network } = suiClient\n const packageId = useMemo(\n () => mainPackage[network as keyof typeof mainPackage].packageId,\n [network]\n )\n\n console.log('🔍 Fetching Walrus sites list for address:', address, packageId)\n\n const sitesListQuery = useQuery(\n {\n queryKey: [\n ...queryKeys.walrusSites(address, network),\n options?.cursor,\n options?.limit\n ],\n queryFn: async () => {\n if (!address) return { sites: [], nextCursor: null, hasNextPage: false }\n return fetchWalrusSitesListPaginated(\n suiClient,\n address,\n packageId,\n options?.limit,\n options?.cursor\n )\n },\n enabled: !!address,\n staleTime: 1000 * 60 * 5, // 5 minutes\n retry: 2,\n retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, 30000)\n },\n queryClient\n )\n\n // Return paginated data directly - no need to fetch full details for list view\n return {\n data: sitesListQuery.data?.sites ?? [],\n nextCursor: sitesListQuery.data?.nextCursor ?? null,\n hasNextPage: sitesListQuery.data?.hasNextPage ?? false,\n isLoading: sitesListQuery.isLoading,\n isError: sitesListQuery.isError,\n error: sitesListQuery.error\n }\n}\n","import type { ZenFsFileManager } from '@cmdoss/file-manager'\nimport {\n getSHA256Hash,\n type IAsset,\n sha256ToU256\n} from '@cmdoss/walrus-site-builder'\nimport { type QueryClient, useQuery } from '@tanstack/react-query'\n\nexport function useZenfsFilesQuery(\n fm: ZenFsFileManager | null,\n clients: {\n queryClient: QueryClient\n }\n) {\n const { queryClient } = clients\n return useQuery(\n {\n queryKey: ['zenfs-files', fm?.workspaceDir],\n queryFn: async () => {\n if (!fm) return []\n const files = await fm.listFiles()\n const assets: IAsset[] = []\n for (const path of files) {\n const content = await fm?.readFile(path)\n if (!content) continue\n const hash = await getSHA256Hash(content)\n const hashU256 = sha256ToU256(hash)\n assets.push({ path, content, hashU256 })\n }\n return assets\n },\n enabled: !!fm,\n staleTime: 5 * 60 * 1000 // 5 minutes\n },\n queryClient\n )\n}\n","import { atom } from 'nanostores'\n\nexport const isDomainDialogOpen = atom(false)\nexport const isAssigningDomain = atom(false)\nexport const isRegisterSuiNSDomainDialogOpen = atom(false)\nexport const isExtendTimeDialogOpen = atom(false)\nexport const isUpdateMetadataModalOpen = atom(false)\n","import { atom, computed } from 'nanostores'\n\nconst DEFAULT_TITLE = 'wal-0'\nconst DEFAULT_DESCRIPTION = 'WAL-0 Generated Project'\n\nclass SiteMetadata {\n title = atom(DEFAULT_TITLE)\n description = atom(DEFAULT_DESCRIPTION)\n imageUrl = atom<string | File | null>('https://www.walrus.xyz/walrus-site')\n link = atom<string>('')\n projectUrl = atom<string>('')\n epochs = atom(5)\n deletable = atom(false)\n loading = atom(false)\n suiNSUrl = atom<Array<{ suins: string; nftId: string }>>([])\n\n // Site data\n originalTitle = atom(DEFAULT_TITLE)\n originalDescription = atom(DEFAULT_DESCRIPTION)\n originalImageUrl = atom<string | File | null>(\n 'https://www.walrus.xyz/walrus-site'\n )\n originalLink = atom<string>('')\n originalProjectUrl = atom<string>('')\n originalEpochs = atom(5)\n originalSuiNSUrl = atom<Array<{ suins: string; nftId: string }>>([])\n\n // Derived/computed state\n isDirty = computed(\n [\n this.title,\n this.description,\n this.imageUrl,\n this.link,\n this.projectUrl,\n this.epochs,\n this.suiNSUrl,\n this.originalTitle,\n this.originalDescription,\n this.originalImageUrl,\n this.originalLink,\n this.originalProjectUrl,\n this.originalEpochs,\n this.originalSuiNSUrl\n ],\n (\n title,\n description,\n iconUrl,\n link,\n projectUrl,\n epochs,\n suiNSUrl,\n originalTitle,\n originalDescription,\n originalIcon,\n originalLink,\n originalProjectUrl,\n originalEpochs,\n originalSuiNSUrl\n ) =>\n title !== originalTitle ||\n description !== originalDescription ||\n (iconUrl ?? null) !== (originalIcon ?? null) ||\n link !== originalLink ||\n projectUrl !== originalProjectUrl ||\n epochs !== originalEpochs ||\n JSON.stringify(\n suiNSUrl.sort((a, b) => a.nftId.localeCompare(b.nftId))\n ) !==\n JSON.stringify(\n originalSuiNSUrl.sort((a, b) => a.nftId.localeCompare(b.nftId))\n )\n )\n /**\n * Computed URL for displaying the image preview\n */\n imageDisplayUrl = computed([this.imageUrl], imageUrl => {\n if (!imageUrl) return null\n if (typeof imageUrl === 'string') return imageUrl\n return URL.createObjectURL(imageUrl) // TODO: revoke when not used\n })\n\n commitChanges() {\n this.originalTitle.set(this.title.get())\n this.originalDescription.set(this.description.get())\n this.originalImageUrl.set(this.imageUrl.get())\n this.originalLink.set(this.link.get())\n this.originalProjectUrl.set(this.projectUrl.get())\n this.originalEpochs.set(this.epochs.get())\n this.originalSuiNSUrl.set(this.suiNSUrl.get().map(item => ({ ...item })))\n }\n\n reset() {\n this.title.set(this.originalTitle.get())\n this.description.set(this.originalDescription.get())\n this.imageUrl.set(this.originalImageUrl.get())\n this.link.set(this.originalLink.get())\n this.projectUrl.set(this.originalProjectUrl.get())\n this.epochs.set(this.originalEpochs.get())\n this.suiNSUrl.set(this.originalSuiNSUrl.get().map(item => ({ ...item })))\n this.loading.set(false)\n }\n\n cancelEdit = () => this.reset()\n}\n\nexport const siteMetadataStore = new SiteMetadata()\n","export interface TOk<T> {\n ok: true\n data: T\n error?: never\n}\nexport interface TFailed<E> {\n ok: false\n error: E\n data?: never\n}\nexport type TResult<T = void, E = string> = TOk<T> | TFailed<E>\n\nexport function ok(): TOk<void>\nexport function ok<T>(data: T): TOk<T>\nexport function ok<T>(data?: T): TOk<T> {\n return { ok: true, data: data as T }\n}\nexport function failed<E>(error: E): TFailed<E> {\n return { ok: false, error }\n}\n\n// ###########################################################################\n// # API specific result type and helpers\n// ###########################################################################\n\nexport interface TApiError {\n code: string\n message: string\n stack?: string\n}\nexport const apiFailed = failed<TApiError>\nexport type TApiResult<T> = TResult<T, TApiError>\n","import type {\n IAsset,\n ICertifiedBlob,\n IUpdateWalrusSiteFlow,\n IWalrusSiteBuilderSdk\n} from '@cmdoss/walrus-site-builder'\nimport { atom, computed } from 'nanostores'\nimport { failed, ok, type TResult } from '~/lib/result'\nimport { isDomainDialogOpen } from './site-domain.store'\nimport { siteMetadataStore } from './site-metadata.store'\n\nexport enum DeploySteps {\n Idle,\n Prepared,\n Uploaded,\n Certified,\n Deployed\n}\n\nexport enum DeploymentStatus {\n Idle,\n /** Preparing assets for upload */\n Preparing,\n /** Assets have been prepared */\n Prepared,\n /** Uploading assets to the network */\n Uploading,\n /** Assets have been uploaded */\n Uploaded,\n /** Certify uploaded assets */\n Certifying,\n /** Assets have been certified */\n Certified,\n /** Deploy site metadata */\n Deploying,\n /** Site has been deployed */\n Deployed\n}\n\nexport interface SiteMetadata {\n id?: string\n title?: string\n description?: string\n link?: string\n projectUrl?: string\n imageUrl?: string\n creator?: string\n}\nexport interface SiteMetadataUpdate extends Omit<SiteMetadata, 'imageUrl'> {\n imageUrl?: string | File\n}\n\nexport interface DeploymentHandlers {\n prepareAssets: () => Promise<void>\n uploadAssets: (epoch: number | 'max', permanent?: boolean) => Promise<void>\n certifyAssets: () => Promise<void>\n updateSite: () => Promise<void>\n}\n\nclass SitePublishingStore {\n // Deployment state\n deployStatus = atom(DeploymentStatus.Idle)\n deploymentStepIndex = computed([this.deployStatus], s => {\n switch (s) {\n case DeploymentStatus.Idle:\n case DeploymentStatus.Preparing:\n return 0\n case DeploymentStatus.Prepared:\n case DeploymentStatus.Uploading:\n return 1\n case DeploymentStatus.Uploaded:\n case DeploymentStatus.Certifying:\n return 2\n case DeploymentStatus.Certified:\n case DeploymentStatus.Deploying:\n return 3\n case DeploymentStatus.Deployed:\n return 4\n default:\n return 0\n }\n })\n\n // UI state\n isPublishDialogOpen = atom(false)\n certifiedBlobs = atom<ICertifiedBlob[]>([])\n isWorking = computed(\n [this.deployStatus],\n deployStatus =>\n deployStatus !== DeploymentStatus.Idle &&\n deployStatus !== DeploymentStatus.Prepared &&\n deployStatus !== DeploymentStatus.Uploaded &&\n deployStatus !== DeploymentStatus.Certified &&\n deployStatus !== DeploymentStatus.Deployed\n )\n\n deployStatusText = computed([this.deployStatus], s => {\n switch (s) {\n case DeploymentStatus.Idle:\n return 'Start Deployment'\n case DeploymentStatus.Preparing:\n return 'Preparing assets...'\n case DeploymentStatus.Prepared:\n return 'Upload assets'\n case DeploymentStatus.Uploading:\n return 'Uploading assets...'\n case DeploymentStatus.Uploaded:\n return 'Certify assets'\n case DeploymentStatus.Certifying:\n return 'Certifying assets...'\n case DeploymentStatus.Certified:\n return 'Update Site Metadata'\n case DeploymentStatus.Deploying:\n return 'Updating site metadata...'\n case DeploymentStatus.Deployed:\n return 'Customize Domain'\n default:\n return 'Unknown status'\n }\n })\n\n private currentFlow?: IUpdateWalrusSiteFlow\n private siteId?: string\n\n async runDeploymentStep(\n sdk: IWalrusSiteBuilderSdk,\n assets: IAsset[],\n site: SiteMetadata\n ): Promise<TResult<string>> {\n if (this.isWorking.get()) return failed('Another operation is in progress')\n\n const status = this.deployStatus.get()\n\n switch (status) {\n case DeploymentStatus.Idle: {\n this.deployStatus.set(DeploymentStatus.Preparing)\n try {\n this.currentFlow = sdk.executeSiteUpdateFlow(assets, {\n object_id: site.id,\n site_name: site.title,\n metadata: {\n link: site.link,\n description: site.description,\n project_url: site.projectUrl,\n image_url: site.imageUrl,\n creator: site.creator ?? 'CommandOSS Site Builder'\n }\n })\n const diff = await this.currentFlow.prepareResources()\n if (diff.resources.every(r => r.op === 'unchanged')) {\n if (diff.site_name.op === 'noop' && diff.metadata.op === 'noop') {\n this.deployStatus.set(DeploymentStatus.Idle)\n return failed('No changes detected')\n } else {\n // Only metadata/site name changed, skip to certification\n this.deployStatus.set(DeploymentStatus.Certified)\n }\n } else this.deployStatus.set(DeploymentStatus.Prepared)\n return this.runDeploymentStep(sdk, assets, site)\n } catch (e) {\n console.error('Failed to prepare assets:', e)\n const msg =\n e instanceof Error ? e.message : 'Failed to prepare assets'\n this.deployStatus.set(DeploymentStatus.Idle)\n return failed(msg)\n }\n }\n\n case DeploymentStatus.Prepared: {\n if (!this.currentFlow) return failed('Invalid deployment flow')\n\n this.deployStatus.set(DeploymentStatus.Uploading)\n const epochs = siteMetadataStore.epochs.get()\n const deletable = siteMetadataStore.deletable.get()\n\n try {\n await this.currentFlow.writeResources(epochs, deletable)\n } catch (e) {\n console.error('Failed to upload assets:', e)\n this.deployStatus.set(DeploymentStatus.Prepared)\n return failed('Failed to upload assets')\n }\n\n this.deployStatus.set(DeploymentStatus.Uploaded)\n return this.runDeploymentStep(sdk, assets, site)\n }\n\n case DeploymentStatus.Uploaded: {\n if (!this.currentFlow) return failed('Invalid deployment flow')\n this.deployStatus.set(DeploymentStatus.Certifying)\n try {\n await this.currentFlow.certifyResources()\n this.deployStatus.set(DeploymentStatus.Certified)\n return this.runDeploymentStep(sdk, assets, site)\n } catch (e) {\n console.error('Failed to certify assets:', e)\n this.deployStatus.set(DeploymentStatus.Uploaded)\n const msg =\n e instanceof Error ? e.message : 'Failed to certify assets'\n return failed(msg)\n }\n }\n\n case DeploymentStatus.Certified: {\n if (!this.currentFlow) return failed('Invalid deployment flow')\n this.deployStatus.set(DeploymentStatus.Deploying)\n try {\n const { siteId } = await this.currentFlow.writeSite()\n if (!siteId) throw new Error('No site ID returned')\n this.deployStatus.set(DeploymentStatus.Deployed)\n this.siteId = siteId\n return ok(siteId)\n } catch (e) {\n console.error('Failed to deploy site:', e)\n this.deployStatus.set(DeploymentStatus.Certified)\n const msg = e instanceof Error ? e.message : 'Failed to deploy site'\n return failed(msg)\n }\n }\n case DeploymentStatus.Deployed:\n if (!this.siteId) return failed('Invalid state')\n // Deployment completed, close dialog\n this.reset()\n this.closePublishDialog()\n this.openCustomDomainDialog()\n return ok(this.siteId)\n\n default:\n return failed('Invalid deployment step')\n }\n }\n\n reset() {\n this.deployStatus.set(DeploymentStatus.Idle)\n this.certifiedBlobs.set([])\n this.currentFlow = undefined\n }\n\n closePublishDialog = () => this.isPublishDialogOpen.set(false)\n openCustomDomainDialog = () => isDomainDialogOpen.set(true)\n}\n\nexport const sitePublishingStore = new SitePublishingStore()\n","import {\n type ISignAndExecuteTransaction,\n type ISponsorConfig,\n TransactionExecutorService\n} from '@cmdoss/walrus-site-builder'\nimport type { SuiClient } from '@mysten/sui/client'\nimport { useMemo } from 'react'\n\nexport interface UseTransactionExecutorParams {\n suiClient: SuiClient\n walletAddress: string | undefined\n signAndExecuteTransaction: ISignAndExecuteTransaction\n sponsorConfig?: ISponsorConfig\n}\n\n/**\n * React hook to create a TransactionExecutorService instance.\n * Automatically handles sponsor configuration and wallet changes.\n */\nexport function useTransactionExecutor({\n suiClient,\n walletAddress,\n signAndExecuteTransaction,\n sponsorConfig\n}: UseTransactionExecutorParams) {\n return useMemo(() => {\n if (!walletAddress) return null\n\n return new TransactionExecutorService({\n suiClient,\n walletAddress,\n signAndExecuteTransaction,\n sponsorConfig\n })\n }, [suiClient, walletAddress, signAndExecuteTransaction, sponsorConfig])\n}\n","import {\n type IAsset,\n type ISignAndExecuteTransaction,\n type ISponsorConfig,\n type IWalrusSiteBuilderSdk,\n mainPackage,\n objectIdToWalrusSiteUrl,\n WalrusSiteBuilderSdk\n} from '@cmdoss/walrus-site-builder'\nimport type { SuiClient } from '@mysten/sui/client'\nimport { Transaction } from '@mysten/sui/transactions'\nimport {\n ALLOWED_METADATA,\n type SuinsClient,\n SuinsTransaction\n} from '@mysten/suins'\nimport type { WalletAccount } from '@mysten/wallet-standard'\nimport type { WalrusClient } from '@mysten/walrus'\nimport {\n MAINNET_WALRUS_PACKAGE_CONFIG,\n TESTNET_WALRUS_PACKAGE_CONFIG\n} from '@mysten/walrus'\nimport { useStore } from '@nanostores/react'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { useEffect, useMemo, useState } from 'react'\nimport { useWalrusSiteQuery } from '~/queries'\nimport { useSuiNsDomainsQuery } from '~/queries/suins-domains.query'\nimport {\n isAssigningDomain,\n isDomainDialogOpen\n} from '~/stores/site-domain.store'\nimport { siteMetadataStore } from '~/stores/site-metadata.store'\nimport {\n type SiteMetadata,\n type SiteMetadataUpdate,\n sitePublishingStore\n} from '~/stores/site-publishing.store'\nimport { useTransactionExecutor } from './useTransactionExecutor'\n\nexport interface UseSitePublishingParams {\n /**\n * Site Object ID on chain. If not provided, a new site will be created upon publishing.\n */\n siteId?: string\n /**\n * Site's assets to be published.\n */\n assets: IAsset[]\n /**\n * Optional callback to update site metadata after publishing. The site ID will\n * be available in the `site` parameter.\n */\n onUpdateSiteMetadata?: (\n site: SiteMetadataUpdate\n ) => Promise<SiteMetadata | undefined>\n /** Optional callback when a domain is associated with the site. */\n onAssociatedDomain?: (\n nftId: string,\n siteId: string,\n suiNSName: string\n ) => Promise<void>\n /** Optional callback for handling errors. */\n onError?: (msg: string) => void\n /** Optional callback when blobs are extended. */\n onExtendedBlobs?: (msg: string, txDigest?: string) => void\n /**\n * Sui and Query clients needed for on-chain operations.\n */\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n suinsClient: SuinsClient\n walrusClient: WalrusClient\n }\n /** Current wallet account information. */\n currentAccount: WalletAccount | null\n\n /** Callback for signing and executing transactions. */\n signAndExecuteTransaction: ISignAndExecuteTransaction\n sponsorConfig?: ISponsorConfig\n /** Optional domain for the portal to view published site. */\n portalDomain?: string\n /** Whether to use HTTPS for the portal URL. */\n portalHttps?: boolean\n}\n\nexport function useSitePublishing({\n siteId,\n assets,\n onUpdateSiteMetadata,\n onAssociatedDomain,\n onError,\n onExtendedBlobs,\n currentAccount,\n signAndExecuteTransaction,\n sponsorConfig,\n portalDomain,\n portalHttps,\n clients: { suiClient, queryClient, suinsClient, walrusClient }\n}: UseSitePublishingParams) {\n const [isExtending, setIsExtending] = useState(false)\n // Transaction executor with sponsor support\n const txExecutor = useTransactionExecutor({\n suiClient,\n walletAddress: currentAccount?.address,\n signAndExecuteTransaction,\n sponsorConfig\n })\n\n const sdk: IWalrusSiteBuilderSdk | undefined = useMemo(() => {\n if (!suiClient || !walrusClient || !currentAccount) return\n return new WalrusSiteBuilderSdk(\n walrusClient,\n suiClient,\n currentAccount.address,\n signAndExecuteTransaction,\n sponsorConfig\n )\n }, [\n suiClient,\n walrusClient,\n currentAccount,\n signAndExecuteTransaction,\n sponsorConfig\n ])\n\n const {\n data: nsDomains,\n isLoading: isLoadingNsDomains,\n isError: isErrorNsDomains\n } = useSuiNsDomainsQuery(currentAccount, { suiClient, queryClient })\n\n const { data: walrusSiteData } = useWalrusSiteQuery(siteId, {\n suiClient,\n queryClient\n })\n\n // Store state\n const isPublishDialogOpen = useStore(sitePublishingStore.isPublishDialogOpen)\n const isWorking = useStore(sitePublishingStore.isWorking)\n const certifiedBlobs = useStore(sitePublishingStore.certifiedBlobs)\n const deployStatus = useStore(sitePublishingStore.deployStatus)\n const deployStatusText = useStore(sitePublishingStore.deployStatusText)\n const deployStepIndex = useStore(sitePublishingStore.deploymentStepIndex)\n\n const epochs = useStore(siteMetadataStore.epochs)\n const title = useStore(siteMetadataStore.title)\n const imageUrl = useStore(siteMetadataStore.imageUrl)\n const link = useStore(siteMetadataStore.link)\n const description = useStore(siteMetadataStore.description)\n const isEditingSiteMetadata = useStore(siteMetadataStore.isDirty)\n const isSavingSiteMetadata = useStore(siteMetadataStore.loading)\n const isAssigning = useStore(isAssigningDomain)\n\n // Derived state\n const isDeployed = !!siteId\n const walrusSiteUrl = useMemo(() => {\n if (!siteId) return null\n return objectIdToWalrusSiteUrl(siteId, portalDomain, portalHttps)\n }, [siteId, portalDomain, portalHttps])\n\n const associatedDomains = nsDomains.filter(d => d.walrusSiteId === siteId)\n\n // Sync site data to store\n useEffect(() => {\n if (!walrusSiteData) return\n console.log('🔄 Syncing Walrus site data to store', walrusSiteData)\n siteMetadataStore.originalTitle.set(walrusSiteData.name ?? '')\n siteMetadataStore.originalDescription.set(walrusSiteData.description ?? '')\n siteMetadataStore.originalImageUrl.set(walrusSiteData.image_url ?? null)\n siteMetadataStore.originalProjectUrl.set(walrusSiteData.project_url ?? null)\n siteMetadataStore.originalLink.set(walrusSiteData.link ?? '')\n siteMetadataStore.reset()\n }, [walrusSiteData])\n\n // Actions\n const handleRunDeploymentStep = async () => {\n if (!sdk) return onError?.('SDK not initialized')\n if (imageUrl instanceof File) return onError?.('Please upload image first.')\n const siteMetadata: SiteMetadata = {\n id: siteId,\n title,\n description,\n imageUrl: imageUrl ?? undefined,\n link: siteMetadataStore.link.get() ?? undefined,\n projectUrl: siteMetadataStore.projectUrl.get() ?? undefined\n }\n const result = await sitePublishingStore.runDeploymentStep(\n sdk,\n assets,\n siteMetadata\n )\n if (!result.ok) return onError?.(result.error || 'Deployment failed')\n siteMetadata.id = result.data // Update site ID after deployment\n await onUpdateSiteMetadata?.(siteMetadata)\n siteMetadataStore.commitChanges()\n }\n\n const handleSaveSiteMetadata = async () => {\n if (!onUpdateSiteMetadata) {\n siteMetadataStore.commitChanges()\n return\n }\n\n siteMetadataStore.loading.set(true)\n try {\n const result = await onUpdateSiteMetadata({\n id: siteId,\n title: siteMetadataStore.title.get(),\n description: siteMetadataStore.description.get(),\n imageUrl: siteMetadataStore.imageUrl.get() ?? undefined,\n link: siteMetadataStore.link.get() ?? undefined,\n projectUrl: siteMetadataStore.projectUrl.get() ?? undefined\n })\n if (!result) throw new Error('Failed to save site metadata')\n\n if (result.title) siteMetadataStore.title.set(result.title)\n if (result.description)\n siteMetadataStore.description.set(result.description)\n if (result.imageUrl) siteMetadataStore.imageUrl.set(result.imageUrl)\n siteMetadataStore.link.set(result.link ?? '')\n siteMetadataStore.projectUrl.set(result.projectUrl ?? '')\n\n siteMetadataStore.commitChanges()\n } finally {\n siteMetadataStore.loading.set(false)\n }\n }\n\n const handleAssociateDomain = async (\n nftId: string,\n siteId: string,\n suiNSName: string\n ) => {\n if (!suinsClient) return onError?.('SuiNS client not available')\n if (!nftId) return onError?.('No domain selected')\n if (!txExecutor) return onError?.('Transaction executor not available')\n\n isAssigningDomain.set(true)\n try {\n try {\n const transaction = new Transaction()\n const suinsTransaction = new SuinsTransaction(suinsClient, transaction)\n suinsTransaction.setUserData({\n nft: nftId,\n key: ALLOWED_METADATA.walrusSiteId,\n value: siteId\n })\n\n const digest = await txExecutor.execute({\n transaction,\n description: 'Associate domain with Walrus site'\n })\n\n await suiClient.waitForTransaction({ digest })\n\n // Invalidate all SuiNS queries to refetch updated domain data\n await queryClient.invalidateQueries({\n predicate: query => {\n const key = query.queryKey[0]\n return key === 'suins-domains' || key === 'suins-domain-detail'\n }\n })\n\n // Add domain to array if not already present\n const currentDomains = siteMetadataStore.suiNSUrl.get()\n const domainEntry = { suins: suiNSName, nftId }\n\n if (!currentDomains.some(d => d.nftId === nftId)) {\n siteMetadataStore.suiNSUrl.set([...currentDomains, domainEntry])\n }\n\n await onAssociatedDomain?.(nftId, siteId, suiNSName)\n } catch (e) {\n console.error('🚨 Failed to update SuiNS metadata:', e)\n onError?.('Failed to update SuiNS metadata')\n }\n } finally {\n isAssigningDomain.set(false)\n }\n }\n\n function handleOpenDomainDialog() {\n isDomainDialogOpen.set(true)\n }\n function handleOpenPublishingDialog() {\n sitePublishingStore.isPublishDialogOpen.set(true)\n }\n\n const handleExtendBlobs = async (extendEpochs: number) => {\n if (\n !walrusClient ||\n !currentAccount ||\n !walrusSiteData?.resources ||\n walrusSiteData.resources.length === 0\n ) {\n onError?.('Cannot extend blobs: missing required data')\n return\n }\n\n if (!extendEpochs || extendEpochs <= 0 || extendEpochs > 365) {\n onError?.('Invalid epoch count. Must be between 1 and 365')\n return\n }\n\n if (!txExecutor) {\n onError?.('Transaction executor not available')\n return\n }\n\n setIsExtending(true)\n try {\n const blobType = await walrusClient.getBlobType()\n\n // Determine network-specific constants\n const walCoinType =\n mainPackage[suiClient.network as keyof typeof mainPackage]\n .walrusCoinType\n const walrusPackageId =\n mainPackage[suiClient.network as keyof typeof mainPackage]\n .walrusPackageId\n const systemObjectId =\n suiClient.network === 'mainnet'\n ? MAINNET_WALRUS_PACKAGE_CONFIG.systemObjectId\n : TESTNET_WALRUS_PACKAGE_CONFIG.systemObjectId\n\n // Map blob_id to blobObjectId\n const blobIdToObjectIdMap = new Map<string, string>()\n let cursor: string | null | undefined = null\n let hasNextPage = true\n\n while (hasNextPage) {\n const ownedObjects = await suiClient.getOwnedObjects({\n owner: currentAccount.address,\n filter: { StructType: blobType },\n options: { showContent: true },\n cursor\n })\n\n // console.log endEpochs\n console.log('walrusSiteData.resources', walrusSiteData.resources)\n\n for (const resource of walrusSiteData.resources) {\n const blobId = resource.blob_id\n\n for (const obj of ownedObjects.data) {\n if (obj.data?.content && 'fields' in obj.data.content) {\n const fields = obj.data.content.fields as Record<string, unknown>\n if ('blob_id' in fields) {\n const objBlobId = String(fields.blob_id)\n if (objBlobId === blobId && !blobIdToObjectIdMap.has(blobId)) {\n blobIdToObjectIdMap.set(blobId, obj.data.objectId)\n break\n }\n }\n }\n }\n }\n\n hasNextPage = ownedObjects.hasNextPage\n cursor = ownedObjects.nextCursor\n }\n\n if (blobIdToObjectIdMap.size === 0) {\n throw new Error(\n 'No blob objects found for this site. Make sure you own the blob objects.'\n )\n }\n\n const tx = new Transaction()\n tx.setSender(currentAccount.address)\n\n const walCoin = await suiClient.getCoins({\n owner: currentAccount.address,\n coinType: walCoinType\n })\n\n if (walCoin.data.length === 0) {\n throw new Error(\n `No WAL coins found in wallet. Please acquire WAL tokens first.`\n )\n }\n\n // Merge all WAL coins\n if (walCoin.data.length > 1) {\n tx.mergeCoins(\n tx.object(walCoin.data[0].coinObjectId),\n walCoin.data.slice(1).map(coin => tx.object(coin.coinObjectId))\n )\n }\n\n // Extend all blobs by adding epochs to their current expiration\n for (const [_blobId, objectId] of blobIdToObjectIdMap.entries()) {\n tx.moveCall({\n package: walrusPackageId,\n module: 'system',\n function: 'extend_blob',\n arguments: [\n tx.object(systemObjectId),\n tx.object(objectId),\n tx.pure.u32(extendEpochs),\n tx.object(walCoin.data[0].coinObjectId)\n ]\n })\n }\n\n const digest = await txExecutor.execute({\n transaction: tx,\n description: `Extending ${blobIdToObjectIdMap.size} blob(s) by ${extendEpochs} epoch(s)`\n })\n\n // Wait for transaction to complete\n await suiClient.waitForTransaction({ digest })\n\n // Invalidate queries to refetch updated data\n await queryClient.invalidateQueries({\n predicate: query => {\n const key = query.queryKey\n return (\n (Array.isArray(key) &&\n (key[0] === 'walrus-site' || key[0] === 'walrus-sites')) ||\n false\n )\n }\n })\n\n onExtendedBlobs?.(\n `Successfully extended ${blobIdToObjectIdMap.size} blob(s) by ${extendEpochs} epoch(s)`,\n digest\n )\n } catch (error) {\n console.error('Error extending blobs:', error)\n onError?.(\n `Failed to extend blobs: ${error instanceof Error ? error.message : 'Unknown error'}`\n )\n } finally {\n setIsExtending(false)\n }\n }\n\n return {\n state: {\n isDeployed,\n isAssigning,\n isExtending,\n isPublishDialogOpen,\n isWorking,\n certifiedBlobs,\n epochs,\n title,\n iconUrl: imageUrl,\n description,\n link,\n isEditingSiteMetadata,\n deployStatus,\n deployStatusText,\n deployStepIndex,\n walrusSiteUrl,\n nsDomains,\n isLoadingNsDomains,\n isErrorNsDomains,\n isSavingSiteMetadata,\n associatedDomains\n },\n actions: {\n handleRunDeploymentStep,\n handleSaveSiteMetadata,\n handleAssociateDomain,\n handleExtendBlobs,\n handleOpenDomainDialog,\n handleOpenPublishingDialog,\n handleCancelEditingSiteMetadata: siteMetadataStore.reset\n }\n }\n}\n","import type { WalrusClient } from '@mysten/walrus'\nimport { useEffect, useMemo, useState } from 'react'\n\nexport function useEpochDuration(walrusClient: WalrusClient | null) {\n const [epochDurationMs, setEpochDurationMs] = useState<number | null>(null)\n\n // Get epoch duration from Walrus staking state\n useEffect(() => {\n const fetchEpochDuration = async () => {\n if (!walrusClient) return\n\n try {\n const stakingState = await walrusClient.stakingState()\n const duration = Number(stakingState.epoch_duration)\n setEpochDurationMs(duration)\n } catch (error) {\n console.error('Error fetching epoch duration:', error)\n // Fallback to 1 day if fetch fails\n setEpochDurationMs(24 * 60 * 60 * 1000)\n }\n }\n\n fetchEpochDuration()\n }, [walrusClient])\n\n // Calculate expiration date\n const getExpirationDate = useMemo(() => {\n return (epochs: number) => {\n if (!epochDurationMs || !epochs || epochs <= 0) return null\n const now = Date.now()\n return new Date(now + epochs * epochDurationMs)\n }\n }, [epochDurationMs])\n\n const formatDate = (date: Date) => {\n return new Intl.DateTimeFormat('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n }).format(date)\n }\n\n return {\n epochDurationMs,\n getExpirationDate,\n formatDate\n }\n}\n","import { AggregatorClient, Env } from '@cetusprotocol/aggregator-sdk'\nimport type {\n ISignAndExecuteTransaction,\n ISponsorConfig\n} from '@cmdoss/walrus-site-builder'\nimport { mainPackage } from '@cmdoss/walrus-site-builder'\nimport type { SuiClient } from '@mysten/sui/client'\nimport { Transaction } from '@mysten/sui/transactions'\nimport { type SuinsClient, SuinsTransaction } from '@mysten/suins'\nimport type { WalletAccount } from '@mysten/wallet-standard'\nimport type { QueryClient } from '@tanstack/react-query'\nimport BN from 'bn.js'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { useTransactionExecutor } from './useTransactionExecutor'\n\ninterface UseSuiNsRegistrationParams {\n currentAccount: WalletAccount | null\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n suinsClient: SuinsClient\n }\n signAndExecuteTransaction: ISignAndExecuteTransaction\n sponsorConfig?: ISponsorConfig\n}\n\nexport function useSuiNsRegistration({\n currentAccount,\n clients: { suiClient, queryClient, suinsClient },\n signAndExecuteTransaction,\n sponsorConfig\n}: UseSuiNsRegistrationParams) {\n const txExecutor = useTransactionExecutor({\n suiClient,\n walletAddress: currentAccount?.address,\n signAndExecuteTransaction,\n sponsorConfig\n })\n\n const [searchName, setSearchName] = useState('')\n const [isSearching, setIsSearching] = useState(false)\n const [isAvailable, setIsAvailable] = useState<boolean | null>(null)\n const [isRegistering, setIsRegistering] = useState(false)\n const [isSwapping, setIsSwapping] = useState(false)\n const [estimatedPrice, setEstimatedPrice] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [selectedYears, setSelectedYears] = useState(1)\n const [pricePerYear, setPricePerYear] = useState<number | null>(null)\n const [pricePerYearFormatted, setPricePerYearFormatted] = useState<\n string | null\n >(null)\n const [pricePerYearUsdc, setPricePerYearUsdc] = useState<string | null>(null)\n const [totalPriceUsdc, setTotalPriceUsdc] = useState<string | null>(null)\n const priceRefreshIntervalRef = useRef<NodeJS.Timeout | null>(null)\n\n const normalizedName = searchName.toLowerCase().trim()\n const fullName = normalizedName ? `${normalizedName}.sui` : ''\n const network = suiClient.network\n const isMainnet = network === 'mainnet'\n const isTestnet = network === 'testnet'\n\n // Calculate expiration date\n const expirationDate = useMemo(() => {\n if (!selectedYears) return null\n const date = new Date()\n date.setFullYear(date.getFullYear() + selectedYears)\n return date\n }, [selectedYears])\n\n // Calculate total price\n const totalPrice = useMemo(() => {\n if (!pricePerYear || !selectedYears) return null\n return pricePerYear * selectedYears\n }, [pricePerYear, selectedYears])\n\n // Format total price\n const totalPriceFormatted = useMemo(() => {\n if (!totalPrice || !pricePerYearFormatted) return null\n const perYearValue = parseFloat(\n pricePerYearFormatted.replace(/[^\\d.]/g, '')\n )\n if (Number.isNaN(perYearValue)) return null\n const totalValue = perYearValue * selectedYears\n return pricePerYearFormatted.replace(/[\\d.]+/, totalValue.toFixed(4))\n }, [totalPrice, pricePerYearFormatted, selectedYears])\n\n // Get WAL coin type from mainPackage\n const WAL_COIN_TYPE =\n mainPackage[network as keyof typeof mainPackage]?.walrusCoinType\n\n // Initialize Aggregator Client for swaps (mainnet only)\n const aggregatorClient = useMemo(() => {\n if (!suiClient || !currentAccount || !isMainnet) return null\n\n return new AggregatorClient({\n signer: currentAccount.address,\n client: suiClient,\n env: Env.Mainnet\n })\n }, [suiClient, currentAccount, isMainnet])\n\n // Function to update price estimate for mainnet (WAL → USDC)\n const updatePriceEstimate = useCallback(async () => {\n if (\n !suinsClient ||\n !currentAccount ||\n !isMainnet ||\n !WAL_COIN_TYPE ||\n !aggregatorClient ||\n !normalizedName\n ) {\n return\n }\n\n // Get price list\n const priceList = await suinsClient.getPriceList()\n const nameLength = normalizedName.length\n\n // Find price for this name length\n let pricePerYearValue = 0\n for (const [[from, to], price] of priceList.entries()) {\n if (nameLength >= from && nameLength <= to) {\n pricePerYearValue = price\n break\n }\n }\n\n if (pricePerYearValue > 0) {\n setPricePerYear(pricePerYearValue)\n\n // Calculate total price with buffer (5%)\n const totalPriceValue = pricePerYearValue * selectedYears\n const requiredAmount = BigInt(Math.floor(totalPriceValue * 1.05))\n\n // Get current USDC balance to calculate missing amount\n const usdcCoins = await suiClient.getCoins({\n owner: currentAccount.address,\n coinType: suinsClient.config.coins.USDC.type\n })\n\n const usdcBalance =\n usdcCoins.data?.reduce((sum, coin) => sum + BigInt(coin.balance), 0n) ??\n 0n\n\n // Calculate missing USDC (if any)\n const missingUsdc =\n usdcBalance < requiredAmount\n ? requiredAmount - usdcBalance\n : requiredAmount\n\n // Estimate WAL needed using same logic as register\n const baseWalAtomic = 1_000_000_000n // 1 WAL (9 decimals)\n const rateRouter = await aggregatorClient.findRouters({\n from: WAL_COIN_TYPE,\n target: suinsClient.config.coins.USDC.type,\n amount: new BN(baseWalAtomic.toString()),\n byAmountIn: true,\n providers: ['CETUS']\n })\n\n if (rateRouter && !rateRouter.error && rateRouter.amountOut) {\n const rawAmountOut = rateRouter.amountOut\n const usdcOutForOneWal = BigInt(\n rawAmountOut instanceof BN\n ? rawAmountOut.toString()\n : new BN(String(rawAmountOut)).toString()\n )\n\n if (usdcOutForOneWal > 0n) {\n const exchangeRate = Number(baseWalAtomic) / Number(usdcOutForOneWal)\n const estimatedWalNeeded =\n missingUsdc * BigInt(Math.ceil(exchangeRate))\n const walNeededFormatted = (\n Number(estimatedWalNeeded) / 1_000_000_000\n ).toFixed(4)\n const walPerYearFormatted = (\n Number(estimatedWalNeeded) /\n selectedYears /\n 1_000_000_000\n ).toFixed(4)\n setPricePerYearFormatted(`${walPerYearFormatted} WAL`)\n setEstimatedPrice(`~${walNeededFormatted} WAL`)\n } else {\n // Fallback: show USDC price\n const usdcPrice = (Number(requiredAmount) / 1_000_000).toFixed(2)\n const usdcPerYear = (pricePerYearValue / 1_000_000).toFixed(2)\n setPricePerYearFormatted(`${usdcPerYear} USDC`)\n setEstimatedPrice(`~${usdcPrice} USDC`)\n }\n } else {\n // Fallback: show USDC price\n const usdcPrice = (Number(requiredAmount) / 1_000_000).toFixed(2)\n const usdcPerYear = (pricePerYearValue / 1_000_000).toFixed(2)\n setPricePerYearFormatted(`${usdcPerYear} USDC`)\n setEstimatedPrice(`~${usdcPrice} USDC`)\n }\n }\n }, [\n suinsClient,\n currentAccount,\n isMainnet,\n WAL_COIN_TYPE,\n aggregatorClient,\n normalizedName,\n selectedYears,\n suiClient\n ])\n\n // Function to update price estimate for testnet (USDC → SUI)\n // Uses fixed exchange rate: 1 SUI = 1.5 USDC (or 1 USDC = 2/3 SUI)\n const updateTestnetPriceEstimate = useCallback(async () => {\n if (!suinsClient || !currentAccount || !isTestnet || !normalizedName) {\n return\n }\n\n // Get price list (price is in USDC)\n const priceList = await suinsClient.getPriceList()\n const nameLength = normalizedName.length\n\n // Find price for this name length\n let pricePerYearValue = 0\n for (const [[from, to], price] of priceList.entries()) {\n if (nameLength >= from && nameLength <= to) {\n pricePerYearValue = price\n break\n }\n }\n\n if (pricePerYearValue > 0) {\n setPricePerYear(pricePerYearValue)\n\n // Calculate total price (USDC amount) - this is what needs to be paid\n const totalPriceValue = pricePerYearValue * selectedYears\n const usdcAmountAtomic = BigInt(Math.floor(totalPriceValue))\n\n // Fixed exchange rate: 1 SUI = 1.5 USDC\n // So 1 USDC = 2/3 SUI = 0.666666... SUI\n // To calculate: (usdcAmount * 2 * 10^9) / (3 * 10^6)\n // This gives us SUI amount with 9 decimals\n const suiNeededAtomic =\n (usdcAmountAtomic * 2n * 1_000_000_000n) / (3n * 1_000_000n)\n const suiPerYearAtomic =\n (BigInt(Math.floor(pricePerYearValue)) * 2n * 1_000_000_000n) /\n (3n * 1_000_000n)\n\n // Format for display (SUI has 9 decimals)\n const suiNeededFormatted = (\n Number(suiNeededAtomic) / 1_000_000_000\n ).toFixed(4)\n const suiPerYearFormatted = (\n Number(suiPerYearAtomic) / 1_000_000_000\n ).toFixed(4)\n\n // Also store USDC prices for display\n const usdcPrice = (Number(usdcAmountAtomic) / 1_000_000).toFixed(2)\n const usdcPerYear = (pricePerYearValue / 1_000_000).toFixed(2)\n\n setPricePerYearFormatted(`${suiPerYearFormatted} SUI`)\n setEstimatedPrice(`${suiNeededFormatted} SUI`)\n setPricePerYearUsdc(`${usdcPerYear} USDC`)\n setTotalPriceUsdc(`${usdcPrice} USDC`)\n }\n }, [suinsClient, currentAccount, isTestnet, normalizedName, selectedYears])\n\n // Auto-refresh price every 10s when domain is available (mainnet only)\n useEffect(() => {\n if (\n isMainnet &&\n isAvailable &&\n normalizedName &&\n !isRegistering &&\n aggregatorClient\n ) {\n // Clear existing interval\n if (priceRefreshIntervalRef.current) {\n clearInterval(priceRefreshIntervalRef.current)\n }\n\n // Set up interval to refresh price every 10s\n priceRefreshIntervalRef.current = setInterval(() => {\n updatePriceEstimate().catch(err => {\n console.error('Error refreshing price:', err)\n })\n }, 10000)\n\n return () => {\n if (priceRefreshIntervalRef.current) {\n clearInterval(priceRefreshIntervalRef.current)\n }\n }\n }\n }, [\n isMainnet,\n isAvailable,\n normalizedName,\n isRegistering,\n aggregatorClient,\n updatePriceEstimate\n ])\n\n // Update price when years change\n useEffect(() => {\n if (isAvailable && pricePerYear !== null) {\n if (isMainnet && aggregatorClient) {\n updatePriceEstimate().catch(err => {\n console.error('Error updating price:', err)\n })\n } else if (isTestnet) {\n updateTestnetPriceEstimate().catch(err => {\n console.error('Error updating price:', err)\n })\n }\n }\n }, [\n isAvailable,\n pricePerYear,\n isMainnet,\n isTestnet,\n aggregatorClient,\n updatePriceEstimate,\n updateTestnetPriceEstimate\n ])\n\n const handleSearch = useCallback(async () => {\n if (!normalizedName || !suinsClient) return\n\n if (normalizedName.length < 3) {\n setError('Domain name must be at least 3 characters')\n setIsAvailable(null)\n setEstimatedPrice(null)\n return\n }\n\n setIsSearching(true)\n setError(null)\n setIsAvailable(null)\n setEstimatedPrice(null)\n\n try {\n const nameRecord = await suinsClient.getNameRecord(fullName)\n const available = !nameRecord?.nftId\n setIsAvailable(available)\n\n // Show estimated price\n if (available && currentAccount && aggregatorClient) {\n try {\n if (isMainnet && WAL_COIN_TYPE) {\n await updatePriceEstimate()\n } else if (isTestnet) {\n await updateTestnetPriceEstimate()\n }\n } catch (priceError) {\n console.error('Error estimating price:', priceError)\n // Don't set error, just don't show price\n }\n }\n } catch (error) {\n // If getNameRecord throws an error, the name might be available\n console.error('Error checking name:', error)\n setIsAvailable(true)\n } finally {\n setIsSearching(false)\n }\n }, [\n normalizedName,\n fullName,\n suinsClient,\n currentAccount,\n isMainnet,\n isTestnet,\n WAL_COIN_TYPE,\n aggregatorClient,\n updatePriceEstimate,\n updateTestnetPriceEstimate\n ])\n\n const handleRegister = useCallback(async () => {\n if (!suinsClient || !currentAccount || !isAvailable || !normalizedName) {\n return\n }\n\n if (!txExecutor) {\n setError('Transaction executor not available')\n return\n }\n\n setIsRegistering(true)\n setError(null)\n\n try {\n // Get price list\n const priceList = await suinsClient.getPriceList()\n const nameLength = normalizedName.length\n\n // Find price for this name length\n let pricePerYear = 0\n for (const [[from, to], price] of priceList.entries()) {\n if (nameLength >= from && nameLength <= to) {\n pricePerYear = price\n break\n }\n }\n\n if (pricePerYear === 0) {\n throw new Error('Unable to determine price for this domain')\n }\n\n // Register for selected years\n const years = selectedYears\n const totalPrice = pricePerYear * years\n\n // Get coin config (use SUI for testnet, USDC for mainnet)\n const coinType = isTestnet ? 'SUI' : 'USDC'\n const coinConfig = suinsClient.config.coins[coinType]\n\n // Load user balances (only for mainnet USDC/WAL)\n const [usdcCoins, walCoins] = await Promise.all([\n isMainnet\n ? suiClient.getCoins({\n owner: currentAccount.address,\n coinType: suinsClient.config.coins.USDC.type\n })\n : Promise.resolve({ data: [] }),\n isMainnet && WAL_COIN_TYPE\n ? suiClient.getCoins({\n owner: currentAccount.address,\n coinType: WAL_COIN_TYPE\n })\n : Promise.resolve({ data: [] })\n ])\n\n const usdcBalance =\n usdcCoins.data?.reduce((sum, coin) => sum + BigInt(coin.balance), 0n) ??\n 0n\n const walBalance =\n walCoins.data?.reduce((sum, coin) => sum + BigInt(coin.balance), 0n) ??\n 0n\n\n // Calculate required amount with buffer (5%)\n const requiredAmount = BigInt(Math.floor(totalPrice * 1.05))\n\n // On mainnet, check if we need to swap WAL → USDC\n if (isMainnet && coinType === 'USDC') {\n if (usdcBalance < requiredAmount) {\n if (!aggregatorClient || !WAL_COIN_TYPE) {\n throw new Error(\n 'Swap client not ready. Please try again in a few seconds.'\n )\n }\n\n if (walBalance === 0n) {\n throw new Error(\n `Insufficient USDC balance. Need approximately ${(Number(requiredAmount) / 1_000_000).toFixed(2)} USDC, but have ${(Number(usdcBalance) / 1_000_000).toFixed(2)} USDC. No WAL available to swap.`\n )\n }\n\n const missingUsdc = requiredAmount - usdcBalance\n\n // Estimate WAL needed using live rate\n const baseWalAtomic = 1_000_000_000n // 1 WAL (9 decimals)\n const rateRouter = await aggregatorClient.findRouters({\n from: WAL_COIN_TYPE,\n target: suinsClient.config.coins.USDC.type,\n amount: new BN(baseWalAtomic.toString()),\n byAmountIn: true,\n providers: ['CETUS']\n })\n\n if (!rateRouter || rateRouter.error || !rateRouter.amountOut) {\n const msg =\n rateRouter?.error?.msg ||\n 'Failed to fetch WAL → USDC rate from aggregator.'\n throw new Error(msg)\n }\n\n const rawAmountOut = rateRouter.amountOut\n if (!rawAmountOut) {\n throw new Error('Failed to get amount out from rate router')\n }\n const usdcOutForOneWal = BigInt(\n rawAmountOut instanceof BN\n ? rawAmountOut.toString()\n : new BN(String(rawAmountOut)).toString()\n )\n\n if (usdcOutForOneWal === 0n) {\n throw new Error('Aggregator returned zero USDC for 1 WAL.')\n }\n\n const exchangeRate = Number(baseWalAtomic) / Number(usdcOutForOneWal)\n const estimatedWalNeeded =\n missingUsdc * BigInt(Math.ceil(exchangeRate))\n\n if (walBalance < estimatedWalNeeded) {\n throw new Error(\n `Insufficient WAL balance. Need approximately ${(Number(estimatedWalNeeded) / 1_000_000_000).toFixed(4)} WAL to swap for USDC.`\n )\n }\n\n // Perform WAL → USDC swap\n setIsSwapping(true)\n try {\n const amountWalBN = new BN(estimatedWalNeeded.toString())\n\n const routerResult = await aggregatorClient.findRouters({\n from: WAL_COIN_TYPE,\n target: suinsClient.config.coins.USDC.type,\n amount: amountWalBN,\n byAmountIn: true,\n providers: ['CETUS']\n })\n\n if (!routerResult || (routerResult as { error?: unknown }).error) {\n const msg =\n (routerResult as { error?: { msg?: string } })?.error?.msg ||\n 'Failed to find route to swap WAL to USDC for registration.'\n throw new Error(msg)\n }\n\n if (\n (routerResult as { insufficientLiquidity?: boolean })\n .insufficientLiquidity\n ) {\n throw new Error(\n 'Insufficient liquidity to swap WAL to USDC for this registration amount.'\n )\n }\n\n const swapTx = new Transaction()\n swapTx.setSenderIfNotSet(currentAccount.address)\n\n await aggregatorClient.fastRouterSwap({\n router: routerResult,\n txb: swapTx,\n slippage: 0.005 // 0.5% slippage\n })\n\n swapTx.setGasBudget(50_000_000)\n\n const swapDigest = await txExecutor.execute({\n transaction: swapTx,\n description: 'Swap WAL to USDC for SuiNS registration'\n })\n\n // Wait for swap transaction to complete\n await suiClient.waitForTransaction({ digest: swapDigest })\n\n // Refresh USDC balance after swap\n const usdcCoinsAfter = await suiClient.getCoins({\n owner: currentAccount.address,\n coinType: suinsClient.config.coins.USDC.type\n })\n\n const usdcBalanceAfter =\n usdcCoinsAfter.data?.reduce(\n (sum, coin) => sum + BigInt(coin.balance),\n 0n\n ) ?? 0n\n\n if (usdcBalanceAfter < requiredAmount) {\n throw new Error(\n 'Swap completed but still insufficient USDC balance. Please try again.'\n )\n }\n } finally {\n setIsSwapping(false)\n }\n }\n }\n\n // Get user's coins for payment\n const coins = await suiClient.getCoins({\n owner: currentAccount.address,\n coinType: coinConfig.type\n })\n\n if (coins.data.length === 0) {\n throw new Error(`No ${coinType} coins found in your wallet`)\n }\n\n // Calculate max payment with buffer (5%)\n const maxPaymentAmount = Math.floor(totalPrice * 1.05)\n const totalBalance = coins.data.reduce(\n (sum, coin) => sum + BigInt(coin.balance),\n 0n\n )\n\n const gasReserve = 10_000_000n\n const requiredBalance = BigInt(maxPaymentAmount) + gasReserve\n\n if (totalBalance < requiredBalance) {\n throw new Error(\n `Insufficient balance. Need approximately ${(Number(requiredBalance) / 1_000_000_000).toFixed(4)} ${coinType}`\n )\n }\n\n // Create transaction for registration\n const transaction = new Transaction()\n transaction.setSenderIfNotSet(currentAccount.address)\n\n const suinsTransaction = new SuinsTransaction(suinsClient, transaction)\n\n // Prepare payment coin\n let paymentCoin:\n | ReturnType<typeof transaction.object>\n | typeof transaction.gas\n\n if (coinType === 'SUI') {\n // For SUI, use transaction.gas directly\n paymentCoin = transaction.gas\n } else {\n // For USDC, need SUI for gas separately\n const suiCoins = await suiClient.getCoins({\n owner: currentAccount.address,\n coinType: '0x2::sui::SUI'\n })\n\n if (suiCoins.data.length === 0) {\n throw new Error('No SUI coins found for gas fees')\n }\n\n // Merge payment coins if multiple\n const primaryCoin = coins.data[0].coinObjectId\n if (coins.data.length > 1) {\n transaction.mergeCoins(\n transaction.object(primaryCoin),\n coins.data\n .slice(1)\n .map(coin => transaction.object(coin.coinObjectId))\n )\n }\n\n paymentCoin = transaction.object(primaryCoin)\n\n // Merge SUI coins for gas if multiple\n if (suiCoins.data.length > 1) {\n transaction.mergeCoins(\n transaction.object(suiCoins.data[0].coinObjectId),\n suiCoins.data\n .slice(1)\n .map(coin => transaction.object(coin.coinObjectId))\n )\n }\n }\n\n // Prepare registration parameters\n const registerParams: {\n domain: string\n years: number\n coinConfig: typeof coinConfig\n coin: typeof paymentCoin\n priceInfoObjectId?: string\n } = {\n domain: fullName,\n years,\n coinConfig,\n coin: paymentCoin\n }\n\n // Get price info object if feed is available\n if (coinConfig.feed) {\n const priceInfoObjectId = (\n await suinsClient.getPriceInfoObject(transaction, coinConfig.feed)\n )[0]\n registerParams.priceInfoObjectId = priceInfoObjectId\n }\n\n // Register the domain\n const nft = suinsTransaction.register(registerParams)\n\n // Set target address to current account\n suinsTransaction.setTargetAddress({\n nft,\n address: currentAccount.address\n })\n\n // Transfer the NFT to the user\n transaction.transferObjects([nft], currentAccount.address)\n\n // Set gas budget\n transaction.setGasBudget(50_000_000)\n\n // Execute transaction using txExecutor\n if (!txExecutor) {\n throw new Error('Transaction executor not available')\n }\n\n const digest = await txExecutor.execute({\n transaction,\n description: 'Register SuiNS domain'\n })\n\n // Wait for transaction to complete\n await suiClient.waitForTransaction({ digest })\n\n // Invalidate SuiNS domains query to refresh the list\n if (currentAccount?.address) {\n queryClient.invalidateQueries({\n queryKey: ['suins-domains', currentAccount.address, network]\n })\n }\n\n return true\n } catch (err) {\n console.error('Error registering domain:', err)\n setError(err instanceof Error ? err.message : 'Failed to register domain')\n return false\n } finally {\n setIsRegistering(false)\n }\n }, [\n suinsClient,\n currentAccount,\n isAvailable,\n normalizedName,\n fullName,\n selectedYears,\n txExecutor,\n isTestnet,\n isMainnet,\n WAL_COIN_TYPE,\n aggregatorClient,\n suiClient,\n queryClient,\n network\n ])\n\n const reset = useCallback(() => {\n setSearchName('')\n setIsAvailable(null)\n setEstimatedPrice(null)\n setError(null)\n setIsSearching(false)\n setIsRegistering(false)\n setIsSwapping(false)\n setSelectedYears(1)\n setPricePerYear(null)\n setPricePerYearFormatted(null)\n setPricePerYearUsdc(null)\n setTotalPriceUsdc(null)\n if (priceRefreshIntervalRef.current) {\n clearInterval(priceRefreshIntervalRef.current)\n priceRefreshIntervalRef.current = null\n }\n }, [])\n\n return {\n // State\n searchName,\n setSearchName,\n isSearching,\n isAvailable,\n isRegistering,\n isSwapping,\n estimatedPrice,\n error,\n normalizedName,\n fullName,\n selectedYears,\n setSelectedYears,\n pricePerYear,\n pricePerYearFormatted,\n pricePerYearUsdc,\n totalPrice,\n totalPriceFormatted,\n totalPriceUsdc,\n expirationDate,\n // Actions\n handleSearch,\n handleRegister,\n reset\n }\n}\n","import {\n type ISignAndExecuteTransaction,\n type ISponsorConfig,\n WalrusSiteBuilderSdk,\n type WSResources\n} from '@cmdoss/walrus-site-builder'\nimport type { SuiClient } from '@mysten/sui/client'\nimport type { WalletAccount } from '@mysten/wallet-standard'\nimport type { WalrusClient } from '@mysten/walrus'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { useMutation } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { queryKeys } from '~/queries/keys'\n\nexport interface UseUpdateSiteMetadataParams {\n siteId: string\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n walrusClient: WalrusClient\n }\n currentAccount: WalletAccount | null\n signAndExecuteTransaction: ISignAndExecuteTransaction\n sponsorConfig?: ISponsorConfig\n}\n\nexport interface UpdateSiteMetadataInput {\n siteName: string\n metadata: WSResources['metadata']\n}\n\nexport function useUpdateSiteMetadata({\n siteId,\n clients: { suiClient, queryClient, walrusClient },\n currentAccount,\n signAndExecuteTransaction,\n sponsorConfig\n}: UseUpdateSiteMetadataParams) {\n const network = suiClient.network\n\n // Create SDK instance\n const sdk = useMemo(() => {\n if (!currentAccount || !suiClient || !walrusClient) return null\n\n return new WalrusSiteBuilderSdk(\n walrusClient,\n suiClient,\n currentAccount.address,\n signAndExecuteTransaction,\n sponsorConfig\n )\n }, [\n currentAccount,\n suiClient,\n walrusClient,\n signAndExecuteTransaction,\n sponsorConfig\n ])\n\n // Mutation for updating site metadata\n const mutation = useMutation(\n {\n mutationFn: async ({\n siteName,\n metadata\n }: UpdateSiteMetadataInput): Promise<string> => {\n if (!sdk) {\n throw new Error('SDK not initialized')\n }\n\n const digest = await sdk.updateSiteMetadata(siteId, siteName, metadata)\n return digest\n },\n onSuccess: digest => {\n // Invalidate site query to refetch updated data\n queryClient.invalidateQueries({\n queryKey: queryKeys.walrusSite(siteId)\n })\n\n // Also invalidate sites list if needed\n if (currentAccount?.address) {\n queryClient.invalidateQueries({\n queryKey: queryKeys.walrusSites(currentAccount.address, network)\n })\n }\n\n console.log('✅ Site metadata updated successfully:', digest)\n },\n onError: error => {\n console.error('❌ Failed to update site metadata:', error)\n }\n },\n queryClient\n )\n\n return {\n updateSiteMetadata: mutation.mutateAsync,\n isUpdating: mutation.isPending,\n error: mutation.error,\n isSuccess: mutation.isSuccess,\n data: mutation.data\n }\n}\n","import { ZenFsFileManager } from '@cmdoss/file-manager'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { useEffect, useState } from 'react'\n\nexport function useZenFsWorkspace(\n workspaceDir = '/workspace',\n mountDir = '/workspace',\n queryClient: QueryClient\n) {\n const [loading, setLoading] = useState(true)\n const [fileManager, setFileManager] = useState<ZenFsFileManager | null>(null)\n\n // Initialize ZenFS and load existing files\n useEffect(() => {\n setLoading(true)\n console.log('Initializing ZenFS FileManager at', workspaceDir)\n const fm = new ZenFsFileManager(workspaceDir, mountDir)\n setFileManager(fm)\n\n fm.initialize()\n .catch(() => {\n // Ignore errors during initialization\n })\n .then(async () => {\n // Invalidate queries to refresh file listings\n await queryClient.invalidateQueries({\n queryKey: ['zenfs', workspaceDir]\n })\n })\n .finally(() => setLoading(false))\n // Cleanup on unmount\n }, [workspaceDir, mountDir, queryClient])\n\n return {\n loading,\n fileManager\n }\n}\n","import type { WalrusClient } from '@mysten/walrus'\nimport { type QueryClient, useQuery } from '@tanstack/react-query'\nimport { queryKeys } from './keys'\n\nexport function useStorageCostQuery(\n fileSize: number | null,\n epochs: number,\n clients: {\n queryClient: QueryClient\n walrusClient: WalrusClient\n }\n) {\n const { walrusClient, queryClient } = clients\n return useQuery(\n {\n queryKey: queryKeys.storageCost(fileSize, epochs),\n queryFn: async () => {\n if (!walrusClient) throw new Error('Walrus client not available')\n if (fileSize === null) throw new Error('Invalid file size')\n const storageCost = await walrusClient.storageCost(fileSize, epochs)\n return {\n storageCost: storageCost.storageCost.toString(),\n writeCost: storageCost.writeCost.toString(),\n totalCost: storageCost.totalCost.toString()\n }\n },\n enabled:\n !!walrusClient && fileSize !== null && fileSize > 0 && epochs > 0,\n staleTime: 5 * 60 * 1000 // 5 minutes\n },\n queryClient\n )\n}\n","'use strict';\n\nfunction toPrimitive(t, r) {\n if (\"object\" != typeof t || !t) return t;\n var e = t[Symbol.toPrimitive];\n if (void 0 !== e) {\n var i = e.call(t, r || \"default\");\n if (\"object\" != typeof i) return i;\n throw new TypeError(\"@@toPrimitive must return a primitive value.\");\n }\n return (\"string\" === r ? String : Number)(t);\n}\n\nfunction toPropertyKey(t) {\n var i = toPrimitive(t, \"string\");\n return \"symbol\" == typeof i ? i : String(i);\n}\n\nfunction _defineProperty(obj, key, value) {\n key = toPropertyKey(key);\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n return obj;\n}\n\nfunction ownKeys(e, r) {\n var t = Object.keys(e);\n if (Object.getOwnPropertySymbols) {\n var o = Object.getOwnPropertySymbols(e);\n r && (o = o.filter(function (r) {\n return Object.getOwnPropertyDescriptor(e, r).enumerable;\n })), t.push.apply(t, o);\n }\n return t;\n}\nfunction _objectSpread2(e) {\n for (var r = 1; r < arguments.length; r++) {\n var t = null != arguments[r] ? arguments[r] : {};\n r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {\n _defineProperty(e, r, t[r]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {\n Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));\n });\n }\n return e;\n}\n\nfunction mapValues(input, fn) {\n var result = {};\n for (var _key in input) {\n result[_key] = fn(input[_key], _key);\n }\n return result;\n}\n\nvar shouldApplyCompound = (compoundCheck, selections, defaultVariants) => {\n for (var key of Object.keys(compoundCheck)) {\n var _selections$key;\n if (compoundCheck[key] !== ((_selections$key = selections[key]) !== null && _selections$key !== void 0 ? _selections$key : defaultVariants[key])) {\n return false;\n }\n }\n return true;\n};\nvar createRuntimeFn = config => {\n var runtimeFn = options => {\n var className = config.defaultClassName;\n var selections = _objectSpread2(_objectSpread2({}, config.defaultVariants), options);\n for (var variantName in selections) {\n var _selections$variantNa;\n var variantSelection = (_selections$variantNa = selections[variantName]) !== null && _selections$variantNa !== void 0 ? _selections$variantNa : config.defaultVariants[variantName];\n if (variantSelection != null) {\n var selection = variantSelection;\n if (typeof selection === 'boolean') {\n // @ts-expect-error\n selection = selection === true ? 'true' : 'false';\n }\n var selectionClassName =\n // @ts-expect-error\n config.variantClassNames[variantName][selection];\n if (selectionClassName) {\n className += ' ' + selectionClassName;\n }\n }\n }\n for (var [compoundCheck, compoundClassName] of config.compoundVariants) {\n if (shouldApplyCompound(compoundCheck, selections, config.defaultVariants)) {\n className += ' ' + compoundClassName;\n }\n }\n return className;\n };\n runtimeFn.variants = () => Object.keys(config.variantClassNames);\n runtimeFn.classNames = {\n get base() {\n return config.defaultClassName.split(' ')[0];\n },\n get variants() {\n return mapValues(config.variantClassNames, classNames => mapValues(classNames, className => className.split(' ')[0]));\n }\n };\n return runtimeFn;\n};\n\nexports.createRuntimeFn = createRuntimeFn;\nexports.mapValues = mapValues;\n","'use strict';\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar createRuntimeFn_dist_vanillaExtractRecipesCreateRuntimeFn = require('../../dist/createRuntimeFn-166334d7.cjs.prod.js');\n\n\n\nexports.createRuntimeFn = createRuntimeFn_dist_vanillaExtractRecipesCreateRuntimeFn.createRuntimeFn;\n","'use strict';\n\nfunction toPrimitive(t, r) {\n if (\"object\" != typeof t || !t) return t;\n var e = t[Symbol.toPrimitive];\n if (void 0 !== e) {\n var i = e.call(t, r || \"default\");\n if (\"object\" != typeof i) return i;\n throw new TypeError(\"@@toPrimitive must return a primitive value.\");\n }\n return (\"string\" === r ? String : Number)(t);\n}\n\nfunction toPropertyKey(t) {\n var i = toPrimitive(t, \"string\");\n return \"symbol\" == typeof i ? i : String(i);\n}\n\nfunction _defineProperty(obj, key, value) {\n key = toPropertyKey(key);\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n return obj;\n}\n\nfunction ownKeys(e, r) {\n var t = Object.keys(e);\n if (Object.getOwnPropertySymbols) {\n var o = Object.getOwnPropertySymbols(e);\n r && (o = o.filter(function (r) {\n return Object.getOwnPropertyDescriptor(e, r).enumerable;\n })), t.push.apply(t, o);\n }\n return t;\n}\nfunction _objectSpread2(e) {\n for (var r = 1; r < arguments.length; r++) {\n var t = null != arguments[r] ? arguments[r] : {};\n r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {\n _defineProperty(e, r, t[r]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {\n Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));\n });\n }\n return e;\n}\n\nfunction mapValues(input, fn) {\n var result = {};\n for (var _key in input) {\n result[_key] = fn(input[_key], _key);\n }\n return result;\n}\n\nvar shouldApplyCompound = (compoundCheck, selections, defaultVariants) => {\n for (var key of Object.keys(compoundCheck)) {\n var _selections$key;\n if (compoundCheck[key] !== ((_selections$key = selections[key]) !== null && _selections$key !== void 0 ? _selections$key : defaultVariants[key])) {\n return false;\n }\n }\n return true;\n};\nvar createRuntimeFn = config => {\n var runtimeFn = options => {\n var className = config.defaultClassName;\n var selections = _objectSpread2(_objectSpread2({}, config.defaultVariants), options);\n for (var variantName in selections) {\n var _selections$variantNa;\n var variantSelection = (_selections$variantNa = selections[variantName]) !== null && _selections$variantNa !== void 0 ? _selections$variantNa : config.defaultVariants[variantName];\n if (variantSelection != null) {\n var selection = variantSelection;\n if (typeof selection === 'boolean') {\n // @ts-expect-error\n selection = selection === true ? 'true' : 'false';\n }\n var selectionClassName =\n // @ts-expect-error\n config.variantClassNames[variantName][selection];\n if (selectionClassName) {\n className += ' ' + selectionClassName;\n }\n }\n }\n for (var [compoundCheck, compoundClassName] of config.compoundVariants) {\n if (shouldApplyCompound(compoundCheck, selections, config.defaultVariants)) {\n className += ' ' + compoundClassName;\n }\n }\n return className;\n };\n runtimeFn.variants = () => Object.keys(config.variantClassNames);\n runtimeFn.classNames = {\n get base() {\n return config.defaultClassName.split(' ')[0];\n },\n get variants() {\n return mapValues(config.variantClassNames, classNames => mapValues(classNames, className => className.split(' ')[0]));\n }\n };\n return runtimeFn;\n};\n\nexports.createRuntimeFn = createRuntimeFn;\nexports.mapValues = mapValues;\n","'use strict';\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar createRuntimeFn_dist_vanillaExtractRecipesCreateRuntimeFn = require('../../dist/createRuntimeFn-2f250aaf.cjs.dev.js');\n\n\n\nexports.createRuntimeFn = createRuntimeFn_dist_vanillaExtractRecipesCreateRuntimeFn.createRuntimeFn;\n","'use strict';\n\nif (process.env.NODE_ENV === \"production\") {\n module.exports = require(\"./vanilla-extract-recipes-createRuntimeFn.cjs.prod.js\");\n} else {\n module.exports = require(\"./vanilla-extract-recipes-createRuntimeFn.cjs.dev.js\");\n}\n","import { style } from '@vanilla-extract/css'\nimport { recipe } from '@vanilla-extract/recipes'\nimport { themeVars } from '~/theme.css'\n\nexport const banner = recipe({\n base: {\n position: 'relative',\n isolation: 'isolate',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'space-between',\n gap: themeVars.spacing.xs,\n overflow: 'hidden',\n borderRadius: themeVars.radius.lg,\n marginTop: themeVars.spacing.sm,\n borderWidth: '1px',\n borderStyle: 'solid',\n paddingTop: themeVars.spacing.xs,\n paddingBottom: themeVars.spacing.xs,\n paddingLeft: themeVars.spacing.sm,\n paddingRight: '3rem',\n '@media': {\n 'screen and (min-width: 640px)': {\n flexDirection: 'row',\n alignItems: 'center',\n paddingTop: themeVars.spacing.sm,\n paddingBottom: themeVars.spacing.sm\n }\n }\n },\n variants: {\n variant: {\n info: {\n background:\n 'linear-gradient(to right, oklch(0.951 0.026 236.824 / 0.8), oklch(0.882 0.059 254.128 / 0.8))',\n borderColor: 'oklch(0.546 0.245 262.881 / 0.15)',\n selectors: {\n '.dark &': {\n background:\n 'linear-gradient(to right, oklch(0.282 0.091 267.935 / 0.6), oklch(0.379 0.146 265.522 / 0.6))',\n borderColor: 'oklch(0.746 0.16 232.661 / 0.2)'\n }\n }\n },\n success: {\n background:\n 'linear-gradient(to right, oklch(0.95 0.052 163.051 / 0.8), oklch(0.925 0.084 155.995 / 0.8))',\n borderColor: 'oklch(0.627 0.194 149.214 / 0.15)',\n selectors: {\n '.dark &': {\n background:\n 'linear-gradient(to right, oklch(0.262 0.051 172.552 / 0.6), oklch(0.393 0.095 152.535 / 0.6))',\n borderColor: 'oklch(0.792 0.209 151.711 / 0.2)'\n }\n }\n },\n warning: {\n background:\n 'linear-gradient(to right, oklch(0.962 0.059 95.617 / 0.8), oklch(0.973 0.071 103.193 / 0.8))',\n borderColor: 'oklch(0.666 0.179 58.318 / 0.15)',\n selectors: {\n '.dark &': {\n background:\n 'linear-gradient(to right, oklch(0.279 0.077 45.635 / 0.6), oklch(0.421 0.095 57.708 / 0.6))',\n borderColor: 'oklch(0.828 0.189 84.429 / 0.2)'\n }\n }\n },\n alert: {\n background:\n 'linear-gradient(to right, oklch(0.954 0.038 75.164 / 0.8), oklch(0.954 0.038 75.164 / 0.8))',\n borderColor: 'oklch(0.646 0.222 41.116 / 0.15)',\n selectors: {\n '.dark &': {\n background:\n 'linear-gradient(to right, oklch(0.266 0.079 36.259 / 0.6), oklch(0.408 0.123 38.172 / 0.6))',\n borderColor: 'oklch(0.75 0.183 55.934 / 0.2)'\n }\n }\n },\n error: {\n background:\n 'linear-gradient(to right, oklch(0.936 0.032 17.717 / 0.8), oklch(0.892 0.058 10.001 / 0.8))',\n borderColor: 'oklch(0.577 0.245 27.325 / 0.15)',\n selectors: {\n '.dark &': {\n background:\n 'linear-gradient(to right, oklch(0.258 0.092 26.042 / 0.6), oklch(0.41 0.159 10.272 / 0.6))',\n borderColor: 'oklch(0.704 0.191 22.216 / 0.2)'\n }\n }\n }\n }\n },\n defaultVariants: {\n variant: 'info'\n }\n})\n\nexport const gridPattern = style({\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n color: 'oklch(0 0 0 / 0.3)',\n mixBlendMode: 'overlay',\n maskImage: 'linear-gradient(to right, oklch(0 0 0), transparent)',\n '@media': {\n 'screen and (min-width: 768px)': {\n maskImage: 'linear-gradient(to right, oklch(0 0 0) 60%, transparent)'\n }\n },\n selectors: {\n '.dark &': {\n color: 'oklch(1 0 0 / 0.2)'\n }\n }\n})\n\nexport const content = style({\n display: 'flex',\n alignItems: 'center',\n gap: themeVars.spacing.sm,\n position: 'relative',\n zIndex: 10\n})\n\nexport const iconContainer = recipe({\n base: {\n display: 'none',\n borderRadius: '9999px',\n borderWidth: '1px',\n borderStyle: 'solid',\n padding: themeVars.spacing.xs,\n boxShadow: 'inset 0 0 1px 1px oklch(1 0 0)',\n '@media': {\n 'screen and (min-width: 640px)': {\n display: 'block'\n }\n },\n selectors: {\n '.dark &': {\n boxShadow: 'inset 0 0 1px 1px oklch(1 0 0 / 0.1)'\n }\n }\n },\n variants: {\n variant: {\n info: {\n backgroundColor: 'oklch(1 0 0 / 0.5)',\n borderColor: 'oklch(0.546 0.245 262.881 / 0.5)',\n selectors: {\n '.dark &': {\n backgroundColor: 'oklch(0.282 0.091 267.935 / 0.4)',\n borderColor: 'oklch(0.746 0.16 232.661 / 0.4)'\n }\n }\n },\n success: {\n backgroundColor: 'oklch(1 0 0 / 0.5)',\n borderColor: 'oklch(0.627 0.194 149.214 / 0.5)',\n selectors: {\n '.dark &': {\n backgroundColor: 'oklch(0.262 0.051 172.552 / 0.4)',\n borderColor: 'oklch(0.792 0.209 151.711 / 0.4)'\n }\n }\n },\n warning: {\n backgroundColor: 'oklch(1 0 0 / 0.5)',\n borderColor: 'oklch(0.666 0.179 58.318 / 0.5)',\n selectors: {\n '.dark &': {\n backgroundColor: 'oklch(0.279 0.077 45.635 / 0.4)',\n borderColor: 'oklch(0.828 0.189 84.429 / 0.4)'\n }\n }\n },\n alert: {\n backgroundColor: 'oklch(1 0 0 / 0.5)',\n borderColor: 'oklch(0.646 0.222 41.116 / 0.5)',\n selectors: {\n '.dark &': {\n backgroundColor: 'oklch(0.266 0.079 36.259 / 0.4)',\n borderColor: 'oklch(0.75 0.183 55.934 / 0.4)'\n }\n }\n },\n error: {\n backgroundColor: 'oklch(1 0 0 / 0.5)',\n borderColor: 'oklch(0.577 0.245 27.325 / 0.5)',\n selectors: {\n '.dark &': {\n backgroundColor: 'oklch(0.258 0.092 26.042 / 0.4)',\n borderColor: 'oklch(0.704 0.191 22.216 / 0.4)'\n }\n }\n }\n }\n }\n})\n\nexport const icon = recipe({\n base: {},\n variants: {\n variant: {\n info: {\n color: 'oklch(0.424 0.199 265.638)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.809 0.105 251.813)'\n }\n }\n },\n success: {\n color: 'oklch(0.448 0.119 151.328)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.845 0.143 164.978)'\n }\n }\n },\n warning: {\n color: 'oklch(0.473 0.137 46.201)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.879 0.169 91.605)'\n }\n }\n },\n alert: {\n color: 'oklch(0.47 0.157 37.304)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.837 0.128 66.29)'\n }\n }\n },\n error: {\n color: 'oklch(0.444 0.177 26.899)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.808 0.114 19.571)'\n }\n }\n }\n }\n }\n})\n\nexport const textContainer = style({\n display: 'flex',\n flexDirection: 'column'\n})\n\nexport const title = recipe({\n base: {\n fontSize: '0.875rem',\n fontWeight: 600\n },\n variants: {\n variant: {\n info: {\n color: 'oklch(0.379 0.146 265.522)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.932 0.032 255.585)'\n }\n }\n },\n success: {\n color: 'oklch(0.393 0.095 152.535)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.962 0.044 156.743)'\n }\n }\n },\n warning: {\n color: 'oklch(0.414 0.112 45.904)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.962 0.059 95.617)'\n }\n }\n },\n alert: {\n color: 'oklch(0.408 0.123 38.172)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.954 0.038 75.164)'\n }\n }\n },\n error: {\n color: 'oklch(0.396 0.141 25.723)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.936 0.032 17.717)'\n }\n }\n }\n }\n }\n})\n\nexport const description = recipe({\n base: {\n fontSize: '0.75rem'\n },\n variants: {\n variant: {\n info: {\n color: 'oklch(0.424 0.199 265.638 / 0.8)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.882 0.059 254.128 / 0.7)'\n }\n }\n },\n success: {\n color: 'oklch(0.448 0.119 151.328 / 0.8)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.905 0.093 164.15 / 0.7)'\n }\n }\n },\n warning: {\n color: 'oklch(0.473 0.137 46.201 / 0.8)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.924 0.12 95.746 / 0.7)'\n }\n }\n },\n alert: {\n color: 'oklch(0.47 0.157 37.304 / 0.8)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.901 0.076 70.697 / 0.7)'\n }\n }\n },\n error: {\n color: 'oklch(0.444 0.177 26.899 / 0.8)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.885 0.062 18.334 / 0.7)'\n }\n }\n }\n }\n }\n})\n\nexport const closeButton = recipe({\n base: {\n position: 'absolute',\n right: themeVars.spacing.sm,\n top: '50%',\n transform: 'translateY(-50%)',\n transition: 'colors 0.2s ease-in-out',\n cursor: 'pointer',\n border: 'none',\n background: 'transparent',\n padding: 0,\n '@media': {\n 'screen and (min-width: 640px)': {\n position: 'relative',\n right: 0,\n transform: 'none'\n }\n }\n },\n variants: {\n variant: {\n info: {\n color: 'oklch(0.546 0.245 262.881 / 0.5)',\n ':hover': {\n color: 'oklch(0.546 0.245 262.881)'\n },\n selectors: {\n '.dark &': {\n color: 'oklch(0.746 0.16 232.661 / 0.5)'\n },\n '.dark &:hover': {\n color: 'oklch(0.809 0.105 251.813)'\n }\n }\n },\n success: {\n color: 'oklch(0.627 0.194 149.214 / 0.5)',\n ':hover': {\n color: 'oklch(0.627 0.194 149.214)'\n },\n selectors: {\n '.dark &': {\n color: 'oklch(0.792 0.209 151.711 / 0.5)'\n },\n '.dark &:hover': {\n color: 'oklch(0.845 0.143 164.978)'\n }\n }\n },\n warning: {\n color: 'oklch(0.666 0.179 58.318 / 0.5)',\n ':hover': {\n color: 'oklch(0.666 0.179 58.318)'\n },\n selectors: {\n '.dark &': {\n color: 'oklch(0.828 0.189 84.429 / 0.5)'\n },\n '.dark &:hover': {\n color: 'oklch(0.879 0.169 91.605)'\n }\n }\n },\n alert: {\n color: 'oklch(0.646 0.222 41.116 / 0.5)',\n ':hover': {\n color: 'oklch(0.646 0.222 41.116)'\n },\n selectors: {\n '.dark &': {\n color: 'oklch(0.75 0.183 55.934 / 0.5)'\n },\n '.dark &:hover': {\n color: 'oklch(0.837 0.128 66.29)'\n }\n }\n },\n error: {\n color: 'oklch(0.577 0.245 27.325 / 0.5)',\n ':hover': {\n color: 'oklch(0.577 0.245 27.325)'\n },\n selectors: {\n '.dark &': {\n color: 'oklch(0.704 0.191 22.216 / 0.5)'\n },\n '.dark &:hover': {\n color: 'oklch(0.808 0.114 19.571)'\n }\n }\n }\n }\n }\n})\n\nexport const closeIcon = style({\n width: '1.25rem',\n height: '1.25rem'\n})\n\nexport const link = recipe({\n base: {\n fontWeight: 600,\n textDecoration: 'underline',\n textUnderlineOffset: '2px',\n transition: 'opacity 0.2s ease-in-out',\n ':hover': {\n opacity: 0.8\n }\n },\n variants: {\n variant: {\n info: {\n color: 'oklch(0.424 0.199 265.638)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.809 0.105 251.813)'\n }\n }\n },\n success: {\n color: 'oklch(0.448 0.119 151.328)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.845 0.143 164.978)'\n }\n }\n },\n warning: {\n color: 'oklch(0.473 0.137 46.201)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.879 0.169 91.605)'\n }\n }\n },\n alert: {\n color: 'oklch(0.47 0.157 37.304)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.837 0.128 66.29)'\n }\n }\n },\n error: {\n color: 'oklch(0.444 0.177 26.899)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.808 0.114 19.571)'\n }\n }\n }\n }\n }\n})\n","import {\n AlertCircle,\n AlertTriangle,\n CheckCircle,\n Link2,\n XCircle\n} from 'lucide-react'\nimport type { FC, ReactNode } from 'react'\nimport {\n banner,\n closeButton,\n closeIcon,\n content,\n description,\n gridPattern,\n icon,\n iconContainer,\n link,\n textContainer,\n title\n} from './Banner.css'\n\ntype BannerVariant = 'info' | 'success' | 'warning' | 'alert' | 'error'\n\nexport interface BannerProps {\n title: string\n description?: string\n icon?: ReactNode\n showIcon?: boolean\n className?: string\n variant?: BannerVariant\n onClose?: () => void\n url?: string\n urlName?: string\n}\n\nconst defaultIcons: Record<BannerVariant, ReactNode> = {\n info: <Link2 style={{ width: '1rem', height: '1rem' }} strokeWidth={1.5} />,\n success: (\n <CheckCircle style={{ width: '1rem', height: '1rem' }} strokeWidth={1.5} />\n ),\n warning: (\n <AlertTriangle\n style={{ width: '1rem', height: '1rem' }}\n strokeWidth={1.5}\n />\n ),\n alert: (\n <AlertCircle style={{ width: '1rem', height: '1rem' }} strokeWidth={1.5} />\n ),\n error: <XCircle style={{ width: '1rem', height: '1rem' }} strokeWidth={1.5} />\n}\n\nexport const Banner: FC<BannerProps> = ({\n title: titleText,\n description: descriptionText,\n icon: customIcon,\n showIcon = true,\n className = '',\n variant = 'info',\n onClose,\n url,\n urlName\n}) => {\n return (\n <div className={`${banner({ variant })} ${className}`}>\n {/* Grid pattern overlay */}\n <svg\n className={gridPattern}\n width=\"100%\"\n height=\"100%\"\n aria-hidden=\"true\"\n >\n <defs>\n <pattern\n id={`grid-pattern-${variant}`}\n x=\"-1\"\n y=\"-2\"\n width=\"13\"\n height=\"13\"\n patternUnits=\"userSpaceOnUse\"\n >\n <path\n d=\"M 13 0 L 0 0 0 13\"\n fill=\"transparent\"\n stroke=\"currentColor\"\n strokeWidth=\"1\"\n >\n <title>Grid pattern</title>\n </path>\n </pattern>\n </defs>\n <rect\n fill={`url(#grid-pattern-${variant})`}\n width=\"100%\"\n height=\"100%\"\n />\n </svg>\n\n {/* Content */}\n <div className={content}>\n {showIcon && (\n <div className={iconContainer({ variant })}>\n <div className={icon({ variant })}>\n {customIcon || defaultIcons[variant]}\n </div>\n </div>\n )}\n <div className={textContainer}>\n <h3 className={title({ variant })}>{titleText}</h3>\n {descriptionText && (\n <p className={description({ variant })}>\n {descriptionText}\n {url && urlName && (\n <>\n {' '}\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={link({ variant })}\n >\n {urlName}\n </a>\n </>\n )}\n </p>\n )}\n </div>\n </div>\n\n {/* Close button */}\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n className={closeButton({ variant })}\n aria-label=\"Close banner\"\n >\n <svg\n className={closeIcon}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n >\n <title>Close icon</title>\n </path>\n </svg>\n </button>\n )}\n </div>\n )\n}\n","import { recipe } from '@vanilla-extract/recipes'\nimport { themeVars } from '~/theme.css'\n\nexport const button = recipe({\n base: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: themeVars.spacing.sm,\n borderRadius: themeVars.radius.md,\n fontSize: '0.875rem',\n fontWeight: 500,\n transition: 'all 0.2s ease-in-out',\n cursor: 'pointer',\n border: 'none',\n outline: 'none',\n whiteSpace: 'nowrap',\n ':disabled': {\n opacity: 0.5,\n cursor: 'not-allowed',\n pointerEvents: 'none'\n },\n ':focus-visible': {\n outline: `2px solid ${themeVars.colors.primary}`,\n outlineOffset: '2px'\n }\n },\n variants: {\n variant: {\n default: {\n backgroundColor: themeVars.colors.primary,\n color: themeVars.colors.primaryForeground,\n ':hover': {\n opacity: 0.9\n }\n },\n outline: {\n backgroundColor: 'transparent',\n border: `1px solid ${themeVars.colors.border}`,\n color: themeVars.colors.foreground,\n ':hover': {\n backgroundColor: themeVars.colors.accent,\n color: themeVars.colors.accentForeground\n }\n },\n ghost: {\n backgroundColor: 'transparent',\n color: themeVars.colors.foreground,\n ':hover': {\n backgroundColor: themeVars.colors.accent,\n color: themeVars.colors.accentForeground\n }\n },\n destructive: {\n backgroundColor: themeVars.colors.destructive,\n color: themeVars.colors.destructiveForeground,\n ':hover': {\n opacity: 0.9\n }\n },\n gradient: {\n background: `linear-gradient(to right, ${themeVars.colors.blue}, ${themeVars.colors.cyan})`,\n color: '#ffffff',\n ':hover': {\n opacity: 0.9\n }\n }\n },\n size: {\n default: {\n height: '2.5rem',\n padding: `0 ${themeVars.spacing.md}`\n },\n sm: {\n height: '2rem',\n padding: `0 ${themeVars.spacing.sm}`,\n fontSize: '0.75rem'\n },\n lg: {\n height: '3rem',\n padding: `0 ${themeVars.spacing.lg}`,\n fontSize: '1rem'\n },\n icon: {\n height: '2.5rem',\n width: '2.5rem',\n padding: 0\n }\n }\n },\n defaultVariants: {\n variant: 'default',\n size: 'default'\n }\n})\n","import type { ButtonHTMLAttributes, FC } from 'react'\nimport { button } from './Button.css'\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: 'default' | 'outline' | 'ghost' | 'destructive' | 'gradient'\n size?: 'default' | 'sm' | 'lg' | 'icon'\n asChild?: boolean\n}\n\nexport const Button: FC<ButtonProps> = ({\n variant = 'default',\n size = 'default',\n className = '',\n children,\n ...props\n}) => {\n return (\n <button className={`${button({ variant, size })} ${className}`} {...props}>\n {children}\n </button>\n )\n}\n","import { style } from '@vanilla-extract/css'\n\nexport const container = style({\n height: '100%',\n width: '100%',\n position: 'relative'\n})\n\nexport const canvas = style({\n pointerEvents: 'none'\n})\n","import type { FC, HTMLAttributes } from 'react'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { canvas, container } from './FlickeringGrid.css'\n\nexport interface FlickeringGridProps extends HTMLAttributes<HTMLDivElement> {\n squareSize?: number\n gridGap?: number\n flickerChance?: number\n color?: string\n width?: number\n height?: number\n maxOpacity?: number\n}\n\nexport const FlickeringGrid: FC<FlickeringGridProps> = ({\n squareSize = 4,\n gridGap = 6,\n flickerChance = 0.3,\n color = 'rgb(0, 0, 0)',\n width,\n height,\n className = '',\n maxOpacity = 0.3,\n ...props\n}) => {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const [isInView, setIsInView] = useState(false)\n const [canvasSize, setCanvasSize] = useState({ width: 0, height: 0 })\n\n const memoizedColor = useMemo(() => {\n const toRGBA = (color: string) => {\n if (typeof window === 'undefined') {\n return 'rgba(0, 0, 0,'\n }\n const canvasEl = document.createElement('canvas')\n canvasEl.width = canvasEl.height = 1\n const ctx = canvasEl.getContext('2d')\n if (!ctx) return 'rgba(255, 0, 0,'\n ctx.fillStyle = color\n ctx.fillRect(0, 0, 1, 1)\n const [r, g, b] = Array.from(ctx.getImageData(0, 0, 1, 1).data)\n return `rgba(${r}, ${g}, ${b},`\n }\n return toRGBA(color)\n }, [color])\n\n const setupCanvas = useCallback(\n (canvasEl: HTMLCanvasElement, width: number, height: number) => {\n const dpr = window.devicePixelRatio || 1\n canvasEl.width = width * dpr\n canvasEl.height = height * dpr\n canvasEl.style.width = `${width}px`\n canvasEl.style.height = `${height}px`\n const cols = Math.floor(width / (squareSize + gridGap))\n const rows = Math.floor(height / (squareSize + gridGap))\n\n const squares = new Float32Array(cols * rows)\n for (let i = 0; i < squares.length; i++) {\n squares[i] = Math.random() * maxOpacity\n }\n\n return { cols, rows, squares, dpr }\n },\n [squareSize, gridGap, maxOpacity]\n )\n\n const updateSquares = useCallback(\n (squares: Float32Array, deltaTime: number) => {\n for (let i = 0; i < squares.length; i++) {\n if (Math.random() < flickerChance * deltaTime) {\n squares[i] = Math.random() * maxOpacity\n }\n }\n },\n [flickerChance, maxOpacity]\n )\n\n const drawGrid = useCallback(\n (\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n cols: number,\n rows: number,\n squares: Float32Array,\n dpr: number\n ) => {\n ctx.clearRect(0, 0, width, height)\n ctx.fillStyle = 'transparent'\n ctx.fillRect(0, 0, width, height)\n\n for (let i = 0; i < cols; i++) {\n for (let j = 0; j < rows; j++) {\n const opacity = squares[i * rows + j]\n ctx.fillStyle = `${memoizedColor}${opacity})`\n ctx.fillRect(\n i * (squareSize + gridGap) * dpr,\n j * (squareSize + gridGap) * dpr,\n squareSize * dpr,\n squareSize * dpr\n )\n }\n }\n },\n [memoizedColor, squareSize, gridGap]\n )\n\n useEffect(() => {\n const canvasEl = canvasRef.current\n const container = containerRef.current\n if (!canvasEl || !container) return\n\n const ctx = canvasEl.getContext('2d')\n if (!ctx) return\n\n let animationFrameId: number\n let gridParams: ReturnType<typeof setupCanvas>\n\n const updateCanvasSize = () => {\n const newWidth = width || container.clientWidth\n const newHeight = height || container.clientHeight\n setCanvasSize({ width: newWidth, height: newHeight })\n gridParams = setupCanvas(canvasEl, newWidth, newHeight)\n }\n\n updateCanvasSize()\n\n let lastTime = 0\n const animate = (time: number) => {\n if (!isInView) return\n\n const deltaTime = (time - lastTime) / 1000\n lastTime = time\n\n updateSquares(gridParams.squares, deltaTime)\n drawGrid(\n ctx,\n canvasEl.width,\n canvasEl.height,\n gridParams.cols,\n gridParams.rows,\n gridParams.squares,\n gridParams.dpr\n )\n animationFrameId = requestAnimationFrame(animate)\n }\n\n const resizeObserver = new ResizeObserver(() => {\n updateCanvasSize()\n })\n\n resizeObserver.observe(container)\n\n const intersectionObserver = new IntersectionObserver(\n ([entry]) => {\n setIsInView(entry.isIntersecting)\n },\n { threshold: 0 }\n )\n\n intersectionObserver.observe(canvasEl)\n\n if (isInView) {\n animationFrameId = requestAnimationFrame(animate)\n }\n\n return () => {\n cancelAnimationFrame(animationFrameId)\n resizeObserver.disconnect()\n intersectionObserver.disconnect()\n }\n }, [setupCanvas, updateSquares, drawGrid, width, height, isInView])\n\n return (\n <div ref={containerRef} className={`${container} ${className}`} {...props}>\n <canvas\n ref={canvasRef}\n className={canvas}\n style={{\n width: canvasSize.width,\n height: canvasSize.height\n }}\n />\n </div>\n )\n}\n","import { style } from '@vanilla-extract/css'\nimport { themeVars } from '~/theme.css'\n\nexport const input = style({\n display: 'flex',\n width: '100%',\n borderRadius: themeVars.radius.md,\n border: `1px solid ${themeVars.colors.border}`,\n backgroundColor: themeVars.colors.background,\n padding: `${themeVars.spacing.sm} ${themeVars.spacing.md}`,\n fontSize: '0.875rem',\n color: themeVars.colors.foreground,\n transition: 'all 0.2s ease-in-out',\n outline: 'none',\n ':focus': {\n borderColor: themeVars.colors.primary,\n boxShadow: `0 0 0 1px ${themeVars.colors.primary}`\n },\n ':disabled': {\n cursor: 'not-allowed',\n opacity: 0.5\n },\n '::placeholder': {\n color: themeVars.colors.mutedForeground\n }\n})\n\nexport const label = style({\n fontSize: '0.875rem',\n fontWeight: 500,\n color: themeVars.colors.foreground,\n display: 'block',\n marginBottom: themeVars.spacing.xs\n})\n\nexport const textarea = style({\n display: 'flex',\n width: '100%',\n borderRadius: themeVars.radius.md,\n border: `1px solid ${themeVars.colors.border}`,\n backgroundColor: themeVars.colors.background,\n padding: `${themeVars.spacing.sm} ${themeVars.spacing.md}`,\n fontSize: '0.875rem',\n color: themeVars.colors.foreground,\n transition: 'all 0.2s ease-in-out',\n outline: 'none',\n minHeight: '5rem',\n resize: 'vertical',\n ':focus': {\n borderColor: themeVars.colors.primary,\n boxShadow: `0 0 0 1px ${themeVars.colors.primary}`\n },\n ':disabled': {\n cursor: 'not-allowed',\n opacity: 0.5\n },\n '::placeholder': {\n color: themeVars.colors.mutedForeground\n }\n})\n","import type {\n InputHTMLAttributes,\n LabelHTMLAttributes,\n TextareaHTMLAttributes\n} from 'react'\nimport { type FC, forwardRef, type ReactNode } from 'react'\nimport {\n input,\n label as labelStyle,\n textarea as textareaStyle\n} from './Input.css'\n\nexport interface InputProps extends InputHTMLAttributes<HTMLInputElement> {}\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(\n ({ className = '', ...props }, ref) => {\n return <input ref={ref} className={`${input} ${className}`} {...props} />\n }\n)\n\nInput.displayName = 'Input'\n\nexport interface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {\n children?: ReactNode\n}\n\nexport const Label: FC<LabelProps> = ({\n className = '',\n children,\n ...props\n}) => {\n return (\n // biome-ignore lint/a11y/noLabelWithoutControl: Label will be associated with input when used\n <label className={`${labelStyle} ${className}`} {...props}>\n {children}\n </label>\n )\n}\n\nexport interface TextareaProps\n extends TextareaHTMLAttributes<HTMLTextAreaElement> {}\n\nexport const Textarea: FC<TextareaProps> = ({ className = '', ...props }) => {\n return <textarea className={`${textareaStyle} ${className}`} {...props} />\n}\n","import { keyframes, style } from '@vanilla-extract/css'\nimport { themeVars } from '~/theme.css'\n\nconst spin = keyframes({\n '0%': { transform: 'rotate(0deg)' },\n '100%': { transform: 'rotate(360deg)' }\n})\n\nexport const stepperContainer = style({\n width: '100%',\n marginTop: '0.5rem'\n})\n\nexport const stepperWrapper = style({\n display: 'flex',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n position: 'relative',\n paddingTop: '0.5rem'\n})\n\nexport const stepContainer = style({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n position: 'relative',\n flex: 1\n})\n\nexport const stepIndicator = style({\n width: '1rem',\n height: '1rem',\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: 'all 0.2s'\n})\n\nexport const stepIndicatorCompleted = style({\n backgroundColor: '#15803d',\n color: 'white'\n})\n\nexport const stepIndicatorActive = style({\n backgroundColor: '#3b82f6',\n color: 'white'\n})\n\nexport const stepIndicatorPending = style({\n backgroundColor: themeVars.colors.muted,\n color: themeVars.colors.mutedForeground\n})\n\nexport const stepLine = style({\n position: 'absolute',\n top: '0.5rem',\n left: '50%',\n width: '100%',\n height: '0.125rem',\n transform: 'translateY(-50%) translateX(0.5rem)',\n transition: 'background-color 0.2s'\n})\n\nexport const stepLineCompleted = style({\n backgroundColor: '#3b82f6'\n})\n\nexport const stepLinePending = style({\n backgroundColor: themeVars.colors.border\n})\n\nexport const stepLabel = style({\n marginTop: '0.25rem',\n fontSize: '0.625rem',\n fontWeight: 500,\n textAlign: 'center',\n transition: 'color 0.2s'\n})\n\nexport const stepLabelActive = style({\n color: themeVars.colors.foreground\n})\n\nexport const stepLabelInactive = style({\n color: themeVars.colors.mutedForeground\n})\n\nexport const stepDot = style({\n width: '0.5rem',\n height: '0.5rem',\n borderRadius: '50%',\n backgroundColor: 'currentColor'\n})\n\nexport const stepSpinner = style({\n width: '0.75rem',\n height: '0.75rem',\n border: '2px solid white',\n borderTop: '2px solid transparent',\n borderRadius: '50%',\n animation: `${spin} 1s linear infinite`\n})\n","import type { FC } from 'react'\nimport * as styles from './Stepper.css'\n\ninterface StepProps {\n title: string\n description?: string\n isCompleted?: boolean\n isActive?: boolean\n isLast?: boolean\n isLoading?: boolean\n}\n\nconst Step: FC<StepProps> = ({\n title,\n isLoading,\n isCompleted,\n isActive,\n isLast\n}) => {\n return (\n <div className={styles.stepContainer}>\n {/* Step indicator */}\n <div\n className={`${styles.stepIndicator} ${\n isCompleted\n ? styles.stepIndicatorCompleted\n : isActive\n ? styles.stepIndicatorActive\n : styles.stepIndicatorPending\n }`}\n >\n {isCompleted ? (\n <svg\n width=\"16\"\n height=\"16\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <title>Check</title>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 13l4 4L19 7\"\n />\n </svg>\n ) : isLoading ? (\n <div className={styles.stepSpinner} />\n ) : (\n <div className={styles.stepDot} />\n )}\n </div>\n\n {/* Connection line */}\n {!isLast && (\n <div\n className={`${styles.stepLine} ${\n isCompleted ? styles.stepLineCompleted : styles.stepLinePending\n }`}\n />\n )}\n\n {/* Step label */}\n <span\n className={`${styles.stepLabel} ${\n isActive || isCompleted\n ? styles.stepLabelActive\n : styles.stepLabelInactive\n }`}\n >\n {title}\n </span>\n </div>\n )\n}\n\ninterface StepperProps {\n steps: Array<{ title: string; description?: string }>\n currentStep: number\n isLoading?: boolean\n}\n\nexport const Stepper: FC<StepperProps> = ({\n steps,\n currentStep,\n isLoading\n}) => {\n return (\n <div className={styles.stepperContainer}>\n <div className={styles.stepperWrapper}>\n {steps.map((step, index) => (\n <Step\n key={step.title}\n title={step.title}\n description={step.description}\n isCompleted={index < currentStep}\n isLoading={isLoading && index === currentStep}\n isActive={index === currentStep}\n isLast={index === steps.length - 1}\n />\n ))}\n </div>\n </div>\n )\n}\n","import { keyframes, style } from '@vanilla-extract/css'\nimport { themeVars } from '~/theme.css'\n\nconst spin = keyframes({\n '0%': { transform: 'rotate(0deg)' },\n '100%': { transform: 'rotate(360deg)' }\n})\n\nexport const overlay = style({\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n position: 'fixed',\n inset: 0,\n zIndex: 50\n})\n\nexport const content = style({\n backgroundColor: themeVars.colors.background,\n borderRadius: themeVars.radius.lg,\n boxShadow:\n '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n width: '90vw',\n maxWidth: '42rem',\n maxHeight: '90vh',\n overflow: 'auto',\n zIndex: 51,\n border: `1px solid ${themeVars.colors.border}`,\n padding: themeVars.spacing.md,\n display: 'flex',\n flexDirection: 'column'\n})\n\nexport const loadingOverlay = style({\n position: 'absolute',\n inset: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n backdropFilter: 'blur(4px)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 100,\n borderRadius: themeVars.radius.lg\n})\n\nexport const loadingContent = style({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: themeVars.spacing.md\n})\n\nexport const spinner = style({\n width: '2rem',\n height: '2rem',\n animation: `${spin} 1s linear infinite`,\n color: 'white'\n})\n\nexport const header = style({\n position: 'relative',\n marginBottom: themeVars.spacing.sm\n})\n\nexport const title = style({\n fontSize: '1rem',\n fontWeight: 600,\n color: themeVars.colors.foreground,\n marginBottom: '0.25rem'\n})\n\nexport const description = style({\n fontSize: '0.875rem',\n color: themeVars.colors.mutedForeground\n})\n\nexport const closeButton = style({\n position: 'absolute',\n top: 0,\n right: 0,\n padding: '0.25rem',\n cursor: 'pointer',\n border: 'none',\n background: 'transparent',\n color: themeVars.colors.foreground,\n borderRadius: themeVars.radius.md,\n transition: 'background-color 0.2s',\n ':hover': {\n backgroundColor: themeVars.colors.muted\n }\n})\n\nexport const body = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.sm,\n flex: 1,\n overflow: 'auto'\n})\n\nexport const formSection = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.sm\n})\n\nexport const fieldGroup = style({\n display: 'flex',\n flexDirection: 'column',\n gap: '0.375rem'\n})\n\nexport const dateInputWrapper = style({\n position: 'relative'\n})\n\nexport const dateIcon = style({\n position: 'absolute',\n left: '0.75rem',\n top: '50%',\n transform: 'translateY(-50%)',\n color: themeVars.colors.mutedForeground,\n pointerEvents: 'none'\n})\n\nexport const inputError = style({\n borderColor: themeVars.colors.destructive\n})\n\nexport const infoText = style({\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem',\n fontSize: '0.75rem',\n color: themeVars.colors.mutedForeground\n})\n\nexport const errorText = style({\n fontSize: '0.75rem',\n color: themeVars.colors.destructive\n})\n\nexport const summaryGrid = style({\n display: 'grid',\n gridTemplateColumns: 'repeat(2, 1fr)',\n gap: themeVars.spacing.sm,\n marginTop: '0.5rem',\n '@media': {\n '(max-width: 768px)': {\n gridTemplateColumns: '1fr'\n }\n }\n})\n\nexport const summaryCard = style({\n borderRadius: themeVars.radius.md,\n border: `1px solid ${themeVars.colors.border}`,\n backgroundColor: `${themeVars.colors.muted}40`,\n padding: themeVars.spacing.md,\n display: 'flex',\n flexDirection: 'column',\n gap: '0.375rem',\n transition: 'all 0.2s ease',\n ':hover': {\n borderColor: themeVars.colors.border,\n backgroundColor: `${themeVars.colors.muted}60`\n }\n})\n\nexport const summaryHeader = style({\n display: 'flex',\n alignItems: 'center',\n gap: '0.375rem',\n fontSize: '0.75rem',\n color: themeVars.colors.mutedForeground,\n marginBottom: '0.25rem'\n})\n\nexport const summaryContent = style({\n display: 'flex',\n flexDirection: 'column',\n gap: '0.25rem'\n})\n\nexport const summaryValue = style({\n fontSize: '0.8125rem',\n fontWeight: 600,\n color: themeVars.colors.foreground\n})\n\nexport const summarySubtext = style({\n fontSize: '0.75rem',\n color: themeVars.colors.mutedForeground\n})\n\nexport const summaryError = style({\n fontSize: '0.75rem',\n color: themeVars.colors.destructive\n})\n\nexport const summaryList = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.xs\n})\n\nexport const summaryRow = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n fontSize: '0.875rem',\n color: themeVars.colors.mutedForeground,\n paddingTop: themeVars.spacing.xs,\n borderTop: `1px solid ${themeVars.colors.border}50`,\n ':first-child': {\n borderTop: 'none',\n paddingTop: 0\n }\n})\n\nexport const footer = style({\n display: 'flex',\n gap: themeVars.spacing.sm,\n justifyContent: 'flex-end',\n marginTop: themeVars.spacing.sm,\n paddingTop: themeVars.spacing.sm,\n borderTop: `1px solid ${themeVars.colors.border}`\n})\n\nexport const costSection = style({\n borderRadius: themeVars.radius.md,\n border: `1px solid ${themeVars.colors.border}`,\n backgroundColor: `${themeVars.colors.muted}40`,\n padding: themeVars.spacing.md,\n display: 'flex',\n flexDirection: 'column',\n gap: '0.5rem',\n marginTop: '0.5rem',\n transition: 'all 0.2s ease',\n ':hover': {\n borderColor: themeVars.colors.border,\n backgroundColor: `${themeVars.colors.muted}60`\n }\n})\n\nexport const costHeader = style({\n display: 'flex',\n alignItems: 'center',\n gap: '0.375rem',\n fontSize: '0.875rem',\n fontWeight: 600,\n color: themeVars.colors.foreground,\n marginBottom: '0.25rem'\n})\n\nexport const costContent = style({\n display: 'flex',\n flexDirection: 'column',\n gap: '0.375rem'\n})\n\nexport const costRow = style({\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n fontSize: '0.8125rem'\n})\n\nexport const costLabel = style({\n color: themeVars.colors.mutedForeground\n})\n\nexport const costValue = style({\n fontWeight: 500,\n color: themeVars.colors.foreground\n})\n\nexport const costLoading = style({\n display: 'flex',\n alignItems: 'center',\n gap: '0.375rem',\n fontSize: '0.875rem',\n color: themeVars.colors.mutedForeground,\n padding: '0.5rem',\n justifyContent: 'center'\n})\n\nexport const costError = style({\n fontSize: '0.875rem',\n color: themeVars.colors.destructive,\n padding: '0.5rem',\n display: 'flex',\n alignItems: 'center',\n gap: '0.375rem',\n justifyContent: 'center',\n borderRadius: themeVars.radius.sm,\n backgroundColor: `${themeVars.colors.destructive}10`\n})\n\nexport const costWarning = style({\n fontSize: '0.75rem',\n color: themeVars.colors.mutedForeground,\n padding: '0.5rem',\n display: 'flex',\n alignItems: 'flex-start',\n gap: '0.375rem',\n borderRadius: themeVars.radius.sm,\n backgroundColor: 'rgba(245, 158, 11, 0.1)',\n border: '1px solid rgba(245, 158, 11, 0.2)',\n marginTop: '0.25rem'\n})\n\nexport const costDivider = style({\n height: '1px',\n backgroundColor: themeVars.colors.border,\n margin: '0.5rem 0'\n})\n\nexport const costTotalRow = style({\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n paddingTop: '0.5rem',\n marginTop: '0.25rem',\n borderTop: `1px solid ${themeVars.colors.border}`\n})\n\nexport const costTotalLabel = style({\n fontSize: '0.875rem',\n fontWeight: 600,\n color: themeVars.colors.foreground\n})\n\nexport const costTotalValue = style({\n fontSize: '0.9375rem',\n fontWeight: 700,\n color: themeVars.colors.foreground\n})\n\nexport const estimatedBadge = style({\n fontSize: '0.625rem',\n fontWeight: 600,\n padding: '0.125rem 0.375rem',\n borderRadius: themeVars.radius.sm,\n backgroundColor: 'rgba(245, 158, 11, 0.2)',\n color: '#f59e0b',\n textTransform: 'uppercase',\n letterSpacing: '0.025em',\n marginLeft: 'auto'\n})\n","import type {\n ISignAndExecuteTransaction,\n ISponsorConfig\n} from '@cmdoss/walrus-site-builder'\nimport { mainPackage } from '@cmdoss/walrus-site-builder'\nimport type { SuiClient } from '@mysten/sui/client'\nimport { Transaction } from '@mysten/sui/transactions'\nimport type { WalletAccount } from '@mysten/wallet-standard'\nimport {\n MAINNET_WALRUS_PACKAGE_CONFIG,\n TESTNET_WALRUS_PACKAGE_CONFIG,\n type WalrusClient\n} from '@mysten/walrus'\nimport { useStore } from '@nanostores/react'\nimport * as Dialog from '@radix-ui/react-dialog'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { Calendar, Clock, DollarSign, Info, Loader2, X } from 'lucide-react'\nimport type { FC } from 'react'\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport { useEpochDuration, useTransactionExecutor } from '~/hooks'\nimport { useStorageCostQuery } from '~/queries/storage-cost.query'\nimport { useWalrusSiteQuery } from '~/queries/walrus-site.query'\nimport { isExtendTimeDialogOpen } from '~/stores/site-domain.store'\nimport { Banner } from '../ui'\nimport { Button } from '../ui/Button'\nimport { Input, Label } from '../ui/Input'\nimport * as styles from './ExtendTimeDialog.css'\n\ninterface ExtendTimeDialogProps {\n siteId: string | undefined\n currentAccount: WalletAccount | null\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n walrusClient: WalrusClient\n }\n signAndExecuteTransaction: ISignAndExecuteTransaction\n sponsorConfig?: ISponsorConfig\n onSuccess?: (message: string, digest: string) => void\n}\n\nconst ExtendTimeDialog: FC<ExtendTimeDialogProps> = ({\n siteId,\n currentAccount,\n clients: { suiClient, queryClient, walrusClient },\n signAndExecuteTransaction,\n sponsorConfig,\n onSuccess\n}) => {\n const isOpen = useStore(isExtendTimeDialogOpen)\n const [selectedDate, setSelectedDate] = useState<string>('')\n const [epochs, setEpochs] = useState<number>(1)\n const [isExtending, setIsExtending] = useState(false)\n const [dateError, setDateError] = useState<string | null>(null)\n const [currentEpochsRemaining, setCurrentEpochsRemaining] = useState<\n number | null\n >(null)\n const [expirationDates, setExpirationDates] = useState<Map<string, Date>>(\n new Map()\n )\n const [totalFileSize, setTotalFileSize] = useState<number | null>(null)\n\n const { epochDurationMs, formatDate } = useEpochDuration(walrusClient)\n const txExecutor = useTransactionExecutor({\n suiClient,\n walletAddress: currentAccount?.address,\n signAndExecuteTransaction,\n sponsorConfig\n })\n\n const { data: siteData } = useWalrusSiteQuery(siteId, {\n suiClient,\n queryClient\n })\n\n // Function to fetch expiration dates and blob sizes\n const fetchExpirationDates = useCallback(async () => {\n if (!siteId || !walrusClient || !currentAccount || !siteData?.resources) {\n return\n }\n\n try {\n const blobType = await walrusClient.getBlobType()\n const datesMap = new Map<string, Date>()\n let totalSize = 0\n\n // Get staking state once before the loop\n const stakingState = await walrusClient.stakingState()\n const currentEpoch = Number(stakingState.epoch)\n const epochDuration = Number(stakingState.epoch_duration)\n\n let cursor: string | null | undefined = null\n let hasNextPage = true\n\n while (hasNextPage) {\n const ownedObjects = await suiClient.getOwnedObjects({\n owner: currentAccount.address,\n filter: { StructType: blobType },\n options: { showContent: true },\n cursor\n })\n\n for (const resource of siteData.resources) {\n const blobId = resource.blob_id\n if (datesMap.has(blobId)) continue\n\n for (const obj of ownedObjects.data) {\n if (obj.data?.content && 'fields' in obj.data.content) {\n const fields = obj.data.content.fields as Record<string, unknown>\n if ('blob_id' in fields) {\n const objBlobId = String(fields.blob_id)\n if (objBlobId === blobId) {\n const storage = fields.storage as\n | {\n fields?: { end_epoch?: unknown }\n }\n | undefined\n\n if (storage?.fields?.end_epoch !== undefined) {\n const endEpoch = Number(storage.fields.end_epoch)\n const remainingEpochs = endEpoch - currentEpoch\n const expirationTime =\n Date.now() + remainingEpochs * epochDuration\n datesMap.set(blobId, new Date(expirationTime))\n\n // Get blob size from fields.size (onchain data has this field)\n const sizeField = fields.size\n if (sizeField !== undefined) {\n // Size can be string or number\n const size =\n typeof sizeField === 'string'\n ? Number(sizeField)\n : Number(sizeField)\n if (!Number.isNaN(size) && size > 0) {\n totalSize += size\n }\n }\n break\n }\n }\n }\n }\n }\n }\n\n hasNextPage = ownedObjects.hasNextPage\n cursor = ownedObjects.nextCursor\n }\n\n setExpirationDates(datesMap)\n setTotalFileSize(totalSize > 0 ? totalSize : null)\n } catch (error) {\n console.error('Error fetching expiration dates:', error)\n }\n }, [siteId, walrusClient, currentAccount, suiClient, siteData])\n\n // Query storage cost (only when we have file size)\n const {\n data: storageCostData,\n isLoading: isStorageCostLoading,\n error: storageCostError\n } = useStorageCostQuery(totalFileSize, epochs, {\n queryClient,\n walrusClient\n })\n\n // Calculate estimated cost as fallback (rough estimate: ~1KB per resource)\n const estimatedFileSize = useMemo(() => {\n if (totalFileSize !== null) return null\n if (!siteData?.resources) return null\n // Estimate: average 10KB per resource\n return siteData.resources.length * 10 * 1024\n }, [totalFileSize, siteData?.resources])\n\n // Query estimated cost as fallback\n const { data: estimatedCostData, isLoading: isEstimatedCostLoading } =\n useStorageCostQuery(estimatedFileSize, epochs, {\n queryClient,\n walrusClient\n })\n\n // Format file size helper\n const formatFileSize = useCallback((bytes: number | null): string => {\n if (bytes === null || bytes === 0) return 'Unknown'\n const units = ['B', 'KB', 'MB', 'GB']\n let size = bytes\n let unitIndex = 0\n while (size >= 1024 && unitIndex < units.length - 1) {\n size /= 1024\n unitIndex++\n }\n return `${size.toFixed(2)} ${units[unitIndex]}`\n }, [])\n\n // Format WAL amount helper\n const formatWalAmount = useCallback((amount: string | undefined): string => {\n if (!amount) return '—'\n const num = BigInt(amount)\n // WAL has 9 decimals\n const formatted = Number(num) / 1_000_000_000\n return formatted.toFixed(6)\n }, [])\n\n // Query blob expiration dates\n useEffect(() => {\n if (isOpen && siteId) {\n fetchExpirationDates()\n }\n }, [isOpen, siteId, fetchExpirationDates])\n\n // Calculate current expiration date (earliest expiration from all resources)\n const currentExpiredDateMemo = useMemo(() => {\n if (!siteData?.resources || siteData.resources.length === 0) {\n return null\n }\n\n const timestamps = siteData.resources\n .map(resource => expirationDates.get(resource.blob_id)?.getTime())\n .filter((timestamp): timestamp is number => typeof timestamp === 'number')\n\n if (timestamps.length === 0) {\n return null\n }\n\n return new Date(Math.min(...timestamps))\n }, [siteData?.resources, expirationDates])\n\n // Calculate current epochs remaining\n useEffect(() => {\n if (!currentExpiredDateMemo || !epochDurationMs) {\n setCurrentEpochsRemaining(null)\n return\n }\n\n const now = Date.now()\n if (currentExpiredDateMemo.getTime() <= now) {\n setCurrentEpochsRemaining(0)\n return\n }\n\n const remaining = Math.ceil(\n (currentExpiredDateMemo.getTime() - now) / epochDurationMs\n )\n setCurrentEpochsRemaining(remaining)\n }, [currentExpiredDateMemo, epochDurationMs])\n\n // Calculate min and max dates for date picker\n const minDate = useMemo(() => {\n if (!epochDurationMs || !currentExpiredDateMemo) return ''\n const now = Date.now()\n const currentExpiration = currentExpiredDateMemo.getTime()\n\n // Min date is either current expiration or now + 1 epoch, whichever is later\n const minEpochs = 1\n const minFromNow = now + minEpochs * epochDurationMs\n const minTimestamp = Math.max(currentExpiration, minFromNow)\n\n return new Date(minTimestamp).toISOString().slice(0, 10)\n }, [epochDurationMs, currentExpiredDateMemo])\n\n const maxDate = useMemo(() => {\n if (!epochDurationMs || !currentExpiredDateMemo) return ''\n const currentExpiration = currentExpiredDateMemo.getTime()\n const maxEpochs = 365\n const maxTimestamp = currentExpiration + maxEpochs * epochDurationMs\n return new Date(maxTimestamp).toISOString().slice(0, 10)\n }, [epochDurationMs, currentExpiredDateMemo])\n\n // Calculate epochs from selected date\n const calculateEpochsFromDate = (dateString: string) => {\n if (!epochDurationMs || !dateString || !currentExpiredDateMemo) return 1\n\n const targetTime = new Date(dateString).getTime()\n const currentExpiration = currentExpiredDateMemo.getTime()\n const diffMs = targetTime - currentExpiration\n\n if (diffMs <= 0) return 1\n\n // Calculate epochs and round up\n const exactEpochs = diffMs / epochDurationMs\n const roundedEpochs = Math.ceil(exactEpochs)\n\n // Clamp between 1 and 365\n return Math.max(1, Math.min(365, roundedEpochs))\n }\n\n // Handle date change\n const handleDateChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newDate = e.target.value\n setSelectedDate(newDate)\n setDateError(null)\n\n if (!newDate) {\n setEpochs(1)\n return\n }\n\n const calculatedEpochs = calculateEpochsFromDate(newDate)\n setEpochs(calculatedEpochs)\n }\n\n // Get projected date from epochs\n const projectedDate = useMemo(() => {\n if (!epochDurationMs || !currentExpiredDateMemo) return null\n const currentExpiration = currentExpiredDateMemo.getTime()\n const projectedTimestamp = currentExpiration + epochs * epochDurationMs\n return new Date(projectedTimestamp)\n }, [epochs, currentExpiredDateMemo, epochDurationMs])\n\n // Initialize selected date when dialog opens\n useEffect(() => {\n if (isOpen && epochDurationMs && currentExpiredDateMemo) {\n // Default to current expiration + 1 epoch\n const defaultTimestamp =\n currentExpiredDateMemo.getTime() + epochDurationMs\n const defaultDate = new Date(defaultTimestamp).toISOString().slice(0, 10)\n setSelectedDate(defaultDate)\n setEpochs(1)\n setDateError(null)\n }\n }, [isOpen, epochDurationMs, currentExpiredDateMemo])\n\n const handleExtend = useCallback(async () => {\n if (\n !walrusClient ||\n !currentAccount ||\n !siteData?.resources ||\n siteData.resources.length === 0 ||\n !siteId\n ) {\n setDateError('Cannot extend blobs: missing required data')\n return\n }\n\n if (!epochs || epochs <= 0 || epochs > 365) {\n setDateError('Invalid epoch count. Must be between 1 and 365')\n return\n }\n\n if (!selectedDate) {\n setDateError('Please select an expiration date')\n return\n }\n\n if (!txExecutor) {\n setDateError('Transaction executor not available')\n return\n }\n\n setIsExtending(true)\n setDateError(null)\n\n try {\n const blobType = await walrusClient.getBlobType()\n const network = suiClient.network\n\n // Determine network-specific constants\n const walCoinType =\n mainPackage[network as keyof typeof mainPackage]?.walrusCoinType\n const walrusPackageId =\n mainPackage[network as keyof typeof mainPackage]?.walrusPackageId\n const systemObjectId =\n network === 'mainnet'\n ? MAINNET_WALRUS_PACKAGE_CONFIG.systemObjectId\n : TESTNET_WALRUS_PACKAGE_CONFIG.systemObjectId\n\n if (!walCoinType || !walrusPackageId) {\n throw new Error('Network configuration not found')\n }\n\n // Map blob_id to blobObjectId\n const blobIdToObjectIdMap = new Map<string, string>()\n let cursor: string | null | undefined = null\n let hasNextPage = true\n\n while (hasNextPage) {\n const ownedObjects = await suiClient.getOwnedObjects({\n owner: currentAccount.address,\n filter: { StructType: blobType },\n options: { showContent: true },\n cursor\n })\n\n for (const resource of siteData.resources) {\n const blobId = resource.blob_id\n if (blobIdToObjectIdMap.has(blobId)) continue\n\n for (const obj of ownedObjects.data) {\n if (obj.data?.content && 'fields' in obj.data.content) {\n const fields = obj.data.content.fields as Record<string, unknown>\n if ('blob_id' in fields) {\n const objBlobId = String(fields.blob_id)\n if (objBlobId === blobId) {\n blobIdToObjectIdMap.set(blobId, obj.data.objectId)\n break\n }\n }\n }\n }\n }\n\n hasNextPage = ownedObjects.hasNextPage\n cursor = ownedObjects.nextCursor\n }\n\n if (blobIdToObjectIdMap.size === 0) {\n throw new Error(\n 'No blob objects found for this site. Make sure you own the blob objects.'\n )\n }\n\n const tx = new Transaction()\n tx.setSender(currentAccount.address)\n\n const walCoin = await suiClient.getCoins({\n owner: currentAccount.address,\n coinType: walCoinType\n })\n\n if (walCoin.data.length === 0) {\n throw new Error(\n 'No WAL coins found in wallet. Please acquire WAL tokens first.'\n )\n }\n\n // Merge all WAL coins\n if (walCoin.data.length > 1) {\n tx.mergeCoins(\n tx.object(walCoin.data[0].coinObjectId),\n walCoin.data.slice(1).map(coin => tx.object(coin.coinObjectId))\n )\n }\n\n // Extend all blobs by adding epochs to their current expiration\n for (const [_blobId, objectId] of blobIdToObjectIdMap.entries()) {\n tx.moveCall({\n package: walrusPackageId,\n module: 'system',\n function: 'extend_blob',\n arguments: [\n tx.object(systemObjectId),\n tx.object(objectId),\n tx.pure.u32(epochs),\n tx.object(walCoin.data[0].coinObjectId)\n ]\n })\n }\n\n const digest = await txExecutor.execute({\n transaction: tx,\n description: `Extending ${blobIdToObjectIdMap.size} blob(s) by ${epochs} epoch(s)`\n })\n\n // Wait for transaction to complete\n await suiClient.waitForTransaction({ digest })\n\n // Invalidate queries to refetch updated data\n await queryClient.invalidateQueries({\n predicate: query => {\n const key = query.queryKey\n return (\n (Array.isArray(key) &&\n (key[0] === 'walrus-site' || key[0] === 'walrus-sites')) ||\n false\n )\n }\n })\n\n // Refresh expiration dates to reflect the extension\n await fetchExpirationDates()\n\n // Show success message\n const successMessage = `Successfully extended ${blobIdToObjectIdMap.size} blob(s) by ${epochs} epoch(s)`\n onSuccess?.(successMessage, digest)\n\n // Close dialog and reset\n isExtendTimeDialogOpen.set(false)\n setSelectedDate('')\n setEpochs(1)\n setDateError(null)\n } catch (error) {\n console.error('Error extending blobs:', error)\n setDateError(\n `Failed to extend: ${error instanceof Error ? error.message : 'Unknown error'}`\n )\n } finally {\n setIsExtending(false)\n }\n }, [\n walrusClient,\n currentAccount,\n siteData,\n siteId,\n epochs,\n selectedDate,\n txExecutor,\n suiClient,\n queryClient,\n onSuccess,\n fetchExpirationDates\n ])\n\n const handleClose = () => {\n isExtendTimeDialogOpen.set(false)\n setSelectedDate('')\n setEpochs(1)\n setDateError(null)\n }\n\n if (!siteId || !siteData) {\n return null\n }\n\n return (\n <Dialog.Root open={isOpen} onOpenChange={open => !open && handleClose()}>\n <Dialog.Portal>\n <Dialog.Overlay className={styles.overlay} />\n <Dialog.Content className={styles.content}>\n {/* Loading Overlay */}\n {isExtending && (\n <div className={styles.loadingOverlay}>\n <div className={styles.loadingContent}>\n <Loader2 className={styles.spinner} />\n <p>Extending storage time...</p>\n </div>\n </div>\n )}\n\n {/* Header */}\n <div className={styles.header}>\n <Dialog.Title className={styles.title}>\n Extend Time for {siteData.name}\n </Dialog.Title>\n <Dialog.Description className={styles.description}>\n Add epochs to extend the storage time for blobs in this site.\n Epochs will be added to the current expiration time.\n </Dialog.Description>\n <Dialog.Close asChild>\n <button type=\"button\" className={styles.closeButton}>\n <X size={20} />\n </button>\n </Dialog.Close>\n </div>\n\n {/* Content */}\n <div className={styles.body}>\n {/* Expired Warning Banner */}\n {currentEpochsRemaining === 0 && (\n <Banner\n title=\"Site Expired\"\n description=\"This site has expired and cannot be extended. The blobs are no longer available on the Walrus network.\"\n variant=\"warning\"\n />\n )}\n\n {/* Info Banner */}\n {currentEpochsRemaining !== 0 && (\n <Banner\n title=\"How Extension Works\"\n description=\"Select a target expiration date. The system will calculate the required epochs to extend your blobs to that date. Duration is rounded up to the nearest epoch.\"\n variant=\"info\"\n />\n )}\n\n <div className={styles.formSection}>\n <div className={styles.fieldGroup}>\n <Label htmlFor=\"expiration-date\">Target Expiration Date</Label>\n <div className={styles.dateInputWrapper}>\n <Input\n id=\"expiration-date\"\n type=\"date\"\n value={selectedDate}\n min={minDate}\n max={maxDate}\n onChange={handleDateChange}\n disabled={currentEpochsRemaining === 0 || isExtending}\n className={dateError ? styles.inputError : ''}\n />\n </div>\n\n {/* Compact Info */}\n {epochDurationMs && (\n <div className={styles.infoText}>\n <Info size={14} />\n <span>\n 1 epoch ≈{' '}\n {(epochDurationMs / (1000 * 60 * 60 * 24)).toFixed(1)}{' '}\n days • Duration rounded up. Maximum 365 epochs per extend.\n </span>\n </div>\n )}\n {dateError && <p className={styles.errorText}>{dateError}</p>}\n </div>\n\n {/* Summary Cards */}\n <div className={styles.summaryGrid}>\n {/* Current Expiration Card */}\n <div className={styles.summaryCard}>\n <div className={styles.summaryHeader}>\n <Calendar size={14} />\n <span>Current Expiration</span>\n </div>\n {currentExpiredDateMemo ? (\n <div className={styles.summaryContent}>\n <div className={styles.summaryValue}>\n {formatDate(currentExpiredDateMemo)}\n </div>\n {currentEpochsRemaining !== null &&\n currentEpochsRemaining > 0 && (\n <div className={styles.summarySubtext}>\n {currentEpochsRemaining} epoch\n {currentEpochsRemaining !== 1 ? 's' : ''} remaining\n </div>\n )}\n {currentEpochsRemaining === 0 && (\n <div className={styles.summaryError}>Expired</div>\n )}\n </div>\n ) : (\n <div className={styles.summaryValue}>Unavailable</div>\n )}\n </div>\n\n {/* Projected Expiration Card */}\n <div className={styles.summaryCard}>\n <div className={styles.summaryHeader}>\n <Clock size={14} />\n <span>New Expiration Date</span>\n </div>\n {projectedDate ? (\n <div className={styles.summaryContent}>\n <div className={styles.summaryValue}>\n {formatDate(projectedDate)}\n </div>\n {currentEpochsRemaining !== null && (\n <div className={styles.summarySubtext}>\n {currentEpochsRemaining} →{' '}\n {currentEpochsRemaining + epochs} epochs (+{epochs}{' '}\n epoch{epochs !== 1 ? 's' : ''})\n </div>\n )}\n </div>\n ) : (\n <div className={styles.summaryValue}>Select a date</div>\n )}\n </div>\n </div>\n\n {/* Storage Cost Section */}\n <div className={styles.costSection}>\n <div className={styles.costHeader}>\n <DollarSign size={16} />\n <span>Storage Cost</span>\n {totalFileSize === null && estimatedFileSize !== null && (\n <span className={styles.estimatedBadge}>Estimated</span>\n )}\n </div>\n <div className={styles.costContent}>\n <div className={styles.costRow}>\n <span className={styles.costLabel}>Size:</span>\n <span className={styles.costValue}>\n {totalFileSize !== null\n ? formatFileSize(totalFileSize)\n : estimatedFileSize !== null\n ? formatFileSize(estimatedFileSize)\n : 'Unknown'}\n </span>\n </div>\n <div className={styles.costRow}>\n <span className={styles.costLabel}>Resources:</span>\n <span className={styles.costValue}>\n {siteData?.resources?.length || 0} resources • {epochs}{' '}\n epoch\n {epochs !== 1 ? 's' : ''}\n </span>\n </div>\n {isStorageCostLoading || isEstimatedCostLoading ? (\n <div className={styles.costLoading}>\n <Loader2 size={14} className={styles.spinner} />\n <span>Calculating cost...</span>\n </div>\n ) : storageCostData || estimatedCostData ? (\n <>\n {totalFileSize === null && estimatedFileSize !== null && (\n <div className={styles.costWarning}>\n <Info size={12} />\n <span>\n Estimated cost based on{' '}\n {siteData?.resources?.length || 0} resource\n {siteData?.resources?.length !== 1 ? 's' : ''}\n </span>\n </div>\n )}\n <div className={styles.costDivider} />\n <div className={styles.costRow}>\n <span className={styles.costLabel}>Storage Cost:</span>\n <span className={styles.costValue}>\n {formatWalAmount(\n storageCostData?.storageCost ||\n estimatedCostData?.storageCost\n )}{' '}\n WAL\n </span>\n </div>\n </>\n ) : storageCostError ? (\n <div className={styles.costError}>\n <Info size={14} />\n <span>\n Unable to calculate cost. Please ensure you have\n sufficient WAL balance.\n </span>\n </div>\n ) : (\n <div className={styles.costError}>\n <Info size={14} />\n <span>Unable to calculate cost</span>\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n\n {/* Footer */}\n <div className={styles.footer}>\n <Button\n variant=\"outline\"\n onClick={handleClose}\n disabled={isExtending}\n >\n Cancel\n </Button>\n <Button\n onClick={handleExtend}\n disabled={\n isExtending ||\n !epochs ||\n !selectedDate ||\n !!dateError ||\n currentEpochsRemaining === 0\n }\n >\n {isExtending ? 'Extending...' : 'Extend Time'}\n </Button>\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n )\n}\n\nexport default ExtendTimeDialog\n","import { style } from '@vanilla-extract/css'\nimport { themeVars } from '~/theme.css'\n\nexport const content = style({\n minWidth: '20rem',\n maxWidth: '24rem',\n backgroundColor: themeVars.colors.background,\n borderRadius: themeVars.radius.lg,\n padding: themeVars.spacing.sm,\n boxShadow:\n '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',\n border: `1px solid ${themeVars.colors.border}`,\n zIndex: 50\n})\n\nexport const item = style({\n display: 'flex',\n alignItems: 'center',\n gap: themeVars.spacing.sm,\n padding: `${themeVars.spacing.sm} ${themeVars.spacing.md}`,\n fontSize: '0.875rem',\n borderRadius: themeVars.radius.sm,\n cursor: 'pointer',\n outline: 'none',\n userSelect: 'none',\n transition: 'all 0.15s ease-in-out',\n color: themeVars.colors.foreground,\n ':hover': {\n backgroundColor: themeVars.colors.accent,\n color: themeVars.colors.accentForeground\n },\n ':focus': {\n backgroundColor: themeVars.colors.accent,\n color: themeVars.colors.accentForeground\n },\n selectors: {\n '&[data-disabled]': {\n opacity: 0.5,\n cursor: 'not-allowed',\n pointerEvents: 'none'\n }\n }\n})\n\nexport const header = style({\n padding: `${themeVars.spacing.md} ${themeVars.spacing.md} ${themeVars.spacing.md}`\n})\n\nexport const title = style({\n fontWeight: 600,\n fontSize: '0.875rem',\n marginBottom: themeVars.spacing.xs,\n color: themeVars.colors.foreground\n})\n\nexport const description = style({\n fontSize: '0.75rem',\n lineHeight: 1.5,\n color: themeVars.colors.mutedForeground\n})\n\nexport const link = style({\n color: themeVars.colors.cyan,\n textDecoration: 'none',\n ':hover': { textDecoration: 'underline' }\n})\n\nexport const footer = style({\n padding: `${themeVars.spacing.sm} ${themeVars.spacing.sm}`\n})\n\nexport const buttonGroup = style({\n display: 'grid',\n gridTemplateColumns: '1fr 1fr',\n gap: themeVars.spacing.sm\n})\n\nexport const separator = style({\n height: '1px',\n backgroundColor: themeVars.colors.border,\n margin: `${themeVars.spacing.xs} 0`\n})\n","import {\n objectIdToWalrusSiteUrl,\n suinsDomainToWalrusSiteUrl\n} from '@cmdoss/walrus-site-builder'\nimport type { SuiClient } from '@mysten/sui/client'\nimport type { WalletAccount } from '@mysten/wallet-standard'\nimport { useStore } from '@nanostores/react'\nimport * as DropdownMenu from '@radix-ui/react-dropdown-menu'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { CalendarClock, ExternalLink, Globe2 } from 'lucide-react'\nimport type { FC, ReactNode } from 'react'\nimport { useSuiNsDomainsQuery } from '~/queries'\nimport {\n isDomainDialogOpen,\n isExtendTimeDialogOpen,\n siteMetadataStore\n} from '~/stores'\nimport { Banner } from '../ui'\nimport { button } from '../ui/Button.css'\nimport * as styles from './PublishMenu.css'\n\ninterface PublishMenuProps {\n children?: ReactNode\n siteId: string | undefined\n onPublishClick?: () => void\n onDomainClick?: () => void\n network?: 'mainnet' | 'testnet'\n /** Optional domain for the portal to view published site. */\n portalDomain?: string\n /** Whether to use HTTPS for the portal URL. */\n portalHttps?: boolean\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n }\n currentAccount: WalletAccount | null\n}\n\nconst PublishMenu: FC<PublishMenuProps> = ({\n children,\n siteId,\n onPublishClick,\n onDomainClick,\n portalDomain,\n portalHttps,\n network = 'testnet',\n clients,\n currentAccount\n}) => {\n const isDeployed = !!siteId\n const walrusSiteUrl = siteId\n ? objectIdToWalrusSiteUrl(siteId, portalDomain, portalHttps)\n : undefined\n\n const { data: nsDomains } = useSuiNsDomainsQuery(currentAccount, {\n suiClient: clients.suiClient,\n queryClient: clients.queryClient\n })\n\n const associatedDomains = nsDomains.filter(d => d.walrusSiteId === siteId)\n\n const suiNSUrlArray = useStore(siteMetadataStore.suiNSUrl)\n const suiNSUrl = suiNSUrlArray.length > 0 ? suiNSUrlArray[0].suins : undefined\n\n return (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger asChild>{children}</DropdownMenu.Trigger>\n <DropdownMenu.Portal>\n <DropdownMenu.Content className={styles.content}>\n {/* Header */}\n <div className={styles.header}>\n <h4 className={styles.title}>\n {isDeployed ? 'Update your Site' : 'Publish your Site'}\n </h4>\n {isDeployed && walrusSiteUrl ? (\n associatedDomains.length > 0 && suiNSUrl ? (\n <p className={styles.description}>\n Your site is live at{' '}\n <a\n href={suiNSUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={styles.link}\n >\n {suiNSUrl}\n </a>\n . You can update your site to reflect the latest changes.\n </p>\n ) : (\n <p className={styles.description}>\n Your site is live at{' '}\n <a\n href={\n network === 'testnet'\n ? `https://testnet.suivision.xyz/object/${siteId}`\n : `https://suivision.xyz/object/${siteId}`\n }\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={styles.link}\n >\n Explorer\n <ExternalLink\n style={{\n display: 'inline',\n width: '0.75rem',\n height: '0.75rem',\n marginLeft: '0.25rem'\n }}\n />\n </a>\n . You can link SuiNS domains to view your site in the portal.\n </p>\n )\n ) : (\n <p className={styles.description}>\n Deploy your app to{' '}\n <a\n href=\"https://www.walrus.xyz/\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={styles.link}\n >\n Walrus Sites\n </a>\n , a decentralized web hosting platform. After publishing, you\n can customize your domain and feature it in the community.\n </p>\n )}\n </div>\n\n <DropdownMenu.Separator className={styles.separator} />\n\n {/* Menu Items */}\n <DropdownMenu.Item\n className={styles.item}\n onSelect={onDomainClick}\n disabled={!siteId}\n >\n <Globe2 style={{ width: '1rem', height: '1rem' }} />\n <span style={{ flex: 1 }}>Customize Domain</span>\n {!siteId && (\n <span\n style={{\n fontSize: '0.75rem',\n color: 'var(--muted-foreground)'\n }}\n >\n Not Published Yet\n </span>\n )}\n </DropdownMenu.Item>\n\n <DropdownMenu.Item\n className={styles.item}\n onSelect={() => {\n isExtendTimeDialogOpen.set(true)\n }}\n disabled={!siteId}\n >\n <CalendarClock style={{ width: '1rem', height: '1rem' }} />\n <span style={{ flex: 1 }}>Extend Time</span>\n {!siteId && (\n <span\n style={{\n fontSize: '0.75rem',\n color: 'var(--muted-foreground)'\n }}\n >\n Not Published Yet\n </span>\n )}\n </DropdownMenu.Item>\n\n <DropdownMenu.Separator className={styles.separator} />\n\n {/* Footer */}\n <div className={styles.footer}>\n {isDeployed && walrusSiteUrl ? (\n <div className={styles.buttonGroup}>\n {suiNSUrl ? (\n <DropdownMenu.Item\n className={button({\n variant: 'outline',\n size: 'default'\n })}\n style={{ width: '100%' }}\n onSelect={() => {\n window.open(\n suinsDomainToWalrusSiteUrl(\n suiNSUrl,\n portalDomain,\n portalHttps\n ),\n '_blank',\n 'noopener,noreferrer'\n )\n }}\n >\n Visit Site\n </DropdownMenu.Item>\n ) : (\n <DropdownMenu.Item\n className={button({ variant: 'outline', size: 'default' })}\n style={{ width: '100%' }}\n onSelect={() => {\n isDomainDialogOpen.set(true)\n }}\n >\n Link SuiNS\n </DropdownMenu.Item>\n )}\n <DropdownMenu.Item\n className={button({ variant: 'gradient', size: 'default' })}\n onSelect={onPublishClick}\n >\n Update Site\n </DropdownMenu.Item>\n </div>\n ) : (\n <DropdownMenu.Item\n className={button({ variant: 'gradient', size: 'default' })}\n style={{ width: '100%' }}\n onSelect={onPublishClick}\n >\n Publish to Walrus\n </DropdownMenu.Item>\n )}\n\n {/* banner */}\n {network === 'testnet' && (\n <Banner\n title=\"You are publishing to the testnet\"\n description=\"You must run a local Walrus Site Portal to view published site.\"\n variant=\"info\"\n url=\"https://docs.wal.app/walrus-sites/portal.html\"\n urlName=\"Portal Documentation\"\n />\n )}\n </div>\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n )\n}\n\nexport default PublishMenu\n","import { keyframes, style } from '@vanilla-extract/css'\nimport { themeVars } from '~/theme.css'\n\nconst spin = keyframes({\n '0%': { transform: 'rotate(0deg)' },\n '100%': { transform: 'rotate(360deg)' }\n})\n\nexport const overlay = style({\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n position: 'fixed',\n inset: 0,\n zIndex: 50,\n animation: 'fadeIn 150ms ease-in-out'\n})\n\nexport const content = style({\n backgroundColor: themeVars.colors.background,\n borderRadius: themeVars.radius.lg,\n boxShadow:\n '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n width: '90vw',\n maxWidth: '56rem',\n maxHeight: '85vh',\n overflow: 'auto',\n zIndex: 51,\n animation: 'slideIn 200ms ease-in-out',\n border: `1px solid ${themeVars.colors.border}`,\n padding: themeVars.spacing.md\n})\n\nexport const title = style({\n fontSize: '1.125rem',\n fontWeight: 600,\n color: themeVars.colors.foreground,\n marginBottom: themeVars.spacing.xs\n})\n\nexport const description = style({\n fontSize: '0.875rem',\n color: themeVars.colors.mutedForeground\n})\n\nexport const body = style({\n paddingTop: themeVars.spacing.md,\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.sm\n})\n\nexport const section = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.xs,\n marginTop: themeVars.spacing.md\n})\n\nexport const twoColumnSection = style({\n display: 'grid',\n gridTemplateColumns: '1fr 1.5fr',\n gap: themeVars.spacing.lg,\n marginTop: themeVars.spacing.md,\n '@media': {\n '(max-width: 768px)': {\n gridTemplateColumns: '1fr',\n gap: themeVars.spacing.md\n }\n }\n})\n\nexport const leftColumn = style({\n display: 'flex',\n flexDirection: 'column'\n})\n\nexport const rightColumn = style({\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'flex-start'\n})\n\nexport const metadataFields = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.sm\n})\n\nexport const fieldDisplay = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.xs\n})\n\nexport const fieldValue = style({\n fontSize: '0.875rem',\n color: themeVars.colors.foreground,\n padding: themeVars.spacing.sm,\n backgroundColor: 'rgba(var(--muted-rgb), 0.3)',\n borderRadius: themeVars.radius.md,\n border: `1px solid ${themeVars.colors.border}`,\n minHeight: '2.5rem',\n display: 'flex',\n alignItems: 'center',\n wordBreak: 'break-word'\n})\n\nexport const sectionTitle = style({\n fontSize: '0.875rem',\n fontWeight: 600,\n paddingTop: themeVars.spacing.md,\n paddingBottom: themeVars.spacing.sm\n})\n\nexport const buttonGroup = style({\n display: 'flex',\n gap: themeVars.spacing.sm,\n paddingTop: themeVars.spacing.sm\n})\n\nexport const warningText = style({\n fontSize: '0.75rem',\n borderRadius: themeVars.radius.md,\n backgroundColor: themeVars.colors.muted,\n color: themeVars.colors.accentForeground,\n padding: themeVars.spacing.sm,\n marginTop: themeVars.spacing.sm\n})\n\nexport const previewContainer = style({\n position: 'relative'\n})\n\nexport const previewArea = style({\n border: `2px solid ${themeVars.colors.border}`,\n borderRadius: themeVars.radius.lg,\n backgroundColor: 'rgba(var(--muted-rgb), 0.3)',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n aspectRatio: '1 / 1',\n width: '100%',\n position: 'relative',\n overflow: 'hidden'\n})\n\nexport const flickeringGrid = style({\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 0\n})\n\nexport const maskLayer = style({\n position: 'absolute',\n inset: 0,\n zIndex: 1,\n background: `radial-gradient(ellipse 40% 80% at center, ${themeVars.colors.background} 50%, transparent 100%)`,\n opacity: 0.8,\n pointerEvents: 'none'\n})\n\nexport const placeholderContent = style({\n position: 'absolute',\n zIndex: 2,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: themeVars.spacing.sm\n})\n\nexport const previewImageWrapper = style({\n width: '100%',\n height: '100%',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center'\n})\n\nexport const previewImage = style({\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n borderRadius: themeVars.radius.lg\n})\n\nexport const placeholderIcon = style({\n width: '64px',\n height: '64px',\n borderRadius: themeVars.radius.lg,\n border: `2px dashed ${themeVars.colors.border}`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n position: 'relative',\n zIndex: 1,\n marginBottom: themeVars.spacing.sm,\n color: themeVars.colors.mutedForeground\n})\n\nexport const editButton = style({\n position: 'absolute',\n top: themeVars.spacing.sm,\n right: themeVars.spacing.sm,\n padding: themeVars.spacing.sm,\n backgroundColor: themeVars.colors.background,\n border: `1px solid ${themeVars.colors.border}`,\n borderRadius: themeVars.radius.lg,\n cursor: 'pointer',\n transition: 'background-color 0.2s',\n ':hover': {\n backgroundColor: themeVars.colors.muted\n }\n})\n\nexport const metadataText = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.xs\n})\n\nexport const dialogOverlay = style({\n position: 'fixed',\n inset: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n zIndex: 60\n})\n\nexport const dialogContent = style({\n position: 'fixed',\n left: '50%',\n top: '50%',\n transform: 'translate(-50%, -50%)',\n width: '30vw',\n minWidth: '300px',\n maxWidth: '500px',\n maxHeight: '90vh',\n overflowY: 'auto',\n backgroundColor: themeVars.colors.background,\n border: `1px solid ${themeVars.colors.border}`,\n borderRadius: themeVars.radius.lg,\n boxShadow: '0 20px 25px -5px rgba(0, 0, 0, 0.1)',\n zIndex: 70\n})\n\nexport const dialogHeader = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: themeVars.spacing.md,\n borderBottom: `1px solid ${themeVars.colors.border}`,\n position: 'sticky',\n top: 0,\n backgroundColor: themeVars.colors.background,\n zIndex: 10\n})\n\nexport const dialogBody = style({\n padding: themeVars.spacing.md,\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.md\n})\n\nexport const dialogBodyTwoColumn = style({\n padding: themeVars.spacing.md,\n display: 'grid',\n gridTemplateColumns: '1fr',\n gap: themeVars.spacing.lg,\n '@media': {\n '(max-width: 768px)': {\n gridTemplateColumns: '1fr',\n gap: themeVars.spacing.md\n }\n }\n})\n\nexport const dialogRightColumn = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.md\n})\n\nexport const dialogFooter = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: themeVars.spacing.md,\n borderTop: `1px solid ${themeVars.colors.border}`,\n backgroundColor: 'rgba(var(--muted-rgb), 0.3)',\n position: 'sticky',\n bottom: 0\n})\n\nexport const uploadArea = style({\n border: `2px dashed ${themeVars.colors.border}`,\n borderRadius: themeVars.radius.lg,\n padding: themeVars.spacing.lg,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n transition: 'background-color 0.2s',\n ':hover': {\n backgroundColor: 'rgba(var(--muted-rgb), 0.5)'\n }\n})\n\nexport const uploadAreaSquare = style({\n border: `2px dashed ${themeVars.colors.border}`,\n borderRadius: themeVars.radius.lg,\n aspectRatio: '1 / 1',\n width: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n transition: 'background-color 0.2s',\n overflow: 'hidden',\n position: 'relative',\n ':hover': {\n backgroundColor: 'rgba(var(--muted-rgb), 0.5)'\n }\n})\n\nexport const uploadPlaceholder = style({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n padding: themeVars.spacing.lg\n})\n\nexport const fieldLabel = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: themeVars.spacing.xs\n})\n\nexport const charCount = style({\n fontSize: '0.75rem',\n color: themeVars.colors.mutedForeground\n})\n\nexport const collapsibleTrigger = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n padding: themeVars.spacing.sm,\n fontSize: '0.875rem',\n fontWeight: 500,\n color: themeVars.colors.foreground,\n backgroundColor: themeVars.colors.muted,\n border: `1px solid ${themeVars.colors.border}`,\n borderRadius: themeVars.radius.md,\n cursor: 'pointer',\n transition: 'background-color 0.2s',\n ':hover': {\n backgroundColor: 'rgba(var(--muted-rgb), 0.8)'\n }\n})\n\nexport const collapsibleIcon = style({\n transition: 'transform 0.2s ease-in-out'\n})\n\nexport const collapsibleIconExpanded = style({\n transform: 'rotate(180deg)'\n})\n\nexport const collapsibleContent = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.xs,\n marginTop: themeVars.spacing.xs,\n overflow: 'hidden',\n transition: 'all 0.2s ease-in-out',\n padding: themeVars.spacing.sm\n})\n\nexport const collapsibleContentHidden = style({\n maxHeight: 0,\n opacity: 0,\n marginTop: 0\n})\n\nexport const collapsibleContentVisible = style({\n maxHeight: '500px',\n opacity: 1\n})\n\nexport const storageCostSection = style({\n padding: themeVars.spacing.sm,\n backgroundColor: themeVars.colors.muted,\n borderRadius: themeVars.radius.md\n})\n\nexport const storageCostSummary = style({\n display: 'flex',\n flexDirection: 'column'\n})\n\nexport const storageCostLabel = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n fontSize: '0.875rem',\n color: themeVars.colors.foreground\n})\n\nexport const storageCostValue = style({\n display: 'flex',\n alignItems: 'center',\n gap: '0.25rem',\n fontSize: '0.875rem'\n})\n\nexport const storageDetailsGrid = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.sm,\n marginTop: themeVars.spacing.sm\n})\n\nexport const storageDetailsBox = style({\n padding: themeVars.spacing.xs,\n backgroundColor: themeVars.colors.muted,\n borderRadius: themeVars.radius.md\n})\n\nexport const spinner = style({\n animation: `${spin} 1s linear infinite`\n})\n","import type { IAsset } from '@cmdoss/walrus-site-builder'\nimport type { WalrusClient } from '@mysten/walrus'\nimport { useStore } from '@nanostores/react'\nimport * as Dialog from '@radix-ui/react-dialog'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { CalendarClock, Info, Loader2, Pencil, Upload, X } from 'lucide-react'\nimport type { FC } from 'react'\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { useEpochDuration } from '~/hooks'\nimport { useStorageCostQuery } from '~/queries/storage-cost.query'\nimport { siteMetadataStore } from '~/stores/site-metadata.store'\nimport { sitePublishingStore } from '~/stores/site-publishing.store'\nimport { Banner } from '../ui'\nimport { Button } from '../ui/Button'\nimport { FlickeringGrid } from '../ui/FlickeringGrid'\nimport { Input, Label, Textarea } from '../ui/Input'\nimport { Stepper } from '../ui/Stepper'\nimport * as styles from './PublishModal.css'\n\ninterface PublishModalProps {\n siteId: string | undefined\n assets: IAsset[]\n onDeploy?: () => void\n onSaveMetadata?: () => Promise<void>\n onExtendBlobs?: (extendEpochs: number) => Promise<void>\n clients: {\n queryClient: QueryClient\n walrusClient: WalrusClient\n }\n}\n\nconst PublishModal: FC<PublishModalProps> = ({\n siteId,\n assets,\n onDeploy,\n onSaveMetadata,\n onExtendBlobs,\n clients: { queryClient, walrusClient }\n}) => {\n const [isMetadataDialogOpen, setIsMetadataDialogOpen] = useState(false)\n const [isStorageDetailsExpanded, setIsStorageDetailsExpanded] =\n useState(false)\n const [isExtending, setIsExtending] = useState(false)\n const [previousEpochs, setPreviousEpochs] = useState<number>(0)\n const [pendingEpochs, setPendingEpochs] = useState<number>(0)\n\n const isOpen = useStore(sitePublishingStore.isPublishDialogOpen)\n const isWorking = useStore(sitePublishingStore.isWorking)\n const deployStatusText = useStore(sitePublishingStore.deployStatusText)\n const deployStepIndex = useStore(sitePublishingStore.deploymentStepIndex)\n const imageDisplayUrl = useStore(siteMetadataStore.imageDisplayUrl)\n const projectUrl = useStore(siteMetadataStore.projectUrl)\n const epochs = useStore(siteMetadataStore.epochs)\n const isDirty = useStore(siteMetadataStore.isDirty)\n const isLoading = useStore(siteMetadataStore.loading)\n const title = useStore(siteMetadataStore.title)\n const description = useStore(siteMetadataStore.description)\n\n const { epochDurationMs, getExpirationDate } = useEpochDuration(walrusClient)\n\n // Track initial epochs value when editing a site\n useEffect(() => {\n if (siteId && epochs && previousEpochs === 0) {\n setPreviousEpochs(epochs)\n }\n }, [siteId, epochs, previousEpochs])\n\n // Calculate assets size\n const assetsSize = useMemo(\n () => assets.reduce((sum, a) => sum + a.content.byteLength, 0),\n [assets]\n )\n\n // Calculate min and max dates for date picker\n const minDate = useMemo(() => {\n if (!epochDurationMs) return ''\n const now = Date.now()\n const minEpochs = 5\n const minDateTime = now + minEpochs * epochDurationMs\n return new Date(minDateTime).toISOString().slice(0, 10)\n }, [epochDurationMs])\n\n const maxDate = useMemo(() => {\n if (!epochDurationMs) return ''\n const now = Date.now()\n const maxEpochs = 30\n const maxDateTime = now + maxEpochs * epochDurationMs\n return new Date(maxDateTime).toISOString().slice(0, 10)\n }, [epochDurationMs])\n\n // Calculate epochs from selected date\n const calculateEpochsFromDate = (selectedDate: string) => {\n if (!epochDurationMs || !selectedDate) return 5\n\n const now = Date.now()\n const targetTime = new Date(selectedDate).getTime()\n const diffMs = targetTime - now\n\n if (diffMs <= 0) return 5\n\n // Calculate epochs and round up\n const exactEpochs = diffMs / epochDurationMs\n const roundedEpochs = Math.ceil(exactEpochs)\n\n // Clamp between 5 and 30\n return Math.max(5, Math.min(30, roundedEpochs))\n }\n\n // Handle date change\n const handleDateChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const selectedDate = e.target.value\n if (!selectedDate) return\n\n const calculatedEpochs = calculateEpochsFromDate(selectedDate)\n\n // If editing existing site, store pending epochs for later processing\n if (siteId && previousEpochs > 0) {\n setPendingEpochs(calculatedEpochs)\n }\n\n siteMetadataStore.epochs.set(calculatedEpochs)\n }\n\n // Handle save metadata with automatic extend if needed\n const handleSaveMetadataWithExtend = async () => {\n if (!onSaveMetadata) return\n\n // First, save metadata\n await onSaveMetadata()\n\n // Then, if there's a pending extension, extend blobs\n if (\n siteId &&\n onExtendBlobs &&\n previousEpochs > 0 &&\n pendingEpochs > previousEpochs\n ) {\n const extensionEpochs = pendingEpochs - previousEpochs\n\n if (extensionEpochs > 0) {\n setIsExtending(true)\n try {\n await onExtendBlobs(extensionEpochs)\n // Update the previous epochs baseline after successful extension\n setPreviousEpochs(pendingEpochs)\n setPendingEpochs(0)\n } catch (error) {\n console.error('Failed to extend blobs:', error)\n } finally {\n setIsExtending(false)\n }\n }\n }\n }\n\n // Get current selected date from epochs\n const selectedDate = useMemo(() => {\n if (!epochDurationMs || !epochs) return ''\n const now = Date.now()\n const targetTime = now + epochs * epochDurationMs\n return new Date(targetTime).toISOString().slice(0, 10)\n }, [epochs, epochDurationMs])\n\n const {\n data: storageCost = {\n storageCost: '0',\n writeCost: '0',\n totalCost: '0'\n },\n isLoading: storageCostLoading,\n isError: storageCostError\n } = useStorageCostQuery(assetsSize, epochs, { walrusClient, queryClient })\n\n const deploymentSteps = [\n {\n title: 'Prepare',\n description: 'Build and register blobs for deployment'\n },\n { title: 'Upload', description: 'Upload assets to Walrus network' },\n { title: 'Certify', description: 'Certify the uploaded assets' },\n { title: 'Deploy', description: 'Deploy and update the site' }\n ]\n\n // Calculate expiration date using the hook\n const expirationDate = getExpirationDate(epochs)\n\n return (\n <Dialog.Root\n open={isOpen}\n onOpenChange={sitePublishingStore.closePublishDialog}\n >\n <Dialog.Portal>\n <Dialog.Overlay className={styles.overlay} />\n <Dialog.Content className={styles.content}>\n <Dialog.Title className={styles.title}>\n {siteId ? 'Edit Site' : 'Publish New Site'}\n </Dialog.Title>\n <Dialog.Description className={styles.description}>\n Make your project live in the Walrus network.\n </Dialog.Description>\n\n <Stepper\n steps={deploymentSteps}\n currentStep={deployStepIndex}\n isLoading={isWorking}\n />\n\n {/* Website Info Section - Two Column Layout */}\n <section className={styles.twoColumnSection}>\n {/* Left Column: Preview Image */}\n <div className={styles.leftColumn}>\n <div className={styles.previewContainer}>\n <div className={styles.previewArea}>\n {imageDisplayUrl ? (\n <div className={styles.previewImageWrapper}>\n <img\n src={imageDisplayUrl}\n alt=\"Site preview\"\n className={styles.previewImage}\n />\n {/* Gradient Overlay */}\n <div\n style={{\n position: 'absolute',\n inset: 0,\n background:\n 'linear-gradient(to bottom, transparent 0%, transparent 50%, rgba(0, 0, 0, 0.7) 100%)',\n pointerEvents: 'none'\n }}\n />\n {/* Title and Description Overlay */}\n {(title || description) && (\n <div\n style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n padding: '1rem',\n color: 'white',\n pointerEvents: 'none'\n }}\n >\n {title && (\n <h3\n style={{\n fontSize: '0.875rem',\n fontWeight: 600,\n marginBottom: '0.25rem',\n lineHeight: 1.3,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical'\n }}\n >\n {title}\n </h3>\n )}\n {description && (\n <p\n style={{\n fontSize: '0.75rem',\n opacity: 0.9,\n lineHeight: 1.4,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical'\n }}\n >\n {description}\n </p>\n )}\n </div>\n )}\n </div>\n ) : (\n <>\n <FlickeringGrid\n className={styles.flickeringGrid}\n squareSize={2}\n gridGap={6}\n color=\"rgb(0, 0, 0)\"\n maxOpacity={0.3}\n flickerChance={0.3}\n />\n <div className={styles.maskLayer} />\n <div className={styles.placeholderContent}>\n <div className={styles.placeholderIcon}>\n <svg\n width=\"32\"\n height=\"32\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <title>Image placeholder icon</title>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n </div>\n <p\n style={{\n fontWeight: 500,\n color: 'var(--foreground)',\n textAlign: 'center'\n }}\n >\n Add a preview image\n </p>\n <p\n style={{\n color: 'var(--muted-foreground)',\n textAlign: 'center',\n fontSize: '0.875rem'\n }}\n >\n Click the edit button to customize\n </p>\n </div>\n </>\n )}\n </div>\n <button\n type=\"button\"\n className={styles.editButton}\n onClick={() => setIsMetadataDialogOpen(true)}\n >\n <Pencil size={20} />\n </button>\n </div>\n {/* Storage Cost Section */}\n <div\n className={styles.storageCostSection}\n style={{ marginTop: '0.5rem' }}\n >\n <div className={styles.storageCostSummary}>\n <div className={styles.storageCostLabel}>\n <span style={{ fontWeight: 500 }}>Storage Cost</span>\n {assetsSize !== null && (\n <button\n type=\"button\"\n onClick={() =>\n setIsStorageDetailsExpanded(!isStorageDetailsExpanded)\n }\n style={{\n padding: '0.25rem',\n cursor: 'pointer',\n border: 'none',\n background: 'transparent',\n color: 'var(--muted-foreground)',\n borderRadius: '0.25rem',\n transition: 'background-color 0.2s'\n }}\n onMouseEnter={e => {\n e.currentTarget.style.backgroundColor = 'var(--muted)'\n }}\n onMouseLeave={e => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n aria-label=\"View storage cost details\"\n >\n <Info size={16} />\n </button>\n )}\n </div>\n <div className={styles.storageCostValue}>\n {assetsSize === null ? (\n <span\n style={{\n color: 'var(--warning, #f59e0b)',\n display: 'flex',\n alignItems: 'center',\n gap: '0.375rem'\n }}\n >\n <Info size={14} />\n Assets not prepared yet\n </span>\n ) : storageCostLoading ? (\n <span style={{ color: 'var(--muted-foreground)' }}>\n Calculating...\n </span>\n ) : storageCostError ? (\n <span style={{ color: 'var(--destructive)' }}>\n Cost unavailable\n </span>\n ) : (\n <>\n <span\n style={{\n fontSize: '0.875rem',\n color: 'var(--muted-foreground)'\n }}\n >\n {(assetsSize / 1024).toFixed(2)} KB •{' '}\n </span>\n <span\n style={{\n fontWeight: 600,\n color: 'var(--foreground)'\n }}\n >\n {(\n (Number(storageCost.storageCost) +\n Number(storageCost.writeCost)) /\n 1_000_000_000\n ).toFixed(9)}{' '}\n WAL\n </span>\n </>\n )}\n </div>\n </div>\n\n {/* Storage Details Collapsible */}\n {isStorageDetailsExpanded && (\n <div className={styles.storageDetailsBox}>\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '0.2rem'\n }}\n >\n <div style={{ fontSize: '0.875rem' }}>\n <span style={{ fontWeight: 500 }}>Storage Cost:</span>{' '}\n <span style={{ color: '#10b981' }}>\n {(\n Number(storageCost.storageCost) / 1_000_000_000\n ).toFixed(9)}{' '}\n WAL\n </span>\n </div>\n <div style={{ fontSize: '0.875rem' }}>\n <span style={{ fontWeight: 500 }}>Write Cost:</span>{' '}\n <span style={{ color: '#f97316' }}>\n {(\n Number(storageCost.writeCost) / 1_000_000_000\n ).toFixed(9)}{' '}\n WAL\n </span>\n </div>\n <div\n style={{\n fontSize: '0.875rem',\n borderTop: '1px solid var(--border)',\n paddingTop: '0.1rem',\n marginTop: '0.1rem'\n }}\n >\n <span style={{ fontWeight: 500 }}>Total Cost:</span>{' '}\n <span style={{ color: '#3b82f6', fontWeight: 600 }}>\n {(\n (Number(storageCost.storageCost) +\n Number(storageCost.writeCost)) /\n 1_000_000_000\n ).toFixed(9)}{' '}\n WAL\n </span>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Right Column: Metadata Information */}\n <div className={styles.rightColumn}>\n <div className={styles.metadataFields}>\n {/* Right Column: Text Fields */}\n <div className={styles.dialogRightColumn}>\n {/* Title Section */}\n <fieldset>\n <div className={styles.fieldLabel}>\n <Label>Title</Label>\n <span className={styles.charCount}>\n {siteMetadataStore.title.get().length}/120\n </span>\n </div>\n <Input\n value={siteMetadataStore.title.get()}\n onChange={e =>\n siteMetadataStore.title.set(\n e.target.value.slice(0, 120)\n )\n }\n placeholder=\"Add a title...\"\n />\n </fieldset>\n\n {/* Description Section */}\n <fieldset>\n <div className={styles.fieldLabel}>\n <Label>Description</Label>\n <span className={styles.charCount}>\n {siteMetadataStore.description.get().length}/150\n </span>\n </div>\n <Textarea\n value={siteMetadataStore.description.get()}\n onChange={e =>\n siteMetadataStore.description.set(\n e.target.value.slice(0, 150)\n )\n }\n placeholder=\"Add a description...\"\n rows={4}\n />\n </fieldset>\n\n {/* Project URL */}\n <fieldset>\n <Label>\n Project URL\n <span\n style={{\n fontSize: '0.75rem',\n color: 'var(--muted-foreground)'\n }}\n >\n (Optional)\n </span>\n </Label>\n <Input\n value={projectUrl}\n onChange={e =>\n siteMetadataStore.projectUrl.set(e.target.value)\n }\n placeholder=\"https://github.com/username/project\"\n />\n </fieldset>\n\n {/* Storage Duration Section - Only show for new sites */}\n {!siteId && (\n <fieldset>\n <div className={styles.fieldLabel}>\n <Label>Storage Duration</Label>\n {epochs > 0 && (\n <span\n style={{\n fontSize: '0.75rem',\n color: 'var(--muted-foreground)',\n display: 'flex',\n alignItems: 'center',\n gap: '0.25rem'\n }}\n >\n <span\n style={{\n fontWeight: 600,\n color: 'var(--foreground)'\n }}\n >\n {epochs}\n </span>\n epochs\n </span>\n )}\n </div>\n\n {/* Date Picker */}\n <div style={{ position: 'relative' }}>\n <Input\n type=\"date\"\n value={selectedDate}\n min={minDate}\n max={maxDate}\n onChange={handleDateChange}\n disabled={isWorking}\n style={{\n paddingLeft: '2.5rem',\n cursor: isWorking ? 'wait' : 'pointer'\n }}\n />\n <CalendarClock\n size={18}\n style={{\n position: 'absolute',\n left: '0.75rem',\n top: '50%',\n transform: 'translateY(-50%)',\n color: 'var(--muted-foreground)',\n pointerEvents: 'none'\n }}\n />\n </div>\n\n {/* Compact Info */}\n {expirationDate && epochDurationMs && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem',\n fontSize: '0.75rem',\n color: 'var(--muted-foreground)',\n marginTop: '0.5rem'\n }}\n >\n <Info size={14} style={{ flexShrink: 0 }} />\n <span>\n 1 epoch ≈{' '}\n {(epochDurationMs / (1000 * 60 * 60 * 24)).toFixed(\n 1\n )}{' '}\n days\n {' • '}\n Duration rounded up. Can be extended later.\n </span>\n </div>\n )}\n </fieldset>\n )}\n </div>\n </div>\n </div>\n </section>\n\n {isDirty ? (\n <section className={styles.section}>\n <div className={styles.buttonGroup}>\n <Button\n variant=\"outline\"\n style={{ flex: 1 }}\n onClick={siteMetadataStore.cancelEdit}\n disabled={isLoading}\n >\n Cancel\n </Button>\n <Button\n style={{\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '0.5rem'\n }}\n onClick={handleSaveMetadataWithExtend}\n disabled={isLoading || isExtending}\n >\n {isLoading || isExtending ? (\n <>\n <Loader2 size={16} className={styles.spinner} />\n {isExtending ? 'Extending Storage...' : 'Saving...'}\n </>\n ) : (\n 'Save'\n )}\n </Button>\n </div>\n </section>\n ) : (\n <section className={styles.section}>\n <div className={styles.buttonGroup}>\n <Button\n variant=\"gradient\"\n style={{\n width: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '0.5rem'\n }}\n onClick={onDeploy}\n disabled={isWorking}\n >\n {isWorking && (\n <Loader2 size={16} className={styles.spinner} />\n )}\n {deployStatusText}\n </Button>\n </div>\n <Banner\n title=\"Warning\"\n description=\"Please don't close the website\n until the deployment is complete.\"\n variant=\"warning\"\n />\n </section>\n )}\n </Dialog.Content>\n </Dialog.Portal>\n\n {/* Metadata Edit Dialog */}\n <MetadataEditDialog\n isOpen={isMetadataDialogOpen}\n onClose={() => setIsMetadataDialogOpen(false)}\n />\n </Dialog.Root>\n )\n}\n\ninterface MetadataEditDialogProps {\n isOpen: boolean\n onClose: () => void\n onImageChange?: (file: File) => void\n}\n\nfunction MetadataEditDialog({ isOpen, onClose }: MetadataEditDialogProps) {\n const imageDisplayUrl = useStore(siteMetadataStore.imageDisplayUrl)\n const isDirty = useStore(siteMetadataStore.isDirty)\n const isLoading = useStore(siteMetadataStore.loading)\n\n const [uploadMode, setUploadMode] = useState<'file' | 'url'>('file')\n const [imageUrl, setImageUrl] = useState('')\n const [urlError, setUrlError] = useState('')\n const [fileSizeError, setFileSizeError] = useState('')\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n const MAX_FILE_SIZE = 5 * 1024 * 1024 // 5MB in bytes\n\n const handleImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file) return\n\n // Check file size\n if (file.size > MAX_FILE_SIZE) {\n setFileSizeError(\n `File size exceeds 5MB limit (${(file.size / 1024 / 1024).toFixed(2)}MB)`\n )\n e.target.value = '' // Reset input\n return\n }\n\n setFileSizeError('')\n siteMetadataStore.imageUrl.set(file)\n }\n\n const handleUrlSubmit = () => {\n if (!imageUrl.trim()) {\n setUrlError('Please enter a valid URL')\n return\n }\n\n try {\n new URL(imageUrl)\n siteMetadataStore.imageUrl.set(imageUrl)\n setImageUrl('')\n setUrlError('')\n setUploadMode('file')\n } catch {\n setUrlError('Please enter a valid URL')\n }\n }\n\n const handleCancel = () => {\n siteMetadataStore.cancelEdit()\n setUploadMode('file')\n setImageUrl('')\n setUrlError('')\n setFileSizeError('')\n onClose()\n }\n\n return (\n <Dialog.Root open={isOpen} onOpenChange={onClose}>\n <Dialog.Portal>\n <Dialog.Overlay className={styles.dialogOverlay} />\n <Dialog.Content className={styles.dialogContent}>\n {/* Header */}\n <div className={styles.dialogHeader}>\n <Dialog.Title\n style={{\n fontSize: '1.125rem',\n fontWeight: 600,\n color: 'var(--foreground)'\n }}\n >\n Edit Site Image\n </Dialog.Title>\n <Dialog.Close asChild>\n <button\n type=\"button\"\n style={{\n padding: '0.25rem',\n cursor: 'pointer',\n border: 'none',\n background: 'transparent',\n color: 'var(--foreground)',\n borderRadius: '0.5rem',\n transition: 'background-color 0.2s'\n }}\n onMouseEnter={e => {\n e.currentTarget.style.backgroundColor = 'var(--muted)'\n }}\n onMouseLeave={e => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n <X size={20} />\n </button>\n </Dialog.Close>\n </div>\n\n {/* Content */}\n <div className={styles.dialogBodyTwoColumn}>\n {/* Left Column: Image Section */}\n <div>\n <div className={styles.fieldLabel}>\n <Label>Preview Image</Label>\n <span\n style={{\n fontSize: '0.75rem',\n color: 'var(--muted-foreground)'\n }}\n >\n Max 5MB\n </span>\n </div>\n\n {/* Upload Mode Toggle */}\n <div\n style={{\n display: 'flex',\n gap: '0.5rem',\n marginBottom: '1rem',\n padding: '0.25rem',\n backgroundColor: 'var(--muted)',\n borderRadius: '0.5rem'\n }}\n >\n <button\n type=\"button\"\n onClick={() => {\n setUploadMode('file')\n setUrlError('')\n }}\n style={{\n flex: 1,\n padding: '0.5rem 1rem',\n fontSize: '0.875rem',\n fontWeight: 500,\n border: 'none',\n borderRadius: '0.375rem',\n cursor: 'pointer',\n transition: 'all 0.2s',\n backgroundColor:\n uploadMode === 'file'\n ? 'var(--background)'\n : 'transparent',\n color:\n uploadMode === 'file'\n ? 'var(--foreground)'\n : 'var(--muted-foreground)',\n boxShadow:\n uploadMode === 'file'\n ? '0 1px 3px rgba(0, 0, 0, 0.1)'\n : 'none'\n }}\n >\n Upload File\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setUploadMode('url')\n setFileSizeError('')\n }}\n style={{\n flex: 1,\n padding: '0.5rem 1rem',\n fontSize: '0.875rem',\n fontWeight: 500,\n border: 'none',\n borderRadius: '0.375rem',\n cursor: 'pointer',\n transition: 'all 0.2s',\n backgroundColor:\n uploadMode === 'url'\n ? 'var(--background)'\n : 'transparent',\n color:\n uploadMode === 'url'\n ? 'var(--foreground)'\n : 'var(--muted-foreground)',\n boxShadow:\n uploadMode === 'url'\n ? '0 1px 3px rgba(0, 0, 0, 0.1)'\n : 'none'\n }}\n >\n From URL\n </button>\n </div>\n\n {uploadMode === 'file' ? (\n <>\n <div\n className={styles.uploadAreaSquare}\n onClick={() => !isLoading && fileInputRef.current?.click()}\n style={{\n cursor: isLoading ? 'wait' : 'pointer',\n opacity: isLoading ? 0.6 : 1\n }}\n >\n {isLoading ? (\n <div className={styles.uploadPlaceholder}>\n <div\n style={{\n width: '32px',\n height: '32px',\n border: '3px solid var(--muted)',\n borderTop: '3px solid var(--foreground)',\n borderRadius: '50%',\n animation: 'spin 1s linear infinite',\n marginBottom: '0.75rem'\n }}\n />\n <p\n style={{\n fontWeight: 500,\n color: 'var(--foreground)',\n textAlign: 'center'\n }}\n >\n Uploading...\n </p>\n </div>\n ) : imageDisplayUrl ? (\n <img\n src={imageDisplayUrl}\n alt=\"Preview\"\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n borderRadius: '0.5rem'\n }}\n />\n ) : (\n <div className={styles.uploadPlaceholder}>\n <Upload\n size={32}\n style={{\n marginBottom: '0.75rem',\n color: 'var(--muted-foreground)'\n }}\n />\n <p\n style={{\n fontWeight: 500,\n color: 'var(--foreground)',\n textAlign: 'center'\n }}\n >\n Click to upload\n </p>\n <p\n style={{\n fontSize: '0.875rem',\n color: 'var(--muted-foreground)',\n textAlign: 'center',\n marginTop: '0.25rem'\n }}\n >\n Square image recommended\n </p>\n </div>\n )}\n </div>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleImageChange}\n style={{ display: 'none' }}\n />\n {fileSizeError && (\n <p\n style={{\n fontSize: '0.75rem',\n color: 'var(--destructive)',\n marginTop: '0.5rem',\n display: 'flex',\n alignItems: 'center',\n gap: '0.25rem'\n }}\n >\n <Info size={14} />\n {fileSizeError}\n </p>\n )}\n </>\n ) : (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '1rem'\n }}\n >\n {imageDisplayUrl && (\n <div\n style={{\n width: '100%',\n aspectRatio: '1',\n borderRadius: '0.5rem',\n overflow: 'hidden',\n border: '1px solid var(--border)'\n }}\n >\n <img\n src={imageDisplayUrl}\n alt=\"Preview\"\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover'\n }}\n />\n </div>\n )}\n <div>\n <Label>Image URL</Label>\n <div\n style={{\n display: 'flex',\n gap: '0.5rem',\n marginTop: '0.5rem'\n }}\n >\n <Input\n value={imageUrl}\n onChange={e => {\n setImageUrl(e.target.value)\n setUrlError('')\n }}\n onKeyDown={e => {\n if (e.key === 'Enter') {\n handleUrlSubmit()\n }\n }}\n placeholder=\"https://example.com/image.png\"\n style={{ flex: 1 }}\n />\n <Button\n onClick={handleUrlSubmit}\n style={{ flexShrink: 0 }}\n >\n Apply\n </Button>\n </div>\n {urlError && (\n <p\n style={{\n fontSize: '0.75rem',\n color: 'var(--destructive)',\n marginTop: '0.5rem',\n display: 'flex',\n alignItems: 'center',\n gap: '0.25rem'\n }}\n >\n <Info size={14} />\n {urlError}\n </p>\n )}\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Footer */}\n <div className={styles.dialogFooter}>\n <button\n type=\"button\"\n onClick={() => {\n siteMetadataStore.imageUrl.set(\n 'https://www.walrus.xyz/walrus-site'\n )\n onClose()\n }}\n style={{\n fontSize: '0.875rem',\n fontWeight: 500,\n color: 'var(--muted-foreground)',\n cursor: 'pointer',\n border: 'none',\n background: 'transparent',\n transition: 'color 0.2s'\n }}\n onMouseEnter={e => {\n e.currentTarget.style.color = 'var(--foreground)'\n }}\n onMouseLeave={e => {\n e.currentTarget.style.color = 'var(--muted-foreground)'\n }}\n >\n Reset to default\n </button>\n <div style={{ display: 'flex', gap: '0.75rem' }}>\n <Button onClick={handleCancel} variant=\"outline\">\n Close\n </Button>\n <Dialog.Close asChild>\n <Button disabled={!isDirty || isLoading}>\n {isLoading ? 'Saving...' : 'Save Changes'}\n </Button>\n </Dialog.Close>\n </div>\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n )\n}\n\nexport default PublishModal\n","'use client'\n\nimport type { FC } from 'react'\n\ntype DomainCardSvgProps = {\n className?: string\n}\n\n// Sub-component: Background with decorative patterns\nconst CardBackground: FC = () => {\n return (\n <>\n <g clipPath=\"url(#clip0_2_8065)\">\n <rect width=\"440\" height=\"440\" rx=\"24.6939\" fill=\"#221C36\" />\n <g clipPath=\"url(#clip1_2_8065)\">\n <g style={{ mixBlendMode: 'plus-lighter' }}>\n <mask\n id=\"mask0_2_8065\"\n style={{ maskType: 'alpha' }}\n maskUnits=\"userSpaceOnUse\"\n x=\"-371\"\n y=\"-402\"\n width=\"1183\"\n height=\"685\"\n >\n <rect\n x=\"-370.026\"\n y=\"-401.408\"\n width=\"1181.24\"\n height=\"684.133\"\n fill=\"url(#paint0_linear_2_8065)\"\n />\n </mask>\n <g mask=\"url(#mask0_2_8065)\">\n <g opacity=\"0.3\">\n <g clipPath=\"url(#clip2_2_8065)\">\n <path\n d=\"M55.6533 284.621C54.582 285.692 54.5918 287.425 55.6562 288.489L99.9621 332.795C106.892 339.724 106.906 350.929 100.015 357.821C93.1228 364.712 81.9185 364.697 74.989 357.768L30.6831 313.462C15.7599 298.539 15.7201 274.398 30.5751 259.543C45.4302 244.688 69.5712 244.727 84.4945 259.651L114.326 289.482C115.39 290.546 117.123 290.556 118.194 289.485C119.265 288.414 119.255 286.681 118.191 285.617L73.8851 241.311C66.9557 234.381 66.9408 223.177 73.8326 216.285C80.7244 209.393 91.9287 209.408 98.8582 216.338L143.164 260.644C158.087 275.567 158.127 299.708 143.272 314.563C128.417 329.418 104.276 329.378 89.3527 314.455L59.5214 284.624C58.4571 283.559 56.7247 283.55 55.6533 284.621Z\"\n stroke=\"url(#paint1_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M142.429 198.7C141.359 199.77 141.361 201.504 142.429 202.572C143.497 203.64 145.231 203.642 146.301 202.573L176.132 172.741C191.05 157.823 215.251 157.833 230.185 172.767C245.119 187.7 245.128 211.901 230.21 226.819L185.904 271.125C178.98 278.049 167.747 278.046 160.814 271.113C153.881 264.18 153.877 252.946 160.801 246.022L205.107 201.716C206.177 200.647 206.175 198.913 205.107 197.845C204.039 196.777 202.305 196.774 201.235 197.844L171.404 227.675C156.486 242.593 132.285 242.584 117.351 227.65C102.417 212.716 102.408 188.516 117.326 173.598L161.632 129.292C168.556 122.368 179.789 122.371 186.722 129.304C193.655 136.237 193.659 147.47 186.735 154.395L142.429 198.7Z\"\n stroke=\"url(#paint2_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n <g clipPath=\"url(#clip3_2_8065)\">\n <path\n d=\"M230.049 110.225C228.978 111.297 228.988 113.029 230.052 114.094L274.358 158.399C281.288 165.329 281.303 176.533 274.411 183.425C267.519 190.317 256.315 190.302 249.385 183.373L205.079 139.067C190.156 124.143 190.116 100.002 204.971 85.1473C219.826 70.2923 243.967 70.332 258.891 85.2553L288.722 115.087C289.786 116.151 291.519 116.161 292.59 115.089C293.661 114.018 293.651 112.286 292.587 111.221L248.281 66.9155C241.352 59.986 241.337 48.7817 248.229 41.8899C255.121 34.998 266.325 35.013 273.254 41.9424L317.56 86.2483C332.483 101.172 332.523 125.313 317.668 140.168C302.813 155.023 278.672 154.983 263.749 140.06L233.918 110.228C232.853 109.164 231.121 109.154 230.049 110.225Z\"\n stroke=\"url(#paint3_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M316.825 24.3051C315.755 25.3747 315.757 27.1086 316.825 28.1767C317.893 29.2447 319.627 29.247 320.697 28.1773L350.528 -1.65402C365.446 -16.572 389.647 -16.5627 404.581 -1.62882C419.515 13.305 419.524 37.5057 404.606 52.4236L360.3 96.7295C353.376 103.654 342.143 103.65 335.21 96.7173C328.277 89.7844 328.273 78.551 335.197 71.6268L379.503 27.3209C380.573 26.2513 380.571 24.5174 379.503 23.4494C378.435 22.3813 376.701 22.3791 375.631 23.4487L345.8 53.28C330.882 68.198 306.681 68.1887 291.747 53.2548C276.813 38.321 276.804 14.1203 291.722 -0.797645L336.028 -45.1035C342.952 -52.0277 354.186 -52.0242 361.118 -45.0913C368.051 -38.1583 368.055 -26.925 361.131 -20.0008L316.825 24.3051Z\"\n stroke=\"url(#paint4_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n <g clipPath=\"url(#clip4_2_8065)\">\n <path\n d=\"M404.445 -64.1706C403.374 -63.0993 403.384 -61.3669 404.448 -60.3026L448.754 -15.9967C455.684 -9.06721 455.699 2.13713 448.807 9.02895C441.915 15.9208 430.711 15.9059 423.781 8.9764L379.475 -35.3295C364.552 -50.2527 364.512 -74.3938 379.367 -89.2488C394.222 -104.104 418.363 -104.064 433.287 -89.1409L463.118 -59.3095C464.182 -58.2452 465.915 -58.2353 466.986 -59.3067C468.057 -60.378 468.048 -62.1104 466.983 -63.1747L422.677 -107.481C415.748 -114.41 415.733 -125.614 422.625 -132.506C429.517 -139.398 440.721 -139.383 447.65 -132.454L491.956 -88.1478C506.879 -73.2246 506.919 -49.0835 492.064 -34.2285C477.209 -19.3735 453.068 -19.4132 438.145 -34.3365L408.314 -64.1678C407.249 -65.2321 405.517 -65.242 404.445 -64.1706Z\"\n stroke=\"url(#paint5_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n <g clipPath=\"url(#clip5_2_8065)\">\n <path\n d=\"M230.586 286.856C229.516 287.926 229.518 289.66 230.586 290.728C231.654 291.796 233.388 291.798 234.458 290.729L264.289 260.897C279.207 245.979 303.408 245.989 318.342 260.923C333.276 275.856 333.285 300.057 318.367 314.975L274.061 359.281C267.137 366.205 255.903 366.202 248.971 359.269C242.038 352.336 242.034 341.102 248.958 334.178L293.264 289.872C294.334 288.803 294.332 287.069 293.263 286.001C292.195 284.933 290.462 284.93 289.392 286L259.561 315.831C244.643 330.749 220.442 330.74 205.508 315.806C190.574 300.872 190.565 276.672 205.483 261.754L249.789 217.448C256.713 210.524 267.946 210.527 274.879 217.46C281.812 224.393 281.816 235.626 274.892 242.551L230.586 286.856Z\"\n stroke=\"url(#paint6_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n <g clipPath=\"url(#clip6_2_8065)\">\n <path\n d=\"M318.205 198.382C317.133 199.453 317.143 201.186 318.208 202.25L362.513 246.556C369.443 253.485 369.458 264.69 362.566 271.581C355.674 278.473 344.47 278.458 337.54 271.529L293.234 227.223C278.311 212.3 278.271 188.159 293.126 173.304C307.981 158.449 332.123 158.488 347.046 173.412L376.877 203.243C377.941 204.307 379.674 204.317 380.745 203.246C381.817 202.174 381.807 200.442 380.742 199.378L336.436 155.072C329.507 148.142 329.492 136.938 336.384 130.046C343.276 123.154 354.48 123.169 361.41 130.099L405.715 174.405C420.639 189.328 420.678 213.469 405.823 228.324C390.968 243.179 366.827 243.139 351.904 228.216L322.073 198.385C321.008 197.32 319.276 197.31 318.205 198.382Z\"\n stroke=\"url(#paint7_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M404.98 112.461C403.91 113.531 403.913 115.265 404.981 116.333C406.049 117.401 407.783 117.403 408.852 116.334L438.684 86.5023C453.602 71.5843 477.802 71.5936 492.736 86.5275C507.67 101.461 507.679 125.662 492.761 140.58L448.455 184.886C441.531 191.81 430.298 191.807 423.365 184.874C416.432 177.941 416.428 166.707 423.353 159.783L467.659 115.477C468.728 114.408 468.726 112.674 467.658 111.606C466.59 110.538 464.856 110.535 463.786 111.605L433.955 141.436C419.037 156.354 394.836 156.345 379.902 141.411C364.969 126.477 364.959 102.277 379.877 87.3587L424.183 43.0528C431.107 36.1286 442.341 36.1321 449.274 43.065C456.207 49.998 456.21 61.2313 449.286 68.1555L404.98 112.461Z\"\n stroke=\"url(#paint8_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n <g clipPath=\"url(#clip7_2_8065)\">\n <path\n d=\"M492.601 23.9857C491.529 25.0571 491.539 26.7895 492.604 27.8538L536.91 72.1597C543.839 79.0892 543.854 90.2935 536.962 97.1853C530.07 104.077 518.866 104.062 511.936 97.1328L467.631 52.8269C452.707 37.9036 452.668 13.7626 467.523 -1.09245C482.378 -15.9475 506.519 -15.9077 521.442 -0.984478L551.273 28.8469C552.338 29.9112 554.07 29.9211 555.141 28.8497C556.213 27.7783 556.203 26.046 555.138 24.9816L510.833 -19.3243C503.903 -26.2537 503.888 -37.4581 510.78 -44.3499C517.672 -51.2417 528.876 -51.2268 535.806 -44.2973L580.112 0.00856119C595.035 14.9318 595.075 39.0729 580.22 53.9279C565.364 68.7829 541.223 68.7432 526.3 53.8199L496.469 23.9886C495.405 22.9242 493.672 22.9144 492.601 23.9857Z\"\n stroke=\"url(#paint9_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n <g clipPath=\"url(#clip8_2_8065)\">\n <path\n d=\"M406.362 286.537C405.29 287.608 405.3 289.34 406.365 290.405L450.67 334.71C457.6 341.64 457.615 352.844 450.723 359.736C443.831 366.628 432.627 366.613 425.697 359.684L381.392 315.378C366.468 300.454 366.429 276.313 381.284 261.458C396.139 246.603 420.28 246.643 435.203 261.566L465.034 291.398C466.099 292.462 467.831 292.472 468.902 291.4C469.974 290.329 469.964 288.597 468.899 287.532L424.594 243.227C417.664 236.297 417.649 225.093 424.541 218.201C431.433 211.309 442.637 211.324 449.567 218.253L493.872 262.559C508.796 277.483 508.835 301.624 493.98 316.479C479.125 331.334 454.984 331.294 440.061 316.371L410.23 286.539C409.165 285.475 407.433 285.465 406.362 286.537Z\"\n stroke=\"url(#paint10_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M493.137 200.616C492.067 201.686 492.07 203.42 493.138 204.488C494.206 205.556 495.94 205.558 497.009 204.488L526.841 174.657C541.759 159.739 565.959 159.748 580.893 174.682C595.827 189.616 595.836 213.817 580.918 228.735L536.612 273.041C529.688 279.965 518.455 279.961 511.522 273.028C504.589 266.095 504.586 254.862 511.51 247.938L555.816 203.632C556.885 202.562 556.883 200.828 555.815 199.76C554.747 198.692 553.013 198.69 551.943 199.76L522.112 229.591C507.194 244.509 482.993 244.5 468.06 229.566C453.126 214.632 453.116 190.431 468.034 175.513L512.34 131.207C519.264 124.283 530.498 124.287 537.431 131.22C544.364 138.153 544.367 149.386 537.443 156.31L493.137 200.616Z\"\n stroke=\"url(#paint11_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n </g>\n <g opacity=\"0.3\">\n <g clipPath=\"url(#clip9_2_8065)\">\n <path\n d=\"M-33.3645 22.9074C-34.4342 23.977 -34.4319 25.7109 -33.3638 26.7789C-32.2958 27.847 -30.5619 27.8493 -29.4923 26.7796L0.339089 -3.05172C15.257 -17.9697 39.4577 -17.9604 54.3916 -3.02652C69.3254 11.9073 69.3347 36.108 54.4168 51.0259L10.1109 95.3318C3.18672 102.256 -8.04665 102.252 -14.9796 95.3196C-21.9125 88.3866 -21.916 77.1533 -14.9918 70.2291L29.3141 25.9232C30.3837 24.8536 30.3814 23.1197 29.3134 22.0517C28.2454 20.9836 26.5114 20.9814 25.4418 22.051L-4.38954 51.8823C-19.3075 66.8003 -43.5082 66.791 -58.442 51.8571C-73.3759 36.9233 -73.3852 12.7226 -58.4672 -2.19535L-14.1613 -46.5012C-7.23718 -53.4254 3.99619 -53.4219 10.9291 -46.489C17.862 -39.556 17.8655 -28.3227 10.9414 -21.3985L-33.3645 22.9074Z\"\n stroke=\"url(#paint12_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n <g clipPath=\"url(#clip10_2_8065)\">\n <path\n d=\"M54.2562 -65.5677C53.1849 -64.4964 53.1947 -62.764 54.2591 -61.6997L98.565 -17.3938C105.494 -10.4643 105.509 0.740023 98.6175 7.63184C91.7257 14.5237 80.5214 14.5088 73.5919 7.57929L29.286 -36.7266C14.3628 -51.6498 14.323 -75.7909 29.1781 -90.6459C44.0331 -105.501 68.1741 -105.461 83.0974 -90.5379L112.929 -60.7066C113.993 -59.6423 115.725 -59.6324 116.797 -60.7038C117.868 -61.7751 117.858 -63.5075 116.794 -64.5718L72.488 -108.878C65.5586 -115.807 65.5437 -127.012 72.4355 -133.903C79.3273 -140.795 90.5317 -140.78 97.4611 -133.851L141.767 -89.5449C156.69 -74.6217 156.73 -50.4806 141.875 -35.6256C127.02 -20.7706 102.879 -20.8103 87.9556 -35.7336L58.1243 -65.5649C57.06 -66.6292 55.3276 -66.6391 54.2562 -65.5677Z\"\n stroke=\"url(#paint13_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n <g clipPath=\"url(#clip11_2_8065)\">\n <path\n d=\"M-31.983 196.985C-33.0543 198.056 -33.0445 199.788 -31.9801 200.853L12.3258 245.159C19.2552 252.088 19.2701 263.292 12.3783 270.184C5.4865 277.076 -5.71784 277.061 -12.6473 270.132L-56.9532 225.826C-71.8764 210.902 -71.9162 186.761 -57.0611 171.906C-42.2061 157.051 -18.0651 157.091 -3.14183 172.014L26.6895 201.846C27.7538 202.91 29.4862 202.92 30.5576 201.849C31.629 200.777 31.6191 199.045 30.5547 197.98L-13.7512 153.675C-20.6806 146.745 -20.6955 135.541 -13.8037 128.649C-6.91189 121.757 4.29245 121.772 11.2219 128.702L55.5278 173.007C70.451 187.931 70.4908 212.072 55.6358 226.927C40.7807 241.782 16.6397 241.742 1.71644 226.819L-28.1149 196.987C-29.1792 195.923 -30.9116 195.913 -31.983 196.985Z\"\n stroke=\"url(#paint14_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M54.7925 111.064C53.7228 112.134 53.7251 113.868 54.7931 114.936C55.8611 116.004 57.5951 116.006 58.6647 114.936L88.4961 85.1051C103.414 70.1871 127.615 70.1964 142.549 85.1303C157.482 100.064 157.492 124.265 142.574 139.183L98.2678 183.489C91.3437 190.413 80.1103 190.409 73.1774 183.476C66.2445 176.543 66.241 165.31 73.1651 158.386L117.471 114.08C118.541 113.01 118.538 111.276 117.47 110.208C116.402 109.14 114.668 109.138 113.599 110.208L83.7674 140.039C68.8495 154.957 44.6488 154.948 29.715 140.014C14.7811 125.08 14.7718 100.879 29.6898 85.9614L73.9956 41.6556C80.9198 34.7314 92.1532 34.7349 99.0861 41.6678C106.019 48.6008 106.023 59.8341 99.0984 66.7583L54.7925 111.064Z\"\n stroke=\"url(#paint15_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n <g clipPath=\"url(#clip12_2_8065)\">\n <path\n d=\"M142.413 22.5881C141.342 23.6595 141.352 25.3918 142.416 26.4562L186.722 70.762C193.651 77.6915 193.666 88.8958 186.774 95.7877C179.883 102.679 168.678 102.665 161.749 95.7351L117.443 51.4292C102.52 36.506 102.48 12.3649 117.335 -2.49009C132.19 -17.3451 156.331 -17.3054 171.254 -2.38212L201.086 27.4492C202.15 28.5135 203.882 28.5234 204.954 27.4521C206.025 26.3807 206.015 24.6483 204.951 23.584L160.645 -20.7219C153.715 -27.6514 153.701 -38.8557 160.592 -45.7475C167.484 -52.6393 178.689 -52.6244 185.618 -45.695L229.924 -1.38908C244.847 13.5342 244.887 37.6752 230.032 52.5302C215.177 67.3853 191.036 67.3455 176.113 52.4223L146.281 22.5909C145.217 21.5266 143.484 21.5167 142.413 22.5881Z\"\n stroke=\"url(#paint16_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M229.189 -63.3323C228.119 -62.2627 228.121 -60.5287 229.189 -59.4607C230.257 -58.3927 231.991 -58.3904 233.061 -59.4601L262.892 -89.2914C277.81 -104.209 302.011 -104.2 316.945 -89.2662C331.878 -74.3323 331.888 -50.1317 316.97 -35.2137L272.664 9.09215C265.74 16.0163 254.506 16.0128 247.573 9.07988C240.641 2.14696 240.637 -9.08641 247.561 -16.0106L291.867 -60.3164C292.937 -61.3861 292.934 -63.12 291.866 -64.188C290.798 -65.2561 289.064 -65.2583 287.995 -64.1887L258.163 -34.3574C243.246 -19.4394 219.045 -19.4487 204.111 -34.3826C189.177 -49.3164 189.168 -73.5171 204.086 -88.435L248.392 -132.741C255.316 -139.665 266.549 -139.662 273.482 -132.729C280.415 -125.796 280.419 -114.562 273.494 -107.638L229.189 -63.3323Z\"\n stroke=\"url(#paint17_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n </g>\n </g>\n </g>\n </g>\n </g>\n <rect\n x=\"1.12245\"\n y=\"1.12245\"\n width=\"437.755\"\n height=\"437.755\"\n rx=\"23.5714\"\n stroke=\"url(#paint18_linear_2_8065)\"\n strokeWidth=\"2.2449\"\n />\n </>\n )\n}\n\n// Sub-component: SuiNS Logo\nconst SuiNSLogo: FC = () => {\n return (\n <>\n <g clipPath=\"url(#clip13_2_8065)\">\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M330.479 342.088C330.237 342.088 330.041 342.285 330.041 342.527V368.61C330.041 373.074 326.429 376.692 321.974 376.692C317.518 376.692 313.906 373.074 313.906 368.61V342.527C313.906 333.357 321.326 325.923 330.479 325.923C339.632 325.923 347.052 333.357 347.052 342.527V360.088C347.052 360.331 347.248 360.527 347.49 360.527C347.731 360.527 347.927 360.331 347.927 360.088V334.006C347.927 329.542 351.539 325.923 355.995 325.923C360.45 325.923 364.062 329.542 364.062 334.006V360.088C364.062 369.258 356.642 376.692 347.49 376.692C338.337 376.692 330.917 369.258 330.917 360.088V342.527C330.917 342.285 330.721 342.088 330.479 342.088Z\"\n fill=\"#DAD0FF\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M381.32 342.348C381.079 342.348 380.883 342.544 380.883 342.786C380.883 343.028 381.079 343.225 381.32 343.225H398.849C408.002 343.225 415.422 350.659 415.422 359.828C415.422 368.998 408.002 376.432 398.849 376.432H372.815C368.359 376.432 364.747 372.813 364.747 368.35C364.747 363.886 368.359 360.267 372.815 360.267H398.849C399.091 360.267 399.287 360.07 399.287 359.828C399.287 359.586 399.091 359.39 398.849 359.39H381.32C372.168 359.39 364.747 351.956 364.747 342.786C364.747 333.616 372.168 326.182 381.32 326.182H407.355C411.81 326.182 415.422 329.801 415.422 334.265C415.422 338.729 411.81 342.348 407.355 342.348H381.32Z\"\n fill=\"#DAD0FF\"\n />\n </g>\n <rect\n x=\"287.089\"\n y=\"351.359\"\n width=\"25.156\"\n height=\"25.1977\"\n rx=\"12.578\"\n fill=\"#DAD0FF\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M303.198 362.795V362.796C303.812 363.575 304.178 364.563 304.178 365.637C304.178 366.711 303.801 367.728 303.171 368.513L303.116 368.58L303.102 368.494C303.09 368.421 303.075 368.347 303.059 368.273C302.744 366.869 301.716 365.665 300.025 364.69C298.883 364.034 298.229 363.243 298.058 362.345C297.947 361.764 298.029 361.181 298.189 360.681C298.348 360.182 298.585 359.763 298.786 359.511L299.444 358.696C299.559 358.553 299.775 358.553 299.89 358.696L303.199 362.795L303.198 362.795ZM304.239 361.981V361.98L299.83 356.517C299.746 356.413 299.588 356.413 299.504 356.517L295.095 361.981V361.981L295.08 361.999C294.269 363.019 293.784 364.316 293.784 365.727C293.784 369.014 296.418 371.679 299.667 371.679C302.916 371.679 305.55 369.014 305.55 365.727C305.55 364.316 305.065 363.019 304.253 361.999L304.239 361.981H304.239ZM296.15 362.777L296.544 362.289L296.556 362.379C296.566 362.45 296.577 362.522 296.591 362.594C296.846 363.951 297.757 365.082 299.281 365.959C300.606 366.722 301.377 367.601 301.6 368.565C301.692 368.967 301.709 369.363 301.669 369.708L301.666 369.73L301.647 369.739C301.049 370.035 300.377 370.202 299.667 370.202C297.175 370.202 295.155 368.158 295.155 365.637C295.155 364.555 295.527 363.56 296.15 362.778L296.15 362.777Z\"\n fill=\"#221C36\"\n />\n </>\n )\n}\n\nconst DomainCardSvg: FC<DomainCardSvgProps> = ({ className }) => {\n return (\n <svg\n viewBox=\"0 0 440 440\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n role=\"img\"\n aria-label=\"Domain card background\"\n className={className}\n >\n {/* Background with decorative patterns */}\n <CardBackground />\n\n {/* SuiNS Logo */}\n <SuiNSLogo />\n\n {/* SVG Definitions (gradients and clip paths) */}\n <defs>\n <linearGradient id=\"gradient\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" stopColor=\"#4bffa6\" />\n <stop offset=\"56%\" stopColor=\"#ff794b\" />\n <stop offset=\"100%\" stopColor=\"#d962ff\" />\n </linearGradient>\n <linearGradient\n id=\"paint0_linear_2_8065\"\n x1=\"220.592\"\n y1=\"-52.8804\"\n x2=\"220.592\"\n y2=\"282.725\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"white\" />\n <stop offset=\"1\" stopColor=\"white\" stopOpacity=\"0\" />\n </linearGradient>\n <linearGradient\n id=\"paint1_linear_2_8065\"\n x1=\"13.27\"\n y1=\"274.467\"\n x2=\"134.549\"\n y2=\"215.647\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint2_linear_2_8065\"\n x1=\"100.083\"\n y1=\"188.459\"\n x2=\"223.203\"\n y2=\"129.859\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint3_linear_2_8065\"\n x1=\"187.666\"\n y1=\"100.071\"\n x2=\"308.945\"\n y2=\"41.2512\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint4_linear_2_8065\"\n x1=\"274.479\"\n y1=\"14.064\"\n x2=\"397.599\"\n y2=\"-44.5362\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint5_linear_2_8065\"\n x1=\"362.062\"\n y1=\"-74.3248\"\n x2=\"483.341\"\n y2=\"-133.145\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint6_linear_2_8065\"\n x1=\"188.24\"\n y1=\"276.615\"\n x2=\"311.36\"\n y2=\"218.015\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint7_linear_2_8065\"\n x1=\"275.821\"\n y1=\"188.228\"\n x2=\"397.1\"\n y2=\"129.408\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint8_linear_2_8065\"\n x1=\"362.634\"\n y1=\"102.22\"\n x2=\"485.754\"\n y2=\"43.6201\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint9_linear_2_8065\"\n x1=\"450.217\"\n y1=\"13.8316\"\n x2=\"571.496\"\n y2=\"-44.9885\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint10_linear_2_8065\"\n x1=\"363.978\"\n y1=\"276.382\"\n x2=\"485.257\"\n y2=\"217.562\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint11_linear_2_8065\"\n x1=\"450.792\"\n y1=\"190.375\"\n x2=\"573.912\"\n y2=\"131.775\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint12_linear_2_8065\"\n x1=\"-75.71\"\n y1=\"12.6663\"\n x2=\"47.41\"\n y2=\"-45.9339\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint13_linear_2_8065\"\n x1=\"11.8729\"\n y1=\"-75.7219\"\n x2=\"133.151\"\n y2=\"-134.542\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint14_linear_2_8065\"\n x1=\"-74.3663\"\n y1=\"186.83\"\n x2=\"46.9122\"\n y2=\"128.01\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint15_linear_2_8065\"\n x1=\"12.447\"\n y1=\"100.823\"\n x2=\"135.567\"\n y2=\"42.2229\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint16_linear_2_8065\"\n x1=\"100.03\"\n y1=\"12.434\"\n x2=\"221.308\"\n y2=\"-46.3862\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint17_linear_2_8065\"\n x1=\"186.843\"\n y1=\"-73.5734\"\n x2=\"309.963\"\n y2=\"-132.174\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint18_linear_2_8065\"\n x1=\"541.75\"\n y1=\"220\"\n x2=\"134.237\"\n y2=\"-134.348\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"1\" stopColor=\"#D34BFF\" />\n </linearGradient>\n <clipPath id=\"clip0_2_8065\">\n <rect width=\"440\" height=\"440\" rx=\"24.6939\" fill=\"white\" />\n </clipPath>\n <clipPath id=\"clip1_2_8065\">\n <rect width=\"440\" height=\"440\" fill=\"white\" />\n </clipPath>\n <clipPath id=\"clip2_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(1.28839 286.448) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip3_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(175.685 112.053) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip4_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(350.081 -62.3431) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip5_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(89.4453 374.604) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip6_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(263.84 200.209) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip7_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(438.236 25.8132) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip8_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(351.997 288.364) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip9_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(-174.505 110.655) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip10_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(-0.108704 -63.7402) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip11_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(-86.3479 198.812) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip12_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(88.0482 24.4156) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip13_2_8065\">\n <rect\n width=\"101.516\"\n height=\"50.7692\"\n fill=\"white\"\n transform=\"translate(313.906 325.923)\"\n />\n </clipPath>\n </defs>\n </svg>\n )\n}\n\nexport default DomainCardSvg\n","import { style } from '@vanilla-extract/css'\nimport { themeVars } from '~/theme.css'\n\nexport const overlay = style({\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n position: 'fixed',\n inset: 0,\n zIndex: 50\n})\n\nexport const content = style({\n backgroundColor: themeVars.colors.background,\n borderRadius: themeVars.radius.lg,\n boxShadow:\n '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n width: '90vw',\n maxWidth: '56rem',\n maxHeight: '85vh',\n overflow: 'auto',\n zIndex: 51,\n border: `1px solid ${themeVars.colors.border}`\n})\n\nexport const header = style({\n padding: themeVars.spacing.md,\n paddingBottom: 0\n})\n\nexport const title = style({\n fontSize: '1.125rem',\n fontWeight: 600,\n color: themeVars.colors.foreground,\n marginBottom: themeVars.spacing.xs\n})\n\nexport const description = style({\n fontSize: '0.875rem',\n color: themeVars.colors.mutedForeground\n})\n\nexport const body = style({\n padding: themeVars.spacing.md,\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.xs\n})\n\nexport const section = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.xs\n})\n\nexport const sectionTitle = style({\n fontSize: '0.875rem',\n fontWeight: 500,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between'\n})\n\nexport const domainList = style({\n border: `1px solid ${themeVars.colors.border}`,\n borderRadius: themeVars.radius.md,\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column'\n})\n\nexport const domainItem = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: `${themeVars.spacing.sm} ${themeVars.spacing.md}`,\n borderBottom: `1px solid ${themeVars.colors.border}`,\n ':last-child': {\n borderBottom: 'none'\n }\n})\n\nexport const domainCardGrid = style({\n display: 'flex',\n flexWrap: 'wrap',\n gap: themeVars.spacing.lg,\n maxHeight: '25rem',\n overflowY: 'auto',\n padding: themeVars.spacing.xs\n})\n\nexport const domainCard = style({\n width: '9rem',\n height: '9rem',\n position: 'relative',\n padding: themeVars.spacing.md,\n border: 'none',\n cursor: 'pointer',\n transition: 'all 0.2s ease-in-out',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'space-between',\n alignItems: 'flex-start',\n background: 'none',\n selectors: {\n '&:hover:not(:disabled)': {\n transform: 'scale(0.98)',\n borderColor: themeVars.colors.primary\n },\n '&:active:not(:disabled)': {\n transform: 'scale(0.95)'\n },\n '&:disabled': {\n cursor: 'not-allowed',\n opacity: 0.5,\n filter: 'grayscale(1)'\n }\n }\n})\n\nexport const domainCardBg = style({\n position: 'absolute',\n inset: 0,\n zIndex: -1,\n pointerEvents: 'none'\n})\n\nexport const domainName = style({\n fontSize: '1.25rem',\n fontWeight: 700,\n background: 'linear-gradient(90deg, #4bffa6 0%, #ff794b 56%, #d962ff 100%)',\n WebkitBackgroundClip: 'text',\n WebkitTextFillColor: 'transparent',\n wordBreak: 'break-all',\n lineHeight: 1.2\n})\n\nexport const domainExpiry = style({\n fontSize: '0.75rem',\n color: '#DAD0FF'\n})\n\nexport const infoPanel = style({\n display: 'flex',\n gap: themeVars.spacing.md,\n padding: themeVars.spacing.lg,\n backgroundColor: 'rgba(59, 130, 246, 0.1)',\n border: '1px solid rgba(59, 130, 246, 0.2)',\n borderRadius: themeVars.radius.lg\n})\n\nexport const link = style({\n color: themeVars.colors.cyan,\n textDecoration: 'none',\n wordBreak: 'break-all',\n ':hover': {\n textDecoration: 'underline'\n }\n})\n\nexport const loadingSpinner = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: `${themeVars.spacing.xl} 0`,\n color: themeVars.colors.mutedForeground\n})\n","import type {\n ISignAndExecuteTransaction,\n ISponsorConfig\n} from '@cmdoss/walrus-site-builder'\nimport type { SuiClient } from '@mysten/sui/client'\nimport type { SuinsClient } from '@mysten/suins'\nimport type { WalletAccount } from '@mysten/wallet-standard'\nimport * as Dialog from '@radix-ui/react-dialog'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { CheckCircle2, Loader2, Search, X } from 'lucide-react'\nimport type { FC } from 'react'\nimport { useSuiNsRegistration } from '~/hooks'\nimport { Button } from '../ui/Button'\nimport { Input } from '../ui/Input'\nimport * as styles from './SuiNsModal.css'\n\ninterface RegisterSuiNsDialogProps {\n isOpen: boolean\n onClose: () => void\n onRegistered?: () => void\n currentAccount: WalletAccount | null\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n suinsClient: SuinsClient\n }\n signAndExecuteTransaction: ISignAndExecuteTransaction\n sponsorConfig?: ISponsorConfig\n}\n\nexport const RegisterSuiNsDialog: FC<RegisterSuiNsDialogProps> = ({\n isOpen,\n onClose,\n onRegistered,\n currentAccount,\n clients: { suiClient, queryClient, suinsClient },\n signAndExecuteTransaction,\n sponsorConfig\n}) => {\n const {\n searchName,\n setSearchName,\n isSearching,\n isAvailable,\n isRegistering,\n isSwapping,\n estimatedPrice,\n error,\n normalizedName,\n fullName,\n selectedYears,\n setSelectedYears,\n pricePerYearFormatted,\n pricePerYearUsdc,\n totalPriceFormatted,\n totalPriceUsdc,\n expirationDate,\n handleSearch,\n handleRegister: handleRegisterInternal,\n reset\n } = useSuiNsRegistration({\n currentAccount,\n clients: { suiClient, queryClient, suinsClient },\n signAndExecuteTransaction,\n sponsorConfig\n })\n\n const network = suiClient.network\n const isTestnet = network === 'testnet'\n\n const handleRegister = async () => {\n const success = await handleRegisterInternal()\n if (success) {\n if (onRegistered) {\n onRegistered()\n }\n handleClose()\n }\n }\n\n const handleClose = () => {\n reset()\n onClose()\n }\n\n if (!currentAccount) {\n return null\n }\n\n return (\n <Dialog.Root open={isOpen} onOpenChange={open => !open && handleClose()}>\n <Dialog.Portal>\n <Dialog.Overlay\n className={styles.overlay}\n style={{\n zIndex: 51,\n backgroundColor: 'rgba(0, 0, 0, 0.7)'\n }}\n />\n <Dialog.Content\n className={styles.content}\n style={{ maxWidth: '32rem', zIndex: 52 }}\n >\n {/* Loading Overlay */}\n {(isRegistering || isSwapping) && (\n <div\n style={{\n position: 'absolute',\n inset: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n backdropFilter: 'blur(4px)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 100,\n borderRadius: '0.75rem'\n }}\n >\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '0.75rem'\n }}\n >\n <Loader2\n style={{\n width: '2rem',\n height: '2rem',\n animation: 'spin 1s linear infinite',\n color: 'white'\n }}\n />\n <p style={{ fontSize: '0.875rem', color: 'white' }}>\n {isSwapping\n ? 'Swapping WAL to USDC...'\n : 'Registering domain...'}\n </p>\n </div>\n </div>\n )}\n\n {/* Header */}\n <div className={styles.header}>\n <Dialog.Title className={styles.title}>\n Register SuiNS Domain\n </Dialog.Title>\n <Dialog.Description className={styles.description}>\n Search and register a new .sui domain name\n </Dialog.Description>\n <Dialog.Close asChild>\n <button\n type=\"button\"\n onClick={handleClose}\n disabled={isRegistering}\n style={{\n position: 'absolute',\n right: '1rem',\n top: '1rem',\n padding: '0.5rem',\n borderRadius: '0.375rem',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center'\n }}\n >\n <X style={{ width: '1rem', height: '1rem' }} />\n </button>\n </Dialog.Close>\n </div>\n\n {/* Content */}\n <div className={styles.body}>\n {/* Search Section */}\n <div style={{ marginBottom: '1rem' }}>\n <label\n htmlFor=\"domain-search\"\n style={{\n display: 'block',\n fontSize: '0.875rem',\n fontWeight: 500,\n marginBottom: '0.5rem'\n }}\n >\n Search for a domain\n </label>\n <div style={{ display: 'flex', gap: '0.5rem' }}>\n <div style={{ position: 'relative', flex: 1 }}>\n <Input\n id=\"domain-search\"\n type=\"text\"\n value={searchName}\n onChange={e => {\n setSearchName(e.target.value)\n }}\n onKeyDown={e => {\n if (e.key === 'Enter' && normalizedName) {\n handleSearch()\n }\n }}\n placeholder=\"Enter domain name\"\n disabled={isSearching || isRegistering}\n style={{ paddingRight: '3rem' }}\n />\n <span\n style={{\n position: 'absolute',\n right: '0.75rem',\n top: '50%',\n transform: 'translateY(-50%)',\n fontSize: '0.875rem',\n color: 'var(--muted-foreground)',\n pointerEvents: 'none'\n }}\n >\n .sui\n </span>\n </div>\n <Button\n onClick={handleSearch}\n disabled={isSearching || isRegistering || !normalizedName}\n size=\"default\"\n >\n {isSearching ? (\n <Loader2\n style={{\n width: '1rem',\n height: '1rem',\n animation: 'spin 1s linear infinite'\n }}\n />\n ) : (\n <Search style={{ width: '1rem', height: '1rem' }} />\n )}\n </Button>\n </div>\n </div>\n\n {/* Availability Alert */}\n {isAvailable !== null && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '0.625rem',\n padding: '0.875rem',\n borderRadius: '0.5rem',\n border: `1px solid ${\n isAvailable\n ? 'rgba(34, 197, 94, 0.2)'\n : 'rgba(239, 68, 68, 0.2)'\n }`,\n backgroundColor: isAvailable\n ? 'rgba(34, 197, 94, 0.1)'\n : 'rgba(239, 68, 68, 0.1)',\n color: isAvailable ? 'rgb(22, 163, 74)' : 'rgb(220, 38, 38)',\n marginBottom: '1rem'\n }}\n >\n <CheckCircle2\n style={{\n width: '1.25rem',\n height: '1.25rem',\n flexShrink: 0\n }}\n />\n <div style={{ flex: 1, minWidth: 0 }}>\n <p style={{ fontSize: '0.875rem', fontWeight: 600 }}>\n {isAvailable\n ? `${fullName} is available!`\n : `${fullName} is already taken`}\n </p>\n </div>\n </div>\n )}\n\n {/* Year Selection */}\n {isAvailable && (\n <div style={{ marginBottom: '1rem' }}>\n <label\n htmlFor=\"year-select\"\n style={{\n display: 'block',\n fontSize: '0.875rem',\n fontWeight: 500,\n marginBottom: '0.5rem'\n }}\n >\n Registration Period\n </label>\n <div\n style={{\n display: 'flex',\n gap: '0.5rem',\n flexWrap: 'wrap'\n }}\n >\n {[1, 2, 3, 4, 5].map(year => (\n <button\n key={year}\n type=\"button\"\n onClick={() => setSelectedYears(year)}\n disabled={isRegistering || isSwapping}\n style={{\n padding: '0.5rem 1rem',\n borderRadius: '0.375rem',\n border: `1px solid ${\n selectedYears === year\n ? 'rgba(59, 130, 246, 0.5)'\n : 'rgba(229, 231, 235, 1)'\n }`,\n backgroundColor:\n selectedYears === year\n ? 'rgba(59, 130, 246, 0.1)'\n : 'transparent',\n color:\n selectedYears === year\n ? 'rgb(37, 99, 235)'\n : 'inherit',\n fontWeight: selectedYears === year ? 600 : 400,\n cursor:\n isRegistering || isSwapping\n ? 'not-allowed'\n : 'pointer',\n fontSize: '0.875rem',\n transition: 'all 0.2s',\n opacity: isRegistering || isSwapping ? 0.5 : 1\n }}\n >\n {year} {year === 1 ? 'Year' : 'Years'}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {/* Price Breakdown */}\n {isAvailable && (pricePerYearFormatted || estimatedPrice) && (\n <div\n style={{\n padding: '1rem',\n borderRadius: '0.5rem',\n backgroundColor: 'rgba(249, 250, 251, 1)',\n border: '1px solid rgba(229, 231, 235, 1)',\n marginBottom: '1rem'\n }}\n >\n <h3\n style={{\n fontSize: '0.875rem',\n fontWeight: 600,\n marginBottom: '0.75rem',\n color: 'rgb(17, 24, 39)'\n }}\n >\n Price Breakdown\n </h3>\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '0.5rem'\n }}\n >\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center'\n }}\n >\n <span\n style={{\n fontSize: '0.875rem',\n color: 'rgb(107, 114, 128)'\n }}\n >\n Price per year:\n </span>\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-end',\n gap: '0.125rem'\n }}\n >\n <span\n style={{\n fontSize: '0.875rem',\n fontWeight: 600,\n color: 'rgb(17, 24, 39)'\n }}\n >\n {pricePerYearFormatted || estimatedPrice}\n </span>\n {isTestnet && pricePerYearUsdc && (\n <span\n style={{\n fontSize: '0.75rem',\n color: 'rgb(107, 114, 128)',\n opacity: 0.8\n }}\n >\n ({pricePerYearUsdc})\n </span>\n )}\n </div>\n </div>\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center'\n }}\n >\n <span\n style={{\n fontSize: '0.875rem',\n color: 'rgb(107, 114, 128)'\n }}\n >\n Number of years:\n </span>\n <span\n style={{\n fontSize: '0.875rem',\n fontWeight: 600,\n color: 'rgb(17, 24, 39)'\n }}\n >\n {selectedYears}\n </span>\n </div>\n <div\n style={{\n height: '1px',\n backgroundColor: 'rgba(229, 231, 235, 1)',\n margin: '0.5rem 0'\n }}\n />\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center'\n }}\n >\n <span\n style={{\n fontSize: '0.875rem',\n fontWeight: 600,\n color: 'rgb(17, 24, 39)'\n }}\n >\n Total:\n </span>\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-end',\n gap: '0.125rem'\n }}\n >\n <span\n style={{\n fontSize: '1rem',\n fontWeight: 700,\n color: 'rgb(17, 24, 39)'\n }}\n >\n {totalPriceFormatted || estimatedPrice}\n </span>\n {isTestnet && totalPriceUsdc && (\n <span\n style={{\n fontSize: '0.75rem',\n color: 'rgb(107, 114, 128)',\n opacity: 0.8\n }}\n >\n ({totalPriceUsdc})\n </span>\n )}\n </div>\n </div>\n {expirationDate && (\n <div\n style={{\n marginTop: '0.5rem',\n paddingTop: '0.5rem',\n borderTop: '1px solid rgba(229, 231, 235, 1)'\n }}\n >\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center'\n }}\n >\n <span\n style={{\n fontSize: '0.75rem',\n color: 'rgb(107, 114, 128)'\n }}\n >\n Expires on:\n </span>\n <span\n style={{\n fontSize: '0.75rem',\n fontWeight: 500,\n color: 'rgb(17, 24, 39)'\n }}\n >\n {expirationDate.toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric'\n })}\n </span>\n </div>\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Error */}\n {error && (\n <div\n style={{\n padding: '0.75rem',\n borderRadius: '0.5rem',\n backgroundColor: 'rgba(239, 68, 68, 0.1)',\n color: 'rgb(220, 38, 38)',\n fontSize: '0.875rem',\n marginBottom: '1rem'\n }}\n >\n {error}\n </div>\n )}\n\n {/* Register Button */}\n {isAvailable && (\n <Button\n onClick={handleRegister}\n disabled={isRegistering || isSwapping || !normalizedName}\n variant=\"gradient\"\n size=\"default\"\n style={{ width: '100%' }}\n >\n {isSwapping ? (\n <>\n <Loader2\n style={{\n width: '1rem',\n height: '1rem',\n animation: 'spin 1s linear infinite',\n marginRight: '0.5rem'\n }}\n />\n Swapping WAL to USDC...\n </>\n ) : isRegistering ? (\n <>\n <Loader2\n style={{\n width: '1rem',\n height: '1rem',\n animation: 'spin 1s linear infinite',\n marginRight: '0.5rem'\n }}\n />\n Registering...\n </>\n ) : (\n `Register ${fullName} for ${selectedYears} ${selectedYears === 1 ? 'year' : 'years'}`\n )}\n </Button>\n )}\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n )\n}\n","import {\n type ISignAndExecuteTransaction,\n type ISponsorConfig,\n suinsDomainToWalrusSiteUrl\n} from '@cmdoss/walrus-site-builder'\nimport type { SuiClient } from '@mysten/sui/client'\nimport type { SuinsClient } from '@mysten/suins'\nimport type { WalletAccount } from '@mysten/wallet-standard'\nimport { useStore } from '@nanostores/react'\nimport * as Dialog from '@radix-ui/react-dialog'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { ExternalLink, Loader2, X } from 'lucide-react'\nimport type { FC } from 'react'\nimport { useSuiNsDomainsQuery } from '~/queries'\nimport {\n isAssigningDomain,\n isDomainDialogOpen,\n isRegisterSuiNSDomainDialogOpen\n} from '~/stores/site-domain.store'\nimport { siteMetadataStore } from '~/stores/site-metadata.store'\nimport { Banner } from '../ui'\nimport { Button } from '../ui/Button'\nimport DomainCardSvg from './DomainCardSvg'\nimport { RegisterSuiNsDialog } from './RegisterSuiNsDialog'\nimport * as styles from './SuiNsModal.css'\n\nexport interface SuiNsDomain {\n nftId: string\n name: string\n expirationTimestampMs?: number\n walrusSiteId?: string\n walrusSiteUrl?: string\n}\n\ninterface SuiNsModalProps {\n siteId: string | undefined\n onAssociateDomain?: (nftId: string, siteId: string, suiNSName: string) => void\n currentAccount: WalletAccount | null\n /** Optional domain for the portal to view published site. */\n portalDomain?: string\n /** Whether to use HTTPS for the portal URL. */\n portalHttps?: boolean\n /**\n * Sui and Query clients needed for on-chain operations.\n */\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n suinsClient: SuinsClient\n }\n /**\n * Callback for signing and executing transactions.\n * Required for registering new SuiNS domains.\n */\n signAndExecuteTransaction?: ISignAndExecuteTransaction\n /**\n * Optional sponsor configuration for transaction sponsorship.\n */\n sponsorConfig?: ISponsorConfig\n}\n\nconst SuiNsModal: FC<SuiNsModalProps> = ({\n siteId,\n onAssociateDomain,\n currentAccount,\n portalDomain,\n portalHttps,\n clients: { suiClient, queryClient, suinsClient },\n signAndExecuteTransaction,\n sponsorConfig\n}) => {\n const isOpen = useStore(isDomainDialogOpen)\n const isAssigning = useStore(isAssigningDomain)\n const isRegisterSuiNSDomainDialog = useStore(isRegisterSuiNSDomainDialogOpen)\n const suiNSUrlArray = useStore(siteMetadataStore.suiNSUrl)\n const { network } = suiClient\n const {\n data: nsDomains,\n isLoading: isLoadingDomains,\n isError: isErrorDomains\n } = useSuiNsDomainsQuery(currentAccount, { suiClient, queryClient })\n\n // Find all domains that are linked in store (suiNSUrlArray)\n const connectedDomains = nsDomains.filter(domain => {\n console.log('[1]domain', domain)\n console.log('[1]suiNSUrlArray', suiNSUrlArray)\n return suiNSUrlArray.some(entry => entry.nftId === domain.nftId)\n })\n\n // Explorer URL\n const explorerUrl = siteId\n ? network === 'testnet'\n ? `https://testnet.suivision.xyz/object/${siteId}`\n : `https://suivision.xyz/object/${siteId}`\n : undefined\n\n const handleAssociate = (nftId: string, suiNSName: string) => {\n if (siteId && onAssociateDomain) {\n onAssociateDomain(nftId, siteId, suiNSName)\n }\n }\n\n const handleRemoveAssociation = (nftId: string) => {\n if (onAssociateDomain) {\n onAssociateDomain(nftId, '', '')\n }\n }\n\n const formatExpiryDate = (timestamp?: number) => {\n if (!timestamp) return null\n return new Date(timestamp).toLocaleDateString('en-US', {\n month: 'short',\n day: '2-digit',\n year: 'numeric'\n })\n }\n\n return (\n <Dialog.Root open={isOpen} onOpenChange={isDomainDialogOpen.set}>\n <Dialog.Portal>\n <Dialog.Overlay className={styles.overlay} />\n <Dialog.Content className={styles.content}>\n {/* Loading Overlay */}\n {isAssigning && (\n <div\n style={{\n position: 'absolute',\n inset: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n backdropFilter: 'blur(4px)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 100,\n borderRadius: '0.75rem'\n }}\n >\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '0.75rem'\n }}\n >\n <Loader2\n style={{\n width: '2rem',\n height: '2rem',\n animation: 'spin 1s linear infinite',\n color: 'white'\n }}\n />\n <p style={{ fontSize: '0.875rem', color: 'white' }}>\n Updating domain association...\n </p>\n </div>\n </div>\n )}\n\n <div className={styles.header}>\n <Dialog.Title className={styles.title}>\n Customize Domain\n </Dialog.Title>\n <Dialog.Description className={styles.description}>\n Associate your website with a SuiNS domain for easy access\n </Dialog.Description>\n </div>\n\n <div className={styles.body}>\n {/* Currently Associated Domains */}\n <div className={styles.section}>\n <div className={styles.sectionTitle}>\n Currently Associated Domains\n </div>\n <div className={styles.domainList}>\n {/* Explorer - Always shown if siteId exists */}\n {explorerUrl && (\n <div className={styles.domainItem}>\n <div style={{ flex: 1, width: '100%' }}>\n <a\n href={explorerUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className={styles.link}\n style={{ fontSize: '0.875rem', fontWeight: 500 }}\n >\n Explorer\n <ExternalLink\n style={{\n display: 'inline',\n width: '0.75rem',\n height: '0.75rem',\n marginLeft: '0.25rem'\n }}\n />\n </a>\n <p\n style={{\n marginTop: '0.1rem',\n fontSize: '0.75rem',\n color: 'var(--muted-foreground)'\n }}\n >\n Sui Explorer\n </p>\n </div>\n </div>\n )}\n\n {/* SuiNS Domains - Show all linked domains from store */}\n {connectedDomains.length > 0 &&\n connectedDomains.map(domain => {\n const linkedEntry = suiNSUrlArray.find(\n entry => entry.nftId === domain.nftId\n )\n return (\n <div key={domain.nftId} className={styles.domainItem}>\n <div style={{ flex: 1, minWidth: 0 }}>\n <a\n href={\n suinsDomainToWalrusSiteUrl(\n linkedEntry?.suins || '',\n portalDomain,\n portalHttps\n ) || domain.walrusSiteUrl\n }\n target=\"_blank\"\n rel=\"noreferrer\"\n className={styles.link}\n style={{ fontSize: '0.875rem', fontWeight: 500 }}\n >\n @{domain.name}\n </a>\n <p\n style={{\n fontSize: '0.75rem',\n color: 'var(--muted-foreground)'\n }}\n >\n SuiNS Linked Domain\n </p>\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleRemoveAssociation(domain.nftId)}\n disabled={isAssigning}\n title=\"Remove domain association\"\n >\n <X style={{ width: '1rem', height: '1rem' }} />\n </Button>\n </div>\n )\n })}\n </div>\n </div>\n {/* Available Domains */}\n <div className={styles.section} style={{ marginTop: '0.5rem' }}>\n <div className={styles.sectionTitle}>\n <span>Select a domain to associate with your website</span>\n\n <Button\n size=\"sm\"\n type=\"button\"\n onClick={() => isRegisterSuiNSDomainDialogOpen.set(true)}\n >\n Buy a domain\n </Button>\n </div>\n\n {/* Loading state */}\n {isLoadingDomains && (\n <div className={styles.loadingSpinner}>\n <Loader2\n style={{\n width: '1.5rem',\n height: '1.5rem',\n animation: 'spin 1s linear infinite'\n }}\n />\n </div>\n )}\n\n {/* Error state */}\n {isErrorDomains && (\n <p\n style={{\n fontSize: '0.75rem',\n color: 'var(--destructive)',\n padding: '1rem 0'\n }}\n >\n Failed to load your domains. Please try again.\n </p>\n )}\n\n {/* Empty state */}\n {!isLoadingDomains && !isErrorDomains && !nsDomains.length && (\n <Banner\n title=\"You don't own any SuiNS domains yet.\"\n description=\"Buy a domain to continue.\"\n variant=\"warning\"\n />\n )}\n {/* Domain cards */}\n {!isLoadingDomains && !isErrorDomains && nsDomains.length > 0 && (\n <div className={styles.domainCardGrid}>\n {nsDomains.map(domain => {\n const isConnectedToThisSite = suiNSUrlArray.some(\n entry => entry.nftId === domain.nftId\n )\n\n return (\n <button\n key={domain.nftId}\n type=\"button\"\n className={styles.domainCard}\n onClick={() =>\n handleAssociate(domain.nftId, domain.name)\n }\n disabled={isConnectedToThisSite}\n title={\n isConnectedToThisSite\n ? 'Already connected to this site'\n : 'Click to connect'\n }\n >\n <div className={styles.domainCardBg}>\n <DomainCardSvg />\n </div>\n <div className={styles.domainName}>\n @{domain.name || 'Unknown'}\n </div>\n <div className={styles.domainExpiry}>\n {formatExpiryDate(domain.expirationTimestampMs)}\n </div>\n </button>\n )\n })}\n </div>\n )}\n </div>\n {/* Info Panel */}\n {network === 'testnet' && (\n <Banner\n title=\"You are publishing to the testnet\"\n description=\"You must run a local Walrus Site Portal to view published site.\"\n variant=\"info\"\n url=\"https://docs.wal.app/walrus-sites/portal.html\"\n urlName=\"Portal Documentation\"\n />\n )}\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n\n {/* Register SuiNS Dialog */}\n {signAndExecuteTransaction && (\n <RegisterSuiNsDialog\n isOpen={isRegisterSuiNSDomainDialog}\n onClose={() => isRegisterSuiNSDomainDialogOpen.set(false)}\n onRegistered={() => {\n // Invalidate domains query to refresh the list\n if (currentAccount?.address) {\n queryClient.invalidateQueries({\n queryKey: ['suins-domains', currentAccount.address, network]\n })\n }\n }}\n currentAccount={currentAccount}\n clients={{ suiClient, queryClient, suinsClient }}\n signAndExecuteTransaction={signAndExecuteTransaction}\n sponsorConfig={sponsorConfig}\n />\n )}\n </Dialog.Root>\n )\n}\n\nexport default SuiNsModal\n","import type { FC, ReactNode } from 'react'\nimport type { ThemeOverride } from '~/themes/themeContract'\n\ninterface ThemeProviderProps {\n children: ReactNode\n /**\n * Override default theme values for light and/or dark mode\n * @example\n * ```tsx\n * <ThemeProvider\n * themeOverrides={{\n * light: {\n * colors: { primary: '#ff0000' }\n * },\n * dark: {\n * colors: { primary: '#00ff00' }\n * }\n * }}\n * >\n * {children}\n * </ThemeProvider>\n * ```\n */\n themeOverrides?: ThemeOverride\n}\n\nexport const ThemeProvider: FC<ThemeProviderProps> = ({\n children,\n themeOverrides: _ // Currently unused\n}) => {\n return (\n <>\n {/* {themeOverrides && (\n <style\n // biome-ignore lint/security/noDangerouslySetInnerHtml: Required for dynamic theme overrides\n dangerouslySetInnerHTML={{\n __html: `\n :root, .light {\n ${getStaticThemeStyles(lightTheme)}\n }\n .dark {\n ${getStaticThemeStyles(darkTheme)}\n }\n `,\n }}\n />\n )} */}\n {children}\n </>\n )\n}\n\n// function getStaticThemeStyles(theme: ThemeVars) {\n// \treturn `${styleDataAttributeSelector} {${cssStringFromTheme(theme)}}`;\n// }\n\n// function cssStringFromTheme(theme: ThemeVars) {\n// \treturn Object.entries(assignInlineVars(themeVars, theme))\n// \t\t.map(([key, value]) => `${key}:${value};`)\n// \t\t.join('');\n// }\n","import type { FC, ReactNode } from 'react'\nimport {\n type UseSitePublishingParams,\n useSitePublishing\n} from '~/hooks/useSitePublishing'\nimport ExtendTimeDialog from './extend-time-dialog/ExtendTimeDialog'\nimport PublishMenu from './publish-menu/PublishMenu'\nimport PublishModal from './publish-modal/PublishModal'\nimport SuiNsModal from './suins-modal/SuiNsModal'\nimport { ThemeProvider } from './ThemeProvider'\nimport { Button } from './ui/Button'\n\ninterface Props extends UseSitePublishingParams {\n children?: ReactNode\n}\n\nconst PublishButton: FC<Props> = ({\n children,\n siteId,\n assets,\n onUpdateSiteMetadata,\n onAssociatedDomain,\n onError,\n onExtendedBlobs,\n currentAccount,\n signAndExecuteTransaction,\n sponsorConfig,\n portalDomain,\n portalHttps,\n clients\n}) => {\n const {\n actions: {\n handleOpenPublishingDialog,\n handleOpenDomainDialog,\n handleRunDeploymentStep,\n handleSaveSiteMetadata,\n handleAssociateDomain,\n handleExtendBlobs\n }\n } = useSitePublishing({\n siteId,\n assets,\n onUpdateSiteMetadata,\n onAssociatedDomain,\n onError,\n onExtendedBlobs,\n currentAccount,\n signAndExecuteTransaction,\n sponsorConfig,\n clients,\n portalDomain,\n portalHttps\n })\n const network = clients.suiClient.network\n\n return (\n <ThemeProvider>\n <PublishMenu\n siteId={siteId}\n onPublishClick={handleOpenPublishingDialog}\n onDomainClick={handleOpenDomainDialog}\n network={network === 'mainnet' ? 'mainnet' : 'testnet'}\n portalDomain={portalDomain}\n portalHttps={portalHttps}\n clients={clients}\n currentAccount={currentAccount}\n >\n {children || <Button>Publish</Button>}\n </PublishMenu>\n <PublishModal\n siteId={siteId}\n assets={assets}\n onDeploy={handleRunDeploymentStep}\n onSaveMetadata={handleSaveSiteMetadata}\n onExtendBlobs={handleExtendBlobs}\n clients={clients}\n />\n <SuiNsModal\n siteId={siteId}\n onAssociateDomain={handleAssociateDomain}\n currentAccount={currentAccount}\n portalDomain={portalDomain}\n portalHttps={portalHttps}\n clients={clients}\n signAndExecuteTransaction={signAndExecuteTransaction}\n sponsorConfig={sponsorConfig}\n />\n <ExtendTimeDialog\n siteId={siteId}\n currentAccount={currentAccount}\n clients={clients}\n signAndExecuteTransaction={signAndExecuteTransaction}\n sponsorConfig={sponsorConfig}\n onSuccess={(message, digest) => {\n onExtendedBlobs?.(message, digest)\n }}\n />\n </ThemeProvider>\n )\n}\n\nexport default PublishButton\n","import { keyframes, style } from '@vanilla-extract/css'\nimport { themeVars } from '~/theme.css'\n\nconst spin = keyframes({\n '0%': { transform: 'rotate(0deg)' },\n '100%': { transform: 'rotate(360deg)' }\n})\n\nexport const overlay = style({\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n position: 'fixed',\n inset: 0,\n zIndex: 50,\n animation: 'fadeIn 150ms ease-in-out'\n})\n\nexport const content = style({\n backgroundColor: themeVars.colors.background,\n borderRadius: themeVars.radius.lg,\n boxShadow:\n '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n width: '90vw',\n maxWidth: '32rem',\n maxHeight: '90vh',\n overflow: 'auto',\n zIndex: 51,\n animation: 'slideIn 200ms ease-in-out',\n border: `1px solid ${themeVars.colors.border}`,\n padding: 0,\n display: 'flex',\n flexDirection: 'column'\n})\n\nexport const header = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.xs,\n padding: themeVars.spacing.md,\n borderBottom: `1px solid ${themeVars.colors.border}`,\n position: 'relative'\n})\n\nexport const title = style({\n fontSize: '1.125rem',\n fontWeight: 600,\n color: themeVars.colors.foreground,\n margin: 0\n})\n\nexport const description = style({\n fontSize: '0.875rem',\n color: themeVars.colors.mutedForeground,\n margin: 0\n})\n\nexport const closeButton = style({\n position: 'absolute',\n top: themeVars.spacing.md,\n right: themeVars.spacing.md,\n padding: '0.25rem',\n cursor: 'pointer',\n border: 'none',\n background: 'transparent',\n color: themeVars.colors.foreground,\n borderRadius: '0.5rem',\n transition: 'background-color 0.2s',\n ':hover': {\n backgroundColor: themeVars.colors.muted\n }\n})\n\nexport const body = style({\n padding: themeVars.spacing.md,\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.md,\n flex: 1,\n overflowY: 'auto'\n})\n\nexport const loadingContainer = style({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: themeVars.spacing.md,\n padding: themeVars.spacing.xl,\n color: themeVars.colors.mutedForeground\n})\n\nexport const footer = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n gap: themeVars.spacing.sm,\n padding: themeVars.spacing.md,\n borderTop: `1px solid ${themeVars.colors.border}`,\n backgroundColor: 'rgba(var(--muted-rgb), 0.3)'\n})\n\nexport const fieldLabel = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: themeVars.spacing.xs\n})\n\nexport const charCount = style({\n fontSize: '0.75rem',\n color: themeVars.colors.mutedForeground\n})\n\nexport const optionalLabel = style({\n fontSize: '0.75rem',\n color: themeVars.colors.mutedForeground,\n fontWeight: 'normal'\n})\n\nexport const uploadModeToggle = style({\n display: 'flex',\n gap: '0.5rem',\n marginBottom: themeVars.spacing.md,\n padding: '0.25rem',\n backgroundColor: themeVars.colors.muted,\n borderRadius: '0.5rem'\n})\n\nexport const uploadModeButton = style({\n flex: 1,\n padding: '0.5rem 1rem',\n fontSize: '0.875rem',\n fontWeight: 500,\n border: 'none',\n borderRadius: '0.375rem',\n cursor: 'pointer',\n transition: 'all 0.2s',\n backgroundColor: 'transparent',\n color: themeVars.colors.mutedForeground\n})\n\nexport const uploadModeButtonActive = style({\n flex: 1,\n padding: '0.5rem 1rem',\n fontSize: '0.875rem',\n fontWeight: 500,\n border: 'none',\n borderRadius: '0.375rem',\n cursor: 'pointer',\n transition: 'all 0.2s',\n backgroundColor: themeVars.colors.background,\n color: themeVars.colors.foreground,\n boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)'\n})\n\nexport const uploadArea = style({\n border: `2px dashed ${themeVars.colors.border}`,\n borderRadius: themeVars.radius.lg,\n aspectRatio: '1 / 1',\n width: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n transition: 'background-color 0.2s',\n overflow: 'hidden',\n position: 'relative',\n ':hover': {\n backgroundColor: 'rgba(var(--muted-rgb), 0.5)'\n }\n})\n\nexport const uploadPlaceholder = style({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: themeVars.spacing.sm,\n padding: themeVars.spacing.lg,\n color: themeVars.colors.mutedForeground\n})\n\nexport const uploadHint = style({\n fontSize: '0.875rem',\n marginTop: '0.25rem'\n})\n\nexport const previewImage = style({\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n borderRadius: themeVars.radius.lg\n})\n\nexport const urlInputContainer = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.md\n})\n\nexport const imagePreview = style({\n width: '100%',\n aspectRatio: '1',\n borderRadius: themeVars.radius.lg,\n overflow: 'hidden',\n border: `1px solid ${themeVars.colors.border}`\n})\n\nexport const urlInputWrapper = style({\n display: 'flex',\n gap: '0.5rem'\n})\n\nexport const errorText = style({\n fontSize: '0.75rem',\n color: themeVars.colors.destructive,\n marginTop: '0.5rem',\n display: 'flex',\n alignItems: 'center',\n gap: '0.25rem'\n})\n\nexport const errorBanner = style({\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem',\n padding: themeVars.spacing.sm,\n backgroundColor: 'rgba(var(--destructive-rgb), 0.1)',\n border: `1px solid ${themeVars.colors.destructive}`,\n borderRadius: themeVars.radius.md,\n color: themeVars.colors.destructive,\n fontSize: '0.875rem'\n})\n\nexport const warningBanner = style({\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem',\n padding: themeVars.spacing.sm,\n backgroundColor: 'rgba(251, 191, 36, 0.1)',\n border: '1px solid rgb(251, 191, 36)',\n borderRadius: themeVars.radius.md,\n color: 'rgb(251, 191, 36)',\n fontSize: '0.875rem'\n})\n\nexport const spinner = style({\n animation: `${spin} 1s linear infinite`\n})\n","import type { SuiClient } from '@mysten/sui/client'\nimport type { WalrusClient } from '@mysten/walrus'\nimport * as Dialog from '@radix-ui/react-dialog'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { Info, Loader2, Upload, X } from 'lucide-react'\nimport type { FC } from 'react'\nimport { useEffect, useRef, useState } from 'react'\nimport {\n type UseUpdateSiteMetadataParams,\n useUpdateSiteMetadata\n} from '~/hooks/useUpdateSiteMetadata'\nimport { useWalrusSiteQuery } from '~/queries'\nimport { Button } from '../ui/Button'\nimport { Input, Label, Textarea } from '../ui/Input'\nimport * as styles from './UpdateMetadataModal.css'\n\n/**\n * Props for the UpdateMetadataModal component.\n *\n * @example\n * ```tsx\n * <UpdateMetadataModal\n * siteId=\"0x123...\"\n * isOpen={isOpen}\n * onOpenChange={setIsOpen}\n * clients={{ suiClient, queryClient, walrusClient }}\n * currentAccount={currentAccount}\n * signAndExecuteTransaction={signAndExecuteTransaction}\n * />\n * ```\n */\ninterface UpdateMetadataModalProps {\n /** The object ID of the published Walrus site to update */\n siteId: string\n /** Controls the visibility of the modal */\n isOpen: boolean\n /** Callback when modal open state changes */\n onOpenChange: (open: boolean) => void\n /** Optional callback when metadata update succeeds. Receives the transaction digest. */\n onSuccess?: (digest: string) => void\n /** Optional callback when metadata update fails. Receives the error object. */\n onError?: (error: Error) => void\n /** Object containing Sui, Query, and Walrus clients */\n clients: {\n /** Sui blockchain client for on-chain operations */\n suiClient: SuiClient\n /** React Query client for data fetching and caching */\n queryClient: QueryClient\n /** Walrus storage client for blob operations */\n walrusClient: WalrusClient\n }\n /** Current connected wallet account. Must be non-null to submit updates. */\n currentAccount: UseUpdateSiteMetadataParams['currentAccount']\n /** Function to sign and execute transactions on the Sui blockchain */\n signAndExecuteTransaction: UseUpdateSiteMetadataParams['signAndExecuteTransaction']\n /** Optional transaction sponsorship configuration */\n sponsorConfig?: UseUpdateSiteMetadataParams['sponsorConfig']\n}\n\n/**\n * UpdateMetadataModal Component\n *\n * A modal dialog component for updating metadata (name, description, project URL, preview image)\n * of an existing Walrus site on the Sui blockchain.\n *\n * ## Features\n * - Updates site name (max 120 chars), description (max 150 chars), project URL, and preview image\n * - Supports image upload (max 5MB) or URL input\n * - Validates wallet connection before allowing submission\n * - Automatically loads current site metadata when opened\n * - Shows loading states and error messages\n *\n * ## Usage\n *\n * ```tsx\n * import { UpdateMetadataModal, isUpdateMetadataModalOpen } from '@cmdoss/walrus-site-builder-react'\n * import { useStore } from '@nanostores/react'\n *\n * function MyComponent() {\n * const isOpen = useStore(isUpdateMetadataModalOpen)\n *\n * return (\n * <UpdateMetadataModal\n * siteId=\"0x123...\"\n * isOpen={isOpen}\n * onOpenChange={isUpdateMetadataModalOpen.set}\n * onSuccess={(digest) => console.log('Updated:', digest)}\n * clients={{ suiClient, queryClient, walrusClient }}\n * currentAccount={currentAccount}\n * signAndExecuteTransaction={signAndExecuteTransaction}\n * />\n * )\n * }\n * ```\n *\n * ## State Management\n *\n * The modal visibility is typically controlled via the `isUpdateMetadataModalOpen` atom:\n *\n * ```tsx\n * import { isUpdateMetadataModalOpen } from '@cmdoss/walrus-site-builder-react'\n *\n * // Open modal\n * isUpdateMetadataModalOpen.set(true)\n *\n * // Close modal\n * isUpdateMetadataModalOpen.set(false)\n * ```\n *\n * @see {@link useUpdateSiteMetadata} - The hook used internally for metadata updates\n * @see {@link useWalrusSiteQuery} - Used to fetch current site data\n */\n\nconst UpdateMetadataModal: FC<UpdateMetadataModalProps> = ({\n siteId,\n isOpen,\n onOpenChange,\n onSuccess,\n onError,\n clients: { suiClient, queryClient, walrusClient },\n currentAccount,\n signAndExecuteTransaction,\n sponsorConfig\n}) => {\n const [siteName, setSiteName] = useState('')\n const [description, setDescription] = useState('')\n const [projectUrl, setProjectUrl] = useState('')\n const [imageUrl, setImageUrl] = useState('')\n const [uploadMode, setUploadMode] = useState<'file' | 'url'>('url')\n const [urlInput, setUrlInput] = useState('')\n const [urlError, setUrlError] = useState('')\n const [fileSizeError, setFileSizeError] = useState('')\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n const MAX_FILE_SIZE = 5 * 1024 * 1024 // 5MB\n\n // Get current site data\n const { data: siteData, isLoading: isLoadingSite } = useWalrusSiteQuery(\n siteId,\n {\n suiClient,\n queryClient\n }\n )\n\n // Update metadata hook\n const { updateSiteMetadata, isUpdating, error } = useUpdateSiteMetadata({\n siteId,\n clients: {\n suiClient,\n queryClient,\n walrusClient\n },\n currentAccount,\n signAndExecuteTransaction,\n sponsorConfig\n })\n\n // Check if SDK is ready\n const isSdkReady = !!currentAccount && !!suiClient && !!walrusClient\n\n // Populate form with current site data\n useEffect(() => {\n if (siteData && isOpen) {\n setSiteName(siteData.name || '')\n setDescription(siteData.description || '')\n setProjectUrl(siteData.project_url || '')\n setImageUrl(siteData.image_url || '')\n setUrlInput(siteData.image_url || '')\n }\n }, [siteData, isOpen])\n\n // Reset form when modal closes\n useEffect(() => {\n if (!isOpen) {\n setUrlError('')\n setFileSizeError('')\n setUploadMode('url')\n }\n }, [isOpen])\n\n // Handle image file upload\n const handleImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file) return\n\n if (file.size > MAX_FILE_SIZE) {\n setFileSizeError(\n `File size exceeds 5MB limit (${(file.size / 1024 / 1024).toFixed(2)}MB)`\n )\n e.target.value = ''\n return\n }\n\n setFileSizeError('')\n const reader = new FileReader()\n reader.onload = e => {\n const result = e.target?.result\n if (typeof result === 'string') {\n setImageUrl(result)\n }\n }\n reader.readAsDataURL(file)\n }\n\n // Handle URL submit\n const handleUrlSubmit = () => {\n if (!urlInput.trim()) {\n setUrlError('Please enter a valid URL')\n return\n }\n\n try {\n new URL(urlInput)\n setImageUrl(urlInput)\n setUrlError('')\n } catch {\n setUrlError('Please enter a valid URL')\n }\n }\n\n // Handle form submission\n const handleSubmit = async () => {\n if (!isSdkReady) {\n const error = new Error(\n 'Wallet not connected. Please connect your wallet first.'\n )\n onError?.(error)\n return\n }\n\n try {\n const digest = await updateSiteMetadata({\n siteName,\n metadata: {\n description: description || undefined,\n project_url: projectUrl || undefined,\n image_url: imageUrl || undefined\n }\n })\n onSuccess?.(digest)\n onOpenChange(false)\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Unknown error')\n onError?.(error)\n }\n }\n\n // Check if form has changes\n const hasChanges =\n siteName !== (siteData?.name || '') ||\n description !== (siteData?.description || '') ||\n projectUrl !== (siteData?.project_url || '') ||\n imageUrl !== (siteData?.image_url || '')\n\n const isLoading = isLoadingSite || isUpdating\n\n return (\n <Dialog.Root open={isOpen} onOpenChange={onOpenChange}>\n <Dialog.Portal>\n <Dialog.Overlay className={styles.overlay} />\n <Dialog.Content className={styles.content}>\n <div className={styles.header}>\n <Dialog.Title className={styles.title}>\n Update Site Metadata\n </Dialog.Title>\n <Dialog.Description className={styles.description}>\n Update the metadata for your site\n </Dialog.Description>\n <Dialog.Close asChild>\n <button type=\"button\" className={styles.closeButton}>\n <X size={20} />\n </button>\n </Dialog.Close>\n </div>\n\n {isLoadingSite ? (\n <div className={styles.loadingContainer}>\n <Loader2 size={24} className={styles.spinner} />\n <p>Loading site data...</p>\n </div>\n ) : (\n <div className={styles.body}>\n {/* Image URL */}\n <fieldset>\n <div className={styles.fieldLabel}>\n <Label>Preview Image</Label>\n <span className={styles.optionalLabel}>Max 5MB</span>\n </div>\n\n {/* Upload Mode Toggle */}\n <div className={styles.uploadModeToggle}>\n <button\n type=\"button\"\n onClick={() => {\n setUploadMode('file')\n setUrlError('')\n }}\n className={\n uploadMode === 'file'\n ? styles.uploadModeButtonActive\n : styles.uploadModeButton\n }\n >\n Upload File\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setUploadMode('url')\n setFileSizeError('')\n }}\n className={\n uploadMode === 'url'\n ? styles.uploadModeButtonActive\n : styles.uploadModeButton\n }\n >\n From URL\n </button>\n </div>\n\n {uploadMode === 'file' ? (\n <>\n <div\n className={styles.uploadArea}\n onClick={() =>\n !isUpdating && fileInputRef.current?.click()\n }\n style={{\n cursor: isUpdating ? 'wait' : 'pointer',\n opacity: isUpdating ? 0.6 : 1\n }}\n >\n {imageUrl ? (\n <img\n src={imageUrl}\n alt=\"Preview\"\n className={styles.previewImage}\n />\n ) : (\n <div className={styles.uploadPlaceholder}>\n <Upload size={32} />\n <p>Click to upload</p>\n <p className={styles.uploadHint}>\n Square image recommended\n </p>\n </div>\n )}\n </div>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleImageChange}\n style={{ display: 'none' }}\n />\n {fileSizeError && (\n <p className={styles.errorText}>\n <Info size={14} />\n {fileSizeError}\n </p>\n )}\n </>\n ) : (\n <div className={styles.urlInputContainer}>\n {imageUrl && (\n <div className={styles.imagePreview}>\n <img\n src={imageUrl}\n alt=\"Preview\"\n className={styles.previewImage}\n />\n </div>\n )}\n <div className={styles.urlInputWrapper}>\n <Input\n value={urlInput}\n onChange={e => {\n setUrlInput(e.target.value)\n setUrlError('')\n }}\n onKeyDown={e => {\n if (e.key === 'Enter') {\n handleUrlSubmit()\n }\n }}\n placeholder=\"https://example.com/image.png\"\n disabled={isUpdating}\n />\n <Button\n onClick={handleUrlSubmit}\n disabled={isUpdating}\n style={{ flexShrink: 0 }}\n >\n Apply\n </Button>\n </div>\n {urlError && (\n <p className={styles.errorText}>\n <Info size={14} />\n {urlError}\n </p>\n )}\n </div>\n )}\n </fieldset>\n {/* Site Name */}\n <fieldset>\n <div className={styles.fieldLabel}>\n <Label>Site Name</Label>\n <span className={styles.charCount}>\n {siteName.length}/120\n </span>\n </div>\n <Input\n value={siteName}\n onChange={e => setSiteName(e.target.value.slice(0, 120))}\n placeholder=\"Enter site name...\"\n disabled={isUpdating}\n />\n </fieldset>\n\n {/* Description */}\n <fieldset>\n <div className={styles.fieldLabel}>\n <Label>Description</Label>\n <span className={styles.charCount}>\n {description.length}/150\n </span>\n </div>\n <Textarea\n value={description}\n onChange={e => setDescription(e.target.value.slice(0, 150))}\n placeholder=\"Enter description...\"\n rows={4}\n disabled={isUpdating}\n />\n </fieldset>\n\n {/* Project URL */}\n <fieldset>\n <Label>\n Project URL\n <span className={styles.optionalLabel}> (Optional)</span>\n </Label>\n <Input\n value={projectUrl}\n onChange={e => setProjectUrl(e.target.value)}\n placeholder=\"https://github.com/username/project\"\n disabled={isUpdating}\n />\n </fieldset>\n\n {!isSdkReady && (\n <div className={styles.warningBanner}>\n <Info size={16} />\n <span>Please connect your wallet to update metadata</span>\n </div>\n )}\n {error && (\n <div className={styles.errorBanner}>\n <Info size={16} />\n <span>Failed to update metadata: {error.message}</span>\n </div>\n )}\n </div>\n )}\n\n <div className={styles.footer}>\n <Button\n variant=\"outline\"\n onClick={() => onOpenChange(false)}\n disabled={isUpdating}\n >\n Cancel\n </Button>\n <Button\n onClick={handleSubmit}\n disabled={!hasChanges || isLoading || !isSdkReady}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem'\n }}\n >\n {isUpdating && <Loader2 size={16} className={styles.spinner} />}\n {isUpdating\n ? 'Updating...'\n : !isSdkReady\n ? 'Connect Wallet'\n : 'Update Metadata'}\n </Button>\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n )\n}\n\nexport default UpdateMetadataModal\n"],"x_google_ignoreList":[16,17,18,19,20],"mappings":"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AU;SACV,YAAY;SACZ,cAAc;SACd,OAAO;SACR;kBACF;SAEI,EACL,qBAAC;QACC,OAAO;SACL,SAAS;SACT,eAAe;SACf,KAAK;SACN;;SAED,qBAAC;UACC,OAAO;WACL,SAAS;WACT,gBAAgB;WAChB,YAAY;WACb;qBAED,oBAAC;WACC,OAAO;YACL,UAAU;YACV,OAAO;YACR;qBACF;YAEM,EACP,qBAAC;WACC,OAAO;YACL,SAAS;YACT,eAAe;YACf,YAAY;YACZ,KAAK;YACN;sBAED,oBAAC;YACC,OAAO;aACL,UAAU;aACV,YAAY;aACZ,OAAO;aACR;sBAEA,yBAAyB;aACrB,EACN,aAAa,oBACZ,qBAAC;YACC,OAAO;aACL,UAAU;aACV,OAAO;aACP,SAAS;aACV;;aACF;aACG;aAAiB;;aACd;YAEL;WACF;SACN,qBAAC;UACC,OAAO;WACL,SAAS;WACT,gBAAgB;WAChB,YAAY;WACb;qBAED,oBAAC;WACC,OAAO;YACL,UAAU;YACV,OAAO;YACR;qBACF;YAEM,EACP,oBAAC;WACC,OAAO;YACL,UAAU;YACV,YAAY;YACZ,OAAO;YACR;qBAEA;YACI;WACH;SACN,oBAAC,SACC,OAAO;UACL,QAAQ;UACR,iBAAiB;UACjB,QAAQ;UACT,GACD;SACF,qBAAC;UACC,OAAO;WACL,SAAS;WACT,gBAAgB;WAChB,YAAY;WACb;qBAED,oBAAC;WACC,OAAO;YACL,UAAU;YACV,YAAY;YACZ,OAAO;YACR;qBACF;YAEM,EACP,qBAAC;WACC,OAAO;YACL,SAAS;YACT,eAAe;YACf,YAAY;YACZ,KAAK;YACN;sBAED,oBAAC;YACC,OAAO;aACL,UAAU;aACV,YAAY;aACZ,OAAO;aACR;sBAEA,uBAAuB;aACnB,EACN,aAAa,kBACZ,qBAAC;YACC,OAAO;aACL,UAAU;aACV,OAAO;aACP,SAAS;aACV;;aACF;aACG;aAAe;;aACZ;YAEL;WACF;SACL,kBACC,oBAAC;UACC,OAAO;WACL,WAAW;WACX,YAAY;WACZ,WAAW;WACZ;oBAED,qBAAC;WACC,OAAO;YACL,SAAS;YACT,gBAAgB;YAChB,YA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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["allDomains: SuiNsDomain[]","cursor: string | null | undefined","mainPackage","domains","content","dynamicFields: DynamicFieldInfo[]","cursor: string | null","resources: ResourceData[]","result: ResourceData","assets: IAsset[]","content","title","description","link","item","sdk: IWalrusSiteBuilderSdk | undefined","title","link","description","siteMetadata: SiteMetadata","siteId","cursor: string | null | undefined","error","pricePerYear","totalPrice","paymentCoin:\n | ReturnType<typeof transaction.object>\n | typeof transaction.gas","registerParams: {\n domain: string\n years: number\n coinConfig: typeof coinConfig\n coin: typeof paymentCoin\n priceInfoObjectId?: string\n }","r","input","r","input","defaultIcons: Record<BannerVariant, ReactNode>","Banner: FC<BannerProps>","content","title","description","link","closeButton","Button: FC<ButtonProps>","FlickeringGrid: FC<FlickeringGridProps>","color","width","height","container","animationFrameId: number","gridParams: ReturnType<typeof setupCanvas>","Label: FC<LabelProps>","labelStyle","Textarea: FC<TextareaProps>","textareaStyle","Step: FC<StepProps>","styles.stepContainer","styles.stepIndicator","styles.stepIndicatorCompleted","styles.stepIndicatorActive","styles.stepIndicatorPending","styles.stepSpinner","styles.stepDot","styles.stepLine","styles.stepLineCompleted","styles.stepLinePending","styles.stepLabel","styles.stepLabelActive","styles.stepLabelInactive","title","Stepper: FC<StepperProps>","styles.stepperContainer","styles.stepperWrapper","ExtendTimeDialog: FC<ExtendTimeDialogProps>","cursor: string | null | undefined","styles.overlay","styles.content","styles.loadingOverlay","styles.loadingContent","styles.spinner","styles.header","styles.title","styles.description","styles.closeButton","styles.body","styles.formSection","styles.fieldGroup","styles.dateInputWrapper","styles.inputError","styles.infoText","styles.errorText","styles.summaryGrid","styles.summaryCard","styles.summaryHeader","styles.summaryContent","styles.summaryValue","styles.summarySubtext","styles.summaryError","styles.costSection","styles.costHeader","styles.estimatedBadge","styles.costContent","styles.costRow","styles.costLabel","styles.costValue","styles.costLoading","styles.costWarning","styles.costDivider","styles.costError","styles.footer","PublishMenu: FC<PublishMenuProps>","styles.content","styles.header","styles.title","styles.description","styles.link","styles.separator","styles.item","styles.footer","styles.buttonGroup","PublishModal: FC<PublishModalProps>","title","description","selectedDate","styles.overlay","styles.content","styles.title","styles.description","styles.twoColumnSection","styles.leftColumn","styles.previewContainer","styles.previewArea","styles.previewImageWrapper","styles.previewImage","styles.flickeringGrid","styles.maskLayer","styles.placeholderContent","styles.placeholderIcon","styles.editButton","styles.storageCostSection","styles.storageCostSummary","styles.storageCostLabel","styles.storageCostValue","styles.storageDetailsBox","styles.rightColumn","styles.metadataFields","styles.dialogRightColumn","styles.fieldLabel","styles.charCount","styles.section","styles.buttonGroup","styles.spinner","styles.dialogOverlay","styles.dialogContent","styles.dialogHeader","styles.dialogBodyTwoColumn","styles.uploadAreaSquare","styles.uploadPlaceholder","styles.dialogFooter","CardBackground: FC","SuiNSLogo: FC","DomainCardSvg: FC<DomainCardSvgProps>","RegisterSuiNsDialog: FC<RegisterSuiNsDialogProps>","styles.overlay","styles.content","styles.header","styles.title","styles.description","styles.body","SuiNsModal: FC<SuiNsModalProps>","styles.overlay","styles.content","styles.header","styles.title","styles.description","styles.body","styles.section","styles.sectionTitle","styles.domainList","styles.domainItem","styles.link","styles.loadingSpinner","styles.domainCardGrid","styles.domainCard","styles.domainCardBg","DomainCardSvg","styles.domainName","styles.domainExpiry","ThemeProvider: FC<ThemeProviderProps>","UpdateMetadataModal: FC<UpdateMetadataModalProps>","description","e","error","styles.overlay","styles.content","styles.header","styles.title","styles.description","styles.closeButton","styles.loadingContainer","styles.spinner","styles.body","styles.fieldLabel","styles.optionalLabel","styles.uploadModeToggle","styles.uploadModeButtonActive","styles.uploadModeButton","styles.uploadArea","styles.previewImage","styles.uploadPlaceholder","styles.uploadHint","styles.errorText","styles.urlInputContainer","styles.imagePreview","styles.urlInputWrapper","styles.charCount","styles.warningBanner","styles.errorBanner","styles.footer","PublishButton: FC<Props>","PublishMenu","PublishModal","SuiNsModal","ExtendTimeDialog","UpdateMetadataModal"],"sources":["../src/lib/nonNull.ts","../src/queries/keys.ts","../src/queries/suins-domains.query.ts","../src/queries/walrus-site.query.ts","../src/queries/zenfs-files.query.ts","../src/stores/site-domain.store.ts","../src/stores/site-metadata.store.ts","../src/lib/result.ts","../src/stores/site-publishing.store.ts","../src/hooks/useTransactionExecutor.ts","../src/hooks/useSitePublishing.ts","../src/hooks/useEpochDuration.ts","../src/hooks/useSuiNsRegistration.ts","../src/hooks/useUpdateSiteMetadata.ts","../src/hooks/useZenFsWorkspace.ts","../src/queries/storage-cost.query.ts","../../../node_modules/.pnpm/@vanilla-extract+recipes@0.5.7_@vanilla-extract+css@1.18.0/node_modules/@vanilla-extract/recipes/dist/createRuntimeFn-166334d7.cjs.prod.js","../../../node_modules/.pnpm/@vanilla-extract+recipes@0.5.7_@vanilla-extract+css@1.18.0/node_modules/@vanilla-extract/recipes/createRuntimeFn/dist/vanilla-extract-recipes-createRuntimeFn.cjs.prod.js","../../../node_modules/.pnpm/@vanilla-extract+recipes@0.5.7_@vanilla-extract+css@1.18.0/node_modules/@vanilla-extract/recipes/dist/createRuntimeFn-2f250aaf.cjs.dev.js","../../../node_modules/.pnpm/@vanilla-extract+recipes@0.5.7_@vanilla-extract+css@1.18.0/node_modules/@vanilla-extract/recipes/createRuntimeFn/dist/vanilla-extract-recipes-createRuntimeFn.cjs.dev.js","../../../node_modules/.pnpm/@vanilla-extract+recipes@0.5.7_@vanilla-extract+css@1.18.0/node_modules/@vanilla-extract/recipes/createRuntimeFn/dist/vanilla-extract-recipes-createRuntimeFn.cjs.js","../src/components/ui/Banner.css.ts","../src/components/ui/Banner.tsx","../src/components/ui/Button.css.ts","../src/components/ui/Button.tsx","../src/components/ui/FlickeringGrid.css.ts","../src/components/ui/FlickeringGrid.tsx","../src/components/ui/Input.css.ts","../src/components/ui/Input.tsx","../src/components/ui/Stepper.css.ts","../src/components/ui/Stepper.tsx","../src/components/extend-time-dialog/ExtendTimeDialog.css.ts","../src/components/extend-time-dialog/ExtendTimeDialog.tsx","../src/components/publish-menu/PublishMenu.css.ts","../src/components/publish-menu/PublishMenu.tsx","../src/components/publish-modal/PublishModal.css.ts","../src/components/publish-modal/PublishModal.tsx","../src/components/suins-modal/DomainCardSvg.tsx","../src/components/suins-modal/SuiNsModal.css.ts","../src/components/suins-modal/RegisterSuiNsDialog.tsx","../src/components/suins-modal/SuiNsModal.tsx","../src/components/ThemeProvider.tsx","../src/components/update-metadata-modal/UpdateMetadataModal.css.ts","../src/components/update-metadata-modal/UpdateMetadataModal.tsx","../src/components/PublishButton.tsx"],"sourcesContent":["export function nonNull<T>(value: T | null | undefined): value is T {\n return value !== null && value !== undefined\n}\n","export const queryKeys = {\n suinsDomains: (address: string | undefined, network: string) =>\n ['suins-domains', address, network] as const,\n suinsDomainDetail: (name: string, network: string) =>\n ['suins-domain-detail', name, network] as const,\n walrusSite: (siteId: string | undefined) => ['walrus-site', siteId] as const,\n walrusSites: (address: string | undefined, network: string) =>\n ['walrus-sites', address, network] as const,\n storageCost: (fileSize: number | null, epochs: number) =>\n ['storage-cost', fileSize, epochs] as const\n} as const\n","import type { SuiClient } from '@mysten/sui/client'\nimport { mainPackage, SuinsClient } from '@mysten/suins'\nimport type { WalletAccount } from '@mysten/wallet-standard'\nimport { type QueryClient, useQueries, useQuery } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { nonNull } from '~/lib/nonNull'\nimport { queryKeys } from './keys'\n\nexport type SuiNsDomain = {\n name: string\n objectId: string\n expiresAt?: number\n}\n\nexport interface SuiNsDomainDetail {\n name: string\n avatar?: string\n expirationTimestampMs?: number\n nftId: string\n walrusSiteId?: string\n targetAddress?: string\n walrusSiteUrl: string\n}\n\nexport interface ISuiNsDomainQuery {\n isLoading: boolean\n isError: boolean\n data: Array<SuiNsDomainDetail>\n}\n\nexport function useSuiNsDomainsQuery(\n currentAccount: WalletAccount | null,\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n }\n): ISuiNsDomainQuery {\n const { suiClient, queryClient } = clients\n const { network } = suiClient\n const suinsClient = useMemo(\n () =>\n new SuinsClient({\n network: suiClient.network === 'mainnet' ? 'mainnet' : 'testnet',\n client: suiClient\n }),\n [suiClient]\n )\n\n const onchainDataQuery = useQuery(\n {\n queryKey: queryKeys.suinsDomains(currentAccount?.address, network),\n queryFn: async () => {\n if (!currentAccount?.address) return []\n\n try {\n let allDomains: SuiNsDomain[] = []\n let hasNextPage = true\n let cursor: string | null | undefined\n\n // Get the appropriate SuiNS package ID based on network\n const suinsPackageId =\n mainPackage[network as keyof typeof mainPackage]?.packageIdV1\n\n if (!suinsPackageId) {\n console.warn(`SuiNS not supported on network: ${network}`)\n return []\n }\n\n console.log('suinsPackageId', suinsPackageId)\n\n // Fetch all SuiNS domain NFTs owned by the address\n console.log(\n 'suinsPackageId',\n `${suinsPackageId}::suins_registration::SuinsRegistration`\n )\n while (hasNextPage) {\n const response = await suiClient.getOwnedObjects({\n owner: currentAccount.address,\n filter: {\n StructType: `${suinsPackageId}::suins_registration::SuinsRegistration`\n },\n options: { showContent: true, showType: true, showDisplay: true },\n cursor\n })\n\n console.log('response', response)\n\n // Extract domain data from the response\n const domains = response.data\n .filter(obj => obj.data?.content?.dataType === 'moveObject')\n .map(obj => {\n const content = obj.data?.content\n const fields =\n content && 'fields' in content\n ? (content.fields as Record<string, unknown>)\n : {}\n\n return {\n name: (fields?.domain_name as string) || '',\n objectId: obj.data?.objectId || '',\n expiresAt: fields?.expiration_timestamp_ms\n ? Number(fields.expiration_timestamp_ms)\n : undefined\n }\n })\n .filter(domain => domain.name) // Filter out any invalid entries\n\n allDomains = [...allDomains, ...domains]\n hasNextPage = response.hasNextPage\n cursor = response.nextCursor\n }\n\n return allDomains\n } catch (error) {\n console.error('Error fetching SuiNS domains:', error)\n return []\n }\n },\n enabled: !!currentAccount?.address,\n staleTime: 1000 * 60 * 5, // 5 minutes\n retry: 2,\n retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, 30000)\n },\n queryClient\n )\n\n // TODO: improve this with batching if supported by SuinsClient\n const domains = useQueries(\n {\n queries:\n onchainDataQuery.data?.map(domain => ({\n queryKey: queryKeys.suinsDomainDetail(domain.name, network),\n queryFn: async () => await suinsClient?.getNameRecord(domain.name),\n enabled: !!suinsClient && !!domain.name\n })) ?? []\n },\n queryClient\n )\n\n const isLoading = useMemo(\n () => onchainDataQuery.isLoading || domains.some(d => d.isLoading),\n [onchainDataQuery.isLoading, domains]\n )\n const isError = useMemo(\n () => onchainDataQuery.isError || domains.some(d => d.isError),\n [onchainDataQuery.isError, domains]\n )\n const data = useMemo(\n () =>\n domains\n .map(d => d.data)\n .filter(nonNull)\n .map(\n r =>\n <SuiNsDomainDetail>{\n name: r.name.slice(0, -4), // remove \".sui\" suffix\n avatar: r.avatar,\n expirationTimestampMs: Number(r.expirationTimestampMs),\n nftId: r.nftId,\n walrusSiteId: r.walrusSiteId,\n targetAddr: r.targetAddress,\n walrusSiteUrl:\n network === 'mainnet'\n ? `https://${r.name.slice(0, -4)}.wal.app`\n : `http://${r.name.slice(0, -4)}.localhost:3003`\n }\n ),\n [domains, network]\n )\n\n return { isLoading, isError, data }\n}\n","import { mainPackage } from '@cmdoss/walrus-site-builder'\nimport type {\n DynamicFieldInfo,\n ObjectResponseError,\n SuiClient\n} from '@mysten/sui/client'\nimport { type QueryClient, useQuery } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { queryKeys } from './keys'\n\ninterface WalrusSiteDisplayData {\n creator: string\n description: string\n image_url: string\n link: string\n project_url: string\n name: string\n}\n\ninterface ResourceChainValue {\n type: string\n fields: {\n blob_hash: string\n blob_id: string\n headers: {\n type: string\n fields: {\n contents: Array<{\n type: string\n fields: {\n key: string\n value: string\n }\n }>\n }\n }\n path: string\n range: null | unknown\n }\n}\n\ninterface ResourceData {\n blob_hash: string\n blob_id: string\n headers: { key: string; value: string }[]\n path: string\n // range: null | unknown // Not used currently\n}\n\ninterface WalrusSiteData extends WalrusSiteDisplayData {\n id: string\n resources: ResourceData[]\n}\n\nfunction handleError(error: ObjectResponseError): never {\n switch (error.code) {\n case 'deleted':\n throw new Error('Walrus site has been deleted')\n case 'notExists':\n throw new Error('Walrus site does not exist')\n case 'displayError':\n throw new Error('Failed to fetch Walrus site display data')\n case 'dynamicFieldNotFound':\n throw new Error('Walrus site dynamic field not found')\n default:\n throw new Error(`Unknown error when fetching Walrus site!`)\n }\n}\n\nasync function fetchSiteDynamicFields(\n suiClient: SuiClient,\n siteId: string\n): Promise<DynamicFieldInfo[]> {\n const dynamicFields: DynamicFieldInfo[] = []\n let cursor: string | null = null\n while (true) {\n const page = await suiClient.getDynamicFields({ parentId: siteId, cursor })\n cursor = page.nextCursor\n dynamicFields.push(...page.data)\n if (!page.hasNextPage) break\n }\n return dynamicFields\n}\n\nasync function fetchSiteResources(\n suiClient: SuiClient,\n siteId: string,\n packageId: string\n) {\n const dynamicFields = await fetchSiteDynamicFields(suiClient, siteId)\n\n // console.log('🔍 Dynamic fields found:', dynamicFields)\n\n const resourcePaths = dynamicFields\n .filter(f => f.objectType === `${packageId}::site::Resource`)\n .filter(r => r.name.type === `${packageId}::site::ResourcePath`)\n\n // console.log('🔍 Resource paths found:', resourcePaths)\n\n // Fetch resource details\n const resources: ResourceData[] = []\n for (const rp of resourcePaths) {\n const resObj = await suiClient.getObject({\n id: rp.objectId,\n options: { showContent: true }\n })\n\n if (resObj.data?.content?.dataType !== 'moveObject')\n throw new Error('Invalid resource object data type')\n\n const fields = resObj.data?.content?.fields\n if (Array.isArray(fields)) throw new Error('Invalid resource object fields')\n if (!('value' in fields))\n throw new Error('Invalid resource object fields value')\n\n // console.log('🔍 Resource object fields:', fields)\n\n const resourceValue = fields.value as ResourceChainValue\n const result: ResourceData = {\n blob_hash: resourceValue.fields.blob_hash,\n blob_id: resourceValue.fields.blob_id,\n headers: resourceValue.fields.headers.fields.contents.map(c => c.fields),\n path: resourceValue.fields.path\n }\n resources.push(result)\n }\n return resources\n}\n\nasync function fetchWalrusSiteData(\n suiClient: SuiClient,\n id: string,\n packageId: string\n): Promise<WalrusSiteData> {\n // console.log('🔍 Fetching Walrus site data for ID:', id, packageId)\n // Fetch site object and display data\n const objRes = await suiClient.getObject({\n id,\n options: { showDisplay: true }\n })\n\n const error = objRes.data?.display?.error ?? objRes.error\n if (error) handleError(error)\n\n const data = objRes.data?.display?.data\n if (!data) throw new Error('No data returned for Walrus site')\n const siteData = data as unknown as WalrusSiteDisplayData\n // console.log('🔍 Fetched Walrus site display data:', siteData)\n const resources = await fetchSiteResources(suiClient, id, packageId)\n // console.log('🔍 Fetched Walrus site resources:', resources)\n const finalSiteData = { id, ...siteData, resources }\n // console.log('🔍 Fetched Walrus site data:', finalSiteData)\n return finalSiteData\n}\n\nexport function useWalrusSiteQuery(\n id: string | undefined,\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n }\n) {\n const { network } = clients.suiClient\n const packageId = useMemo(\n () => mainPackage[network as keyof typeof mainPackage].packageId,\n [network]\n )\n\n return useQuery(\n {\n queryKey: queryKeys.walrusSite(id),\n queryFn: async () => {\n if (!id) throw new Error('No site ID provided')\n return fetchWalrusSiteData(clients.suiClient, id, packageId)\n },\n enabled: !!id\n },\n clients.queryClient\n )\n}\n\nasync function fetchWalrusSitesListPaginated(\n suiClient: SuiClient,\n address: string,\n packageId: string,\n limit?: number,\n cursorParam?: string | null\n): Promise<{\n sites: WalrusSiteData[]\n nextCursor: string | null\n hasNextPage: boolean\n}> {\n try {\n const response = await suiClient.getOwnedObjects({\n owner: address,\n filter: {\n StructType: `${packageId}::site::Site`\n },\n options: { showDisplay: true, showType: true },\n cursor: cursorParam,\n limit: limit || 50\n })\n\n // console.log('🔍 Response:', response)\n\n if (!response.data || response.data.length === 0) {\n return {\n sites: [],\n nextCursor: response.nextCursor || null,\n hasNextPage: response.hasNextPage\n }\n }\n\n const siteObjects = response.data\n .filter(obj => {\n // Filter for Site objects\n if (!obj.data) {\n console.warn('Object missing data:', obj)\n return false\n }\n\n // Check for display errors\n if (obj.data.display?.error) {\n console.warn(\n 'Display error for site:',\n obj.data.objectId,\n obj.data.display.error\n )\n return false\n }\n\n // Verify it's a Site type\n const type = obj.data.type\n if (!type || type !== `${packageId}::site::Site`) {\n return false\n }\n\n // Must have objectId\n if (!obj.data.objectId) {\n console.warn('Object missing objectId:', obj)\n return false\n }\n\n return true\n })\n .map(obj => {\n // obj.data is guaranteed to exist due to filter above\n if (!obj.data) return null\n\n // Access display data from obj.data.display.data\n const display = obj.data.display?.data\n if (!display) {\n console.warn('No display data for site:', obj.data.objectId)\n return null\n }\n\n const displayData = display as unknown as WalrusSiteDisplayData\n\n // Validate required fields\n if (!displayData.name) {\n console.warn('Site missing name:', obj.data.objectId)\n return null\n }\n\n return {\n id: obj.data.objectId,\n name: displayData.name,\n description: displayData.description || '',\n image_url: displayData.image_url || '',\n link: displayData.link || '',\n project_url: displayData.project_url || '',\n creator: displayData.creator || '',\n resources: [] as ResourceData[]\n }\n })\n .filter((site): site is WalrusSiteData => site !== null)\n\n return {\n sites: siteObjects,\n nextCursor: response.nextCursor || null,\n hasNextPage: response.hasNextPage\n }\n } catch (error) {\n console.error('Error fetching Walrus sites list:', error)\n throw error\n }\n}\n\nexport function useWalrusSitesQuery(\n address: string | undefined,\n options: {\n limit?: number\n cursor?: string | null\n },\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n }\n) {\n const { suiClient, queryClient } = clients\n const { network } = suiClient\n const packageId = useMemo(\n () => mainPackage[network as keyof typeof mainPackage].packageId,\n [network]\n )\n\n console.log('🔍 Fetching Walrus sites list for address:', address, packageId)\n\n const sitesListQuery = useQuery(\n {\n queryKey: [\n ...queryKeys.walrusSites(address, network),\n options?.cursor,\n options?.limit\n ],\n queryFn: async () => {\n if (!address) return { sites: [], nextCursor: null, hasNextPage: false }\n return fetchWalrusSitesListPaginated(\n suiClient,\n address,\n packageId,\n options?.limit,\n options?.cursor\n )\n },\n enabled: !!address,\n staleTime: 1000 * 60 * 5, // 5 minutes\n retry: 2,\n retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, 30000)\n },\n queryClient\n )\n\n // Return paginated data directly - no need to fetch full details for list view\n return {\n data: sitesListQuery.data?.sites ?? [],\n nextCursor: sitesListQuery.data?.nextCursor ?? null,\n hasNextPage: sitesListQuery.data?.hasNextPage ?? false,\n isLoading: sitesListQuery.isLoading,\n isError: sitesListQuery.isError,\n error: sitesListQuery.error\n }\n}\n","import type { ZenFsFileManager } from '@cmdoss/file-manager'\nimport {\n getSHA256Hash,\n type IAsset,\n sha256ToU256\n} from '@cmdoss/walrus-site-builder'\nimport { type QueryClient, useQuery } from '@tanstack/react-query'\n\nexport function useZenfsFilesQuery(\n fm: ZenFsFileManager | null,\n clients: {\n queryClient: QueryClient\n }\n) {\n const { queryClient } = clients\n return useQuery(\n {\n queryKey: ['zenfs-files', fm?.workspaceDir],\n queryFn: async () => {\n if (!fm) return []\n const files = await fm.listFiles()\n const assets: IAsset[] = []\n for (const path of files) {\n const content = await fm?.readFile(path)\n if (!content) continue\n const hash = await getSHA256Hash(content)\n const hashU256 = sha256ToU256(hash)\n assets.push({ path, content, hashU256 })\n }\n return assets\n },\n enabled: !!fm,\n staleTime: 5 * 60 * 1000 // 5 minutes\n },\n queryClient\n )\n}\n","import { atom } from 'nanostores'\n\nexport const isDomainDialogOpen = atom(false)\nexport const isAssigningDomain = atom(false)\nexport const isRegisterSuiNSDomainDialogOpen = atom(false)\nexport const isExtendTimeDialogOpen = atom(false)\nexport const isUpdateMetadataModalOpen = atom(false)\n","import { atom, computed } from 'nanostores'\n\nconst DEFAULT_TITLE = 'wal-0'\nconst DEFAULT_DESCRIPTION = 'WAL-0 Generated Project'\n\nclass SiteMetadata {\n title = atom(DEFAULT_TITLE)\n description = atom(DEFAULT_DESCRIPTION)\n imageUrl = atom<string | File | null>('https://www.walrus.xyz/walrus-site')\n link = atom<string>('')\n projectUrl = atom<string>('')\n epochs = atom(5)\n deletable = atom(false)\n loading = atom(false)\n suiNSUrl = atom<Array<{ suins: string; nftId: string }>>([])\n\n // Site data\n originalTitle = atom(DEFAULT_TITLE)\n originalDescription = atom(DEFAULT_DESCRIPTION)\n originalImageUrl = atom<string | File | null>(\n 'https://www.walrus.xyz/walrus-site'\n )\n originalLink = atom<string>('')\n originalProjectUrl = atom<string>('')\n originalEpochs = atom(5)\n originalSuiNSUrl = atom<Array<{ suins: string; nftId: string }>>([])\n\n // Derived/computed state\n isDirty = computed(\n [\n this.title,\n this.description,\n this.imageUrl,\n this.link,\n this.projectUrl,\n this.epochs,\n this.suiNSUrl,\n this.originalTitle,\n this.originalDescription,\n this.originalImageUrl,\n this.originalLink,\n this.originalProjectUrl,\n this.originalEpochs,\n this.originalSuiNSUrl\n ],\n (\n title,\n description,\n iconUrl,\n link,\n projectUrl,\n epochs,\n suiNSUrl,\n originalTitle,\n originalDescription,\n originalIcon,\n originalLink,\n originalProjectUrl,\n originalEpochs,\n originalSuiNSUrl\n ) =>\n title !== originalTitle ||\n description !== originalDescription ||\n (iconUrl ?? null) !== (originalIcon ?? null) ||\n link !== originalLink ||\n projectUrl !== originalProjectUrl ||\n epochs !== originalEpochs ||\n JSON.stringify(\n suiNSUrl.sort((a, b) => a.nftId.localeCompare(b.nftId))\n ) !==\n JSON.stringify(\n originalSuiNSUrl.sort((a, b) => a.nftId.localeCompare(b.nftId))\n )\n )\n /**\n * Computed URL for displaying the image preview\n */\n imageDisplayUrl = computed([this.imageUrl], imageUrl => {\n if (!imageUrl) return null\n if (typeof imageUrl === 'string') return imageUrl\n return URL.createObjectURL(imageUrl) // TODO: revoke when not used\n })\n\n commitChanges() {\n this.originalTitle.set(this.title.get())\n this.originalDescription.set(this.description.get())\n this.originalImageUrl.set(this.imageUrl.get())\n this.originalLink.set(this.link.get())\n this.originalProjectUrl.set(this.projectUrl.get())\n this.originalEpochs.set(this.epochs.get())\n this.originalSuiNSUrl.set(this.suiNSUrl.get().map(item => ({ ...item })))\n }\n\n reset() {\n this.title.set(this.originalTitle.get())\n this.description.set(this.originalDescription.get())\n this.imageUrl.set(this.originalImageUrl.get())\n this.link.set(this.originalLink.get())\n this.projectUrl.set(this.originalProjectUrl.get())\n this.epochs.set(this.originalEpochs.get())\n this.suiNSUrl.set(this.originalSuiNSUrl.get().map(item => ({ ...item })))\n this.loading.set(false)\n }\n\n cancelEdit = () => this.reset()\n}\n\nexport const siteMetadataStore = new SiteMetadata()\n","export interface TOk<T> {\n ok: true\n data: T\n error?: never\n}\nexport interface TFailed<E> {\n ok: false\n error: E\n data?: never\n}\nexport type TResult<T = void, E = string> = TOk<T> | TFailed<E>\n\nexport function ok(): TOk<void>\nexport function ok<T>(data: T): TOk<T>\nexport function ok<T>(data?: T): TOk<T> {\n return { ok: true, data: data as T }\n}\nexport function failed<E>(error: E): TFailed<E> {\n return { ok: false, error }\n}\n\n// ###########################################################################\n// # API specific result type and helpers\n// ###########################################################################\n\nexport interface TApiError {\n code: string\n message: string\n stack?: string\n}\nexport const apiFailed = failed<TApiError>\nexport type TApiResult<T> = TResult<T, TApiError>\n","import type {\n IAsset,\n ICertifiedBlob,\n IUpdateWalrusSiteFlow,\n IWalrusSiteBuilderSdk\n} from '@cmdoss/walrus-site-builder'\nimport { atom, computed } from 'nanostores'\nimport { failed, ok, type TResult } from '~/lib/result'\nimport { isDomainDialogOpen } from './site-domain.store'\nimport { siteMetadataStore } from './site-metadata.store'\n\nexport enum DeploySteps {\n Idle,\n Prepared,\n Uploaded,\n Certified,\n Deployed\n}\n\nexport enum DeploymentStatus {\n Idle,\n /** Preparing assets for upload */\n Preparing,\n /** Assets have been prepared */\n Prepared,\n /** Uploading assets to the network */\n Uploading,\n /** Assets have been uploaded */\n Uploaded,\n /** Certify uploaded assets */\n Certifying,\n /** Assets have been certified */\n Certified,\n /** Deploy site metadata */\n Deploying,\n /** Site has been deployed */\n Deployed\n}\n\nexport interface SiteMetadata {\n id?: string\n title?: string\n description?: string\n link?: string\n projectUrl?: string\n imageUrl?: string\n creator?: string\n}\nexport interface SiteMetadataUpdate extends Omit<SiteMetadata, 'imageUrl'> {\n imageUrl?: string | File\n}\n\nexport interface DeploymentHandlers {\n prepareAssets: () => Promise<void>\n uploadAssets: (epoch: number | 'max', permanent?: boolean) => Promise<void>\n certifyAssets: () => Promise<void>\n updateSite: () => Promise<void>\n}\n\nclass SitePublishingStore {\n // Deployment state\n deployStatus = atom(DeploymentStatus.Idle)\n deploymentStepIndex = computed([this.deployStatus], s => {\n switch (s) {\n case DeploymentStatus.Idle:\n case DeploymentStatus.Preparing:\n return 0\n case DeploymentStatus.Prepared:\n case DeploymentStatus.Uploading:\n return 1\n case DeploymentStatus.Uploaded:\n case DeploymentStatus.Certifying:\n return 2\n case DeploymentStatus.Certified:\n case DeploymentStatus.Deploying:\n return 3\n case DeploymentStatus.Deployed:\n return 4\n default:\n return 0\n }\n })\n\n // UI state\n isPublishDialogOpen = atom(false)\n certifiedBlobs = atom<ICertifiedBlob[]>([])\n isWorking = computed(\n [this.deployStatus],\n deployStatus =>\n deployStatus !== DeploymentStatus.Idle &&\n deployStatus !== DeploymentStatus.Prepared &&\n deployStatus !== DeploymentStatus.Uploaded &&\n deployStatus !== DeploymentStatus.Certified &&\n deployStatus !== DeploymentStatus.Deployed\n )\n\n deployStatusText = computed([this.deployStatus], s => {\n switch (s) {\n case DeploymentStatus.Idle:\n return 'Start Deployment'\n case DeploymentStatus.Preparing:\n return 'Preparing assets...'\n case DeploymentStatus.Prepared:\n return 'Upload assets'\n case DeploymentStatus.Uploading:\n return 'Uploading assets...'\n case DeploymentStatus.Uploaded:\n return 'Certify assets'\n case DeploymentStatus.Certifying:\n return 'Certifying assets...'\n case DeploymentStatus.Certified:\n return 'Update Site Metadata'\n case DeploymentStatus.Deploying:\n return 'Updating site metadata...'\n case DeploymentStatus.Deployed:\n return 'Customize Domain'\n default:\n return 'Unknown status'\n }\n })\n\n private currentFlow?: IUpdateWalrusSiteFlow\n private siteId?: string\n\n async runDeploymentStep(\n sdk: IWalrusSiteBuilderSdk,\n assets: IAsset[],\n site: SiteMetadata\n ): Promise<TResult<string>> {\n if (this.isWorking.get()) return failed('Another operation is in progress')\n\n const status = this.deployStatus.get()\n\n switch (status) {\n case DeploymentStatus.Idle: {\n this.deployStatus.set(DeploymentStatus.Preparing)\n try {\n this.currentFlow = sdk.executeSiteUpdateFlow(assets, {\n object_id: site.id,\n site_name: site.title,\n metadata: {\n link: site.link,\n description: site.description,\n project_url: site.projectUrl,\n image_url: site.imageUrl,\n creator: site.creator ?? 'CommandOSS Site Builder'\n }\n })\n const diff = await this.currentFlow.prepareResources()\n if (diff.resources.every(r => r.op === 'unchanged')) {\n if (diff.site_name.op === 'noop' && diff.metadata.op === 'noop') {\n this.deployStatus.set(DeploymentStatus.Idle)\n return failed('No changes detected')\n } else {\n // Only metadata/site name changed, skip to certification\n this.deployStatus.set(DeploymentStatus.Certified)\n }\n } else this.deployStatus.set(DeploymentStatus.Prepared)\n return this.runDeploymentStep(sdk, assets, site)\n } catch (e) {\n console.error('Failed to prepare assets:', e)\n const msg =\n e instanceof Error ? e.message : 'Failed to prepare assets'\n this.deployStatus.set(DeploymentStatus.Idle)\n return failed(msg)\n }\n }\n\n case DeploymentStatus.Prepared: {\n if (!this.currentFlow) return failed('Invalid deployment flow')\n\n this.deployStatus.set(DeploymentStatus.Uploading)\n const epochs = siteMetadataStore.epochs.get()\n const deletable = siteMetadataStore.deletable.get()\n\n try {\n await this.currentFlow.writeResources(epochs, deletable)\n } catch (e) {\n console.error('Failed to upload assets:', e)\n this.deployStatus.set(DeploymentStatus.Prepared)\n return failed('Failed to upload assets')\n }\n\n this.deployStatus.set(DeploymentStatus.Uploaded)\n return this.runDeploymentStep(sdk, assets, site)\n }\n\n case DeploymentStatus.Uploaded: {\n if (!this.currentFlow) return failed('Invalid deployment flow')\n this.deployStatus.set(DeploymentStatus.Certifying)\n try {\n await this.currentFlow.certifyResources()\n this.deployStatus.set(DeploymentStatus.Certified)\n return this.runDeploymentStep(sdk, assets, site)\n } catch (e) {\n console.error('Failed to certify assets:', e)\n this.deployStatus.set(DeploymentStatus.Uploaded)\n const msg =\n e instanceof Error ? e.message : 'Failed to certify assets'\n return failed(msg)\n }\n }\n\n case DeploymentStatus.Certified: {\n if (!this.currentFlow) return failed('Invalid deployment flow')\n this.deployStatus.set(DeploymentStatus.Deploying)\n try {\n const { siteId } = await this.currentFlow.writeSite()\n if (!siteId) throw new Error('No site ID returned')\n this.deployStatus.set(DeploymentStatus.Deployed)\n this.siteId = siteId\n return ok(siteId)\n } catch (e) {\n console.error('Failed to deploy site:', e)\n this.deployStatus.set(DeploymentStatus.Certified)\n const msg = e instanceof Error ? e.message : 'Failed to deploy site'\n return failed(msg)\n }\n }\n case DeploymentStatus.Deployed:\n if (!this.siteId) return failed('Invalid state')\n // Deployment completed, close dialog\n this.reset()\n this.closePublishDialog()\n this.openCustomDomainDialog()\n return ok(this.siteId)\n\n default:\n return failed('Invalid deployment step')\n }\n }\n\n reset() {\n this.deployStatus.set(DeploymentStatus.Idle)\n this.certifiedBlobs.set([])\n this.currentFlow = undefined\n }\n\n closePublishDialog = () => this.isPublishDialogOpen.set(false)\n openCustomDomainDialog = () => isDomainDialogOpen.set(true)\n}\n\nexport const sitePublishingStore = new SitePublishingStore()\n","import {\n type ISignAndExecuteTransaction,\n type ISponsorConfig,\n TransactionExecutorService\n} from '@cmdoss/walrus-site-builder'\nimport type { SuiClient } from '@mysten/sui/client'\nimport { useMemo } from 'react'\n\nexport interface UseTransactionExecutorParams {\n suiClient: SuiClient\n walletAddress: string | undefined\n signAndExecuteTransaction: ISignAndExecuteTransaction\n sponsorConfig?: ISponsorConfig\n}\n\n/**\n * React hook to create a TransactionExecutorService instance.\n * Automatically handles sponsor configuration and wallet changes.\n */\nexport function useTransactionExecutor({\n suiClient,\n walletAddress,\n signAndExecuteTransaction,\n sponsorConfig\n}: UseTransactionExecutorParams) {\n return useMemo(() => {\n if (!walletAddress) return null\n\n return new TransactionExecutorService({\n suiClient,\n walletAddress,\n signAndExecuteTransaction,\n sponsorConfig\n })\n }, [suiClient, walletAddress, signAndExecuteTransaction, sponsorConfig])\n}\n","import {\n type IAsset,\n type ISignAndExecuteTransaction,\n type ISponsorConfig,\n type IWalrusSiteBuilderSdk,\n mainPackage,\n objectIdToWalrusSiteUrl,\n WalrusSiteBuilderSdk\n} from '@cmdoss/walrus-site-builder'\nimport type { SuiClient } from '@mysten/sui/client'\nimport { Transaction } from '@mysten/sui/transactions'\nimport {\n ALLOWED_METADATA,\n type SuinsClient,\n SuinsTransaction\n} from '@mysten/suins'\nimport type { WalletAccount } from '@mysten/wallet-standard'\nimport type { WalrusClient } from '@mysten/walrus'\nimport {\n MAINNET_WALRUS_PACKAGE_CONFIG,\n TESTNET_WALRUS_PACKAGE_CONFIG\n} from '@mysten/walrus'\nimport { useStore } from '@nanostores/react'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { useEffect, useMemo, useState } from 'react'\nimport { useWalrusSiteQuery } from '~/queries'\nimport { useSuiNsDomainsQuery } from '~/queries/suins-domains.query'\nimport {\n isAssigningDomain,\n isDomainDialogOpen\n} from '~/stores/site-domain.store'\nimport { siteMetadataStore } from '~/stores/site-metadata.store'\nimport {\n type SiteMetadata,\n type SiteMetadataUpdate,\n sitePublishingStore\n} from '~/stores/site-publishing.store'\nimport { useTransactionExecutor } from './useTransactionExecutor'\n\nexport interface UseSitePublishingParams {\n /**\n * Site Object ID on chain. If not provided, a new site will be created upon publishing.\n */\n siteId?: string\n /**\n * Site's assets to be published.\n */\n assets: IAsset[]\n /**\n * Optional callback to update site metadata after publishing. The site ID will\n * be available in the `site` parameter.\n */\n onUpdateSiteMetadata?: (\n site: SiteMetadataUpdate\n ) => Promise<SiteMetadata | undefined>\n /** Optional callback when a domain is associated with the site. */\n onAssociatedDomain?: (\n nftId: string,\n siteId: string,\n suiNSName: string\n ) => Promise<void>\n /** Optional callback for handling errors. */\n onError?: (msg: string) => void\n /** Optional callback when blobs are extended. */\n onExtendedBlobs?: (msg: string, txDigest?: string) => void\n /**\n * Sui and Query clients needed for on-chain operations.\n */\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n suinsClient: SuinsClient\n walrusClient: WalrusClient\n }\n /** Current wallet account information. */\n currentAccount: WalletAccount | null\n\n /** Callback for signing and executing transactions. */\n signAndExecuteTransaction: ISignAndExecuteTransaction\n sponsorConfig?: ISponsorConfig\n /** Optional domain for the portal to view published site. */\n portalDomain?: string\n /** Whether to use HTTPS for the portal URL. */\n portalHttps?: boolean\n}\n\nexport function useSitePublishing({\n siteId,\n assets,\n onUpdateSiteMetadata,\n onAssociatedDomain,\n onError,\n onExtendedBlobs,\n currentAccount,\n signAndExecuteTransaction,\n sponsorConfig,\n portalDomain,\n portalHttps,\n clients: { suiClient, queryClient, suinsClient, walrusClient }\n}: UseSitePublishingParams) {\n const [isExtending, setIsExtending] = useState(false)\n // Transaction executor with sponsor support\n const txExecutor = useTransactionExecutor({\n suiClient,\n walletAddress: currentAccount?.address,\n signAndExecuteTransaction,\n sponsorConfig\n })\n\n const sdk: IWalrusSiteBuilderSdk | undefined = useMemo(() => {\n if (!suiClient || !walrusClient || !currentAccount) return\n return new WalrusSiteBuilderSdk(\n walrusClient,\n suiClient,\n currentAccount.address,\n signAndExecuteTransaction,\n sponsorConfig\n )\n }, [\n suiClient,\n walrusClient,\n currentAccount,\n signAndExecuteTransaction,\n sponsorConfig\n ])\n\n const {\n data: nsDomains,\n isLoading: isLoadingNsDomains,\n isError: isErrorNsDomains\n } = useSuiNsDomainsQuery(currentAccount, { suiClient, queryClient })\n\n const { data: walrusSiteData } = useWalrusSiteQuery(siteId, {\n suiClient,\n queryClient\n })\n\n // Store state\n const isPublishDialogOpen = useStore(sitePublishingStore.isPublishDialogOpen)\n const isWorking = useStore(sitePublishingStore.isWorking)\n const certifiedBlobs = useStore(sitePublishingStore.certifiedBlobs)\n const deployStatus = useStore(sitePublishingStore.deployStatus)\n const deployStatusText = useStore(sitePublishingStore.deployStatusText)\n const deployStepIndex = useStore(sitePublishingStore.deploymentStepIndex)\n\n const epochs = useStore(siteMetadataStore.epochs)\n const title = useStore(siteMetadataStore.title)\n const imageUrl = useStore(siteMetadataStore.imageUrl)\n const link = useStore(siteMetadataStore.link)\n const description = useStore(siteMetadataStore.description)\n const isEditingSiteMetadata = useStore(siteMetadataStore.isDirty)\n const isSavingSiteMetadata = useStore(siteMetadataStore.loading)\n const isAssigning = useStore(isAssigningDomain)\n\n // Derived state\n const isDeployed = !!siteId\n const walrusSiteUrl = useMemo(() => {\n if (!siteId) return null\n return objectIdToWalrusSiteUrl(siteId, portalDomain, portalHttps)\n }, [siteId, portalDomain, portalHttps])\n\n const associatedDomains = nsDomains.filter(d => d.walrusSiteId === siteId)\n\n // Sync site data to store\n useEffect(() => {\n if (!walrusSiteData) return\n console.log('🔄 Syncing Walrus site data to store', walrusSiteData)\n siteMetadataStore.originalTitle.set(walrusSiteData.name ?? '')\n siteMetadataStore.originalDescription.set(walrusSiteData.description ?? '')\n siteMetadataStore.originalImageUrl.set(walrusSiteData.image_url ?? null)\n siteMetadataStore.originalProjectUrl.set(walrusSiteData.project_url ?? null)\n siteMetadataStore.originalLink.set(walrusSiteData.link ?? '')\n siteMetadataStore.reset()\n }, [walrusSiteData])\n\n // Actions\n const handleRunDeploymentStep = async () => {\n if (!sdk) return onError?.('SDK not initialized')\n if (imageUrl instanceof File) return onError?.('Please upload image first.')\n const siteMetadata: SiteMetadata = {\n id: siteId,\n title,\n description,\n imageUrl: imageUrl ?? undefined,\n link: siteMetadataStore.link.get() ?? undefined,\n projectUrl: siteMetadataStore.projectUrl.get() ?? undefined\n }\n const result = await sitePublishingStore.runDeploymentStep(\n sdk,\n assets,\n siteMetadata\n )\n if (!result.ok) return onError?.(result.error || 'Deployment failed')\n siteMetadata.id = result.data // Update site ID after deployment\n await onUpdateSiteMetadata?.(siteMetadata)\n siteMetadataStore.commitChanges()\n }\n\n const handleSaveSiteMetadata = async () => {\n if (!onUpdateSiteMetadata) {\n siteMetadataStore.commitChanges()\n return\n }\n\n siteMetadataStore.loading.set(true)\n try {\n const result = await onUpdateSiteMetadata({\n id: siteId,\n title: siteMetadataStore.title.get(),\n description: siteMetadataStore.description.get(),\n imageUrl: siteMetadataStore.imageUrl.get() ?? undefined,\n link: siteMetadataStore.link.get() ?? undefined,\n projectUrl: siteMetadataStore.projectUrl.get() ?? undefined\n })\n if (!result) throw new Error('Failed to save site metadata')\n\n if (result.title) siteMetadataStore.title.set(result.title)\n if (result.description)\n siteMetadataStore.description.set(result.description)\n if (result.imageUrl) siteMetadataStore.imageUrl.set(result.imageUrl)\n siteMetadataStore.link.set(result.link ?? '')\n siteMetadataStore.projectUrl.set(result.projectUrl ?? '')\n\n siteMetadataStore.commitChanges()\n } finally {\n siteMetadataStore.loading.set(false)\n }\n }\n\n const handleAssociateDomain = async (\n nftId: string,\n siteId: string,\n suiNSName: string\n ) => {\n if (!suinsClient) return onError?.('SuiNS client not available')\n if (!nftId) return onError?.('No domain selected')\n if (!txExecutor) return onError?.('Transaction executor not available')\n\n isAssigningDomain.set(true)\n try {\n try {\n const transaction = new Transaction()\n const suinsTransaction = new SuinsTransaction(suinsClient, transaction)\n suinsTransaction.setUserData({\n nft: nftId,\n key: ALLOWED_METADATA.walrusSiteId,\n value: siteId\n })\n\n const digest = await txExecutor.execute({\n transaction,\n description: 'Associate domain with Walrus site'\n })\n\n await suiClient.waitForTransaction({ digest })\n\n // Invalidate all SuiNS queries to refetch updated domain data\n await queryClient.invalidateQueries({\n predicate: query => {\n const key = query.queryKey[0]\n return key === 'suins-domains' || key === 'suins-domain-detail'\n }\n })\n\n // Add domain to array if not already present\n const currentDomains = siteMetadataStore.suiNSUrl.get()\n const domainEntry = { suins: suiNSName, nftId }\n\n if (!currentDomains.some(d => d.nftId === nftId)) {\n siteMetadataStore.suiNSUrl.set([...currentDomains, domainEntry])\n }\n\n await onAssociatedDomain?.(nftId, siteId, suiNSName)\n } catch (e) {\n console.error('🚨 Failed to update SuiNS metadata:', e)\n onError?.('Failed to update SuiNS metadata')\n }\n } finally {\n isAssigningDomain.set(false)\n }\n }\n\n function handleOpenDomainDialog() {\n isDomainDialogOpen.set(true)\n }\n function handleOpenPublishingDialog() {\n sitePublishingStore.isPublishDialogOpen.set(true)\n }\n\n const handleExtendBlobs = async (extendEpochs: number) => {\n if (\n !walrusClient ||\n !currentAccount ||\n !walrusSiteData?.resources ||\n walrusSiteData.resources.length === 0\n ) {\n onError?.('Cannot extend blobs: missing required data')\n return\n }\n\n if (!extendEpochs || extendEpochs <= 0 || extendEpochs > 365) {\n onError?.('Invalid epoch count. Must be between 1 and 365')\n return\n }\n\n if (!txExecutor) {\n onError?.('Transaction executor not available')\n return\n }\n\n setIsExtending(true)\n try {\n const blobType = await walrusClient.getBlobType()\n\n // Determine network-specific constants\n const walCoinType =\n mainPackage[suiClient.network as keyof typeof mainPackage]\n .walrusCoinType\n const walrusPackageId =\n mainPackage[suiClient.network as keyof typeof mainPackage]\n .walrusPackageId\n const systemObjectId =\n suiClient.network === 'mainnet'\n ? MAINNET_WALRUS_PACKAGE_CONFIG.systemObjectId\n : TESTNET_WALRUS_PACKAGE_CONFIG.systemObjectId\n\n // Map blob_id to blobObjectId\n const blobIdToObjectIdMap = new Map<string, string>()\n let cursor: string | null | undefined = null\n let hasNextPage = true\n\n while (hasNextPage) {\n const ownedObjects = await suiClient.getOwnedObjects({\n owner: currentAccount.address,\n filter: { StructType: blobType },\n options: { showContent: true },\n cursor\n })\n\n // console.log endEpochs\n console.log('walrusSiteData.resources', walrusSiteData.resources)\n\n for (const resource of walrusSiteData.resources) {\n const blobId = resource.blob_id\n\n for (const obj of ownedObjects.data) {\n if (obj.data?.content && 'fields' in obj.data.content) {\n const fields = obj.data.content.fields as Record<string, unknown>\n if ('blob_id' in fields) {\n const objBlobId = String(fields.blob_id)\n if (objBlobId === blobId && !blobIdToObjectIdMap.has(blobId)) {\n blobIdToObjectIdMap.set(blobId, obj.data.objectId)\n break\n }\n }\n }\n }\n }\n\n hasNextPage = ownedObjects.hasNextPage\n cursor = ownedObjects.nextCursor\n }\n\n if (blobIdToObjectIdMap.size === 0) {\n throw new Error(\n 'No blob objects found for this site. Make sure you own the blob objects.'\n )\n }\n\n const tx = new Transaction()\n tx.setSender(currentAccount.address)\n\n const walCoin = await suiClient.getCoins({\n owner: currentAccount.address,\n coinType: walCoinType\n })\n\n if (walCoin.data.length === 0) {\n throw new Error(\n `No WAL coins found in wallet. Please acquire WAL tokens first.`\n )\n }\n\n // Merge all WAL coins\n if (walCoin.data.length > 1) {\n tx.mergeCoins(\n tx.object(walCoin.data[0].coinObjectId),\n walCoin.data.slice(1).map(coin => tx.object(coin.coinObjectId))\n )\n }\n\n // Extend all blobs by adding epochs to their current expiration\n for (const [_blobId, objectId] of blobIdToObjectIdMap.entries()) {\n tx.moveCall({\n package: walrusPackageId,\n module: 'system',\n function: 'extend_blob',\n arguments: [\n tx.object(systemObjectId),\n tx.object(objectId),\n tx.pure.u32(extendEpochs),\n tx.object(walCoin.data[0].coinObjectId)\n ]\n })\n }\n\n const digest = await txExecutor.execute({\n transaction: tx,\n description: `Extending ${blobIdToObjectIdMap.size} blob(s) by ${extendEpochs} epoch(s)`\n })\n\n // Wait for transaction to complete\n await suiClient.waitForTransaction({ digest })\n\n // Invalidate queries to refetch updated data\n await queryClient.invalidateQueries({\n predicate: query => {\n const key = query.queryKey\n return (\n (Array.isArray(key) &&\n (key[0] === 'walrus-site' || key[0] === 'walrus-sites')) ||\n false\n )\n }\n })\n\n onExtendedBlobs?.(\n `Successfully extended ${blobIdToObjectIdMap.size} blob(s) by ${extendEpochs} epoch(s)`,\n digest\n )\n } catch (error) {\n console.error('Error extending blobs:', error)\n onError?.(\n `Failed to extend blobs: ${error instanceof Error ? error.message : 'Unknown error'}`\n )\n } finally {\n setIsExtending(false)\n }\n }\n\n return {\n state: {\n isDeployed,\n isAssigning,\n isExtending,\n isPublishDialogOpen,\n isWorking,\n certifiedBlobs,\n epochs,\n title,\n iconUrl: imageUrl,\n description,\n link,\n isEditingSiteMetadata,\n deployStatus,\n deployStatusText,\n deployStepIndex,\n walrusSiteUrl,\n nsDomains,\n isLoadingNsDomains,\n isErrorNsDomains,\n isSavingSiteMetadata,\n associatedDomains\n },\n actions: {\n handleRunDeploymentStep,\n handleSaveSiteMetadata,\n handleAssociateDomain,\n handleExtendBlobs,\n handleOpenDomainDialog,\n handleOpenPublishingDialog,\n handleCancelEditingSiteMetadata: siteMetadataStore.reset\n }\n }\n}\n","import type { WalrusClient } from '@mysten/walrus'\nimport { useEffect, useMemo, useState } from 'react'\n\nexport function useEpochDuration(walrusClient: WalrusClient | null) {\n const [epochDurationMs, setEpochDurationMs] = useState<number | null>(null)\n\n // Get epoch duration from Walrus staking state\n useEffect(() => {\n const fetchEpochDuration = async () => {\n if (!walrusClient) return\n\n try {\n const stakingState = await walrusClient.stakingState()\n const duration = Number(stakingState.epoch_duration)\n setEpochDurationMs(duration)\n } catch (error) {\n console.error('Error fetching epoch duration:', error)\n // Fallback to 1 day if fetch fails\n setEpochDurationMs(24 * 60 * 60 * 1000)\n }\n }\n\n fetchEpochDuration()\n }, [walrusClient])\n\n // Calculate expiration date\n const getExpirationDate = useMemo(() => {\n return (epochs: number) => {\n if (!epochDurationMs || !epochs || epochs <= 0) return null\n const now = Date.now()\n return new Date(now + epochs * epochDurationMs)\n }\n }, [epochDurationMs])\n\n const formatDate = (date: Date) => {\n return new Intl.DateTimeFormat('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n }).format(date)\n }\n\n return {\n epochDurationMs,\n getExpirationDate,\n formatDate\n }\n}\n","import { AggregatorClient, Env } from '@cetusprotocol/aggregator-sdk'\nimport type {\n ISignAndExecuteTransaction,\n ISponsorConfig\n} from '@cmdoss/walrus-site-builder'\nimport { mainPackage } from '@cmdoss/walrus-site-builder'\nimport type { SuiClient } from '@mysten/sui/client'\nimport { Transaction } from '@mysten/sui/transactions'\nimport { type SuinsClient, SuinsTransaction } from '@mysten/suins'\nimport type { WalletAccount } from '@mysten/wallet-standard'\nimport type { QueryClient } from '@tanstack/react-query'\nimport BN from 'bn.js'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { useTransactionExecutor } from './useTransactionExecutor'\n\ninterface UseSuiNsRegistrationParams {\n currentAccount: WalletAccount | null\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n suinsClient: SuinsClient\n }\n signAndExecuteTransaction: ISignAndExecuteTransaction\n sponsorConfig?: ISponsorConfig\n}\n\nexport function useSuiNsRegistration({\n currentAccount,\n clients: { suiClient, queryClient, suinsClient },\n signAndExecuteTransaction,\n sponsorConfig\n}: UseSuiNsRegistrationParams) {\n const txExecutor = useTransactionExecutor({\n suiClient,\n walletAddress: currentAccount?.address,\n signAndExecuteTransaction,\n sponsorConfig\n })\n\n const [searchName, setSearchName] = useState('')\n const [isSearching, setIsSearching] = useState(false)\n const [isAvailable, setIsAvailable] = useState<boolean | null>(null)\n const [isRegistering, setIsRegistering] = useState(false)\n const [isSwapping, setIsSwapping] = useState(false)\n const [estimatedPrice, setEstimatedPrice] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [selectedYears, setSelectedYears] = useState(1)\n const [pricePerYear, setPricePerYear] = useState<number | null>(null)\n const [pricePerYearFormatted, setPricePerYearFormatted] = useState<\n string | null\n >(null)\n const [pricePerYearUsdc, setPricePerYearUsdc] = useState<string | null>(null)\n const [totalPriceUsdc, setTotalPriceUsdc] = useState<string | null>(null)\n const priceRefreshIntervalRef = useRef<NodeJS.Timeout | null>(null)\n\n const normalizedName = searchName.toLowerCase().trim()\n const fullName = normalizedName ? `${normalizedName}.sui` : ''\n const network = suiClient.network\n const isMainnet = network === 'mainnet'\n const isTestnet = network === 'testnet'\n\n // Calculate expiration date\n const expirationDate = useMemo(() => {\n if (!selectedYears) return null\n const date = new Date()\n date.setFullYear(date.getFullYear() + selectedYears)\n return date\n }, [selectedYears])\n\n // Calculate total price\n const totalPrice = useMemo(() => {\n if (!pricePerYear || !selectedYears) return null\n return pricePerYear * selectedYears\n }, [pricePerYear, selectedYears])\n\n // Format total price\n const totalPriceFormatted = useMemo(() => {\n if (!totalPrice || !pricePerYearFormatted) return null\n const perYearValue = parseFloat(\n pricePerYearFormatted.replace(/[^\\d.]/g, '')\n )\n if (Number.isNaN(perYearValue)) return null\n const totalValue = perYearValue * selectedYears\n return pricePerYearFormatted.replace(/[\\d.]+/, totalValue.toFixed(4))\n }, [totalPrice, pricePerYearFormatted, selectedYears])\n\n // Get WAL coin type from mainPackage\n const WAL_COIN_TYPE =\n mainPackage[network as keyof typeof mainPackage]?.walrusCoinType\n\n // Initialize Aggregator Client for swaps (mainnet only)\n const aggregatorClient = useMemo(() => {\n if (!suiClient || !currentAccount || !isMainnet) return null\n\n return new AggregatorClient({\n signer: currentAccount.address,\n client: suiClient,\n env: Env.Mainnet\n })\n }, [suiClient, currentAccount, isMainnet])\n\n // Function to update price estimate for mainnet (WAL → USDC)\n const updatePriceEstimate = useCallback(async () => {\n if (\n !suinsClient ||\n !currentAccount ||\n !isMainnet ||\n !WAL_COIN_TYPE ||\n !aggregatorClient ||\n !normalizedName\n ) {\n return\n }\n\n // Get price list\n const priceList = await suinsClient.getPriceList()\n const nameLength = normalizedName.length\n\n // Find price for this name length\n let pricePerYearValue = 0\n for (const [[from, to], price] of priceList.entries()) {\n if (nameLength >= from && nameLength <= to) {\n pricePerYearValue = price\n break\n }\n }\n\n if (pricePerYearValue > 0) {\n setPricePerYear(pricePerYearValue)\n\n // Calculate total price with buffer (5%)\n const totalPriceValue = pricePerYearValue * selectedYears\n const requiredAmount = BigInt(Math.floor(totalPriceValue * 1.05))\n\n // Get current USDC balance to calculate missing amount\n const usdcCoins = await suiClient.getCoins({\n owner: currentAccount.address,\n coinType: suinsClient.config.coins.USDC.type\n })\n\n const usdcBalance =\n usdcCoins.data?.reduce((sum, coin) => sum + BigInt(coin.balance), 0n) ??\n 0n\n\n // Calculate missing USDC (if any)\n const missingUsdc =\n usdcBalance < requiredAmount\n ? requiredAmount - usdcBalance\n : requiredAmount\n\n // Estimate WAL needed using same logic as register\n const baseWalAtomic = 1_000_000_000n // 1 WAL (9 decimals)\n const rateRouter = await aggregatorClient.findRouters({\n from: WAL_COIN_TYPE,\n target: suinsClient.config.coins.USDC.type,\n amount: new BN(baseWalAtomic.toString()),\n byAmountIn: true,\n providers: ['CETUS']\n })\n\n if (rateRouter && !rateRouter.error && rateRouter.amountOut) {\n const rawAmountOut = rateRouter.amountOut\n const usdcOutForOneWal = BigInt(\n rawAmountOut instanceof BN\n ? rawAmountOut.toString()\n : new BN(String(rawAmountOut)).toString()\n )\n\n if (usdcOutForOneWal > 0n) {\n const exchangeRate = Number(baseWalAtomic) / Number(usdcOutForOneWal)\n const estimatedWalNeeded =\n missingUsdc * BigInt(Math.ceil(exchangeRate))\n const walNeededFormatted = (\n Number(estimatedWalNeeded) / 1_000_000_000\n ).toFixed(4)\n const walPerYearFormatted = (\n Number(estimatedWalNeeded) /\n selectedYears /\n 1_000_000_000\n ).toFixed(4)\n setPricePerYearFormatted(`${walPerYearFormatted} WAL`)\n setEstimatedPrice(`~${walNeededFormatted} WAL`)\n } else {\n // Fallback: show USDC price\n const usdcPrice = (Number(requiredAmount) / 1_000_000).toFixed(2)\n const usdcPerYear = (pricePerYearValue / 1_000_000).toFixed(2)\n setPricePerYearFormatted(`${usdcPerYear} USDC`)\n setEstimatedPrice(`~${usdcPrice} USDC`)\n }\n } else {\n // Fallback: show USDC price\n const usdcPrice = (Number(requiredAmount) / 1_000_000).toFixed(2)\n const usdcPerYear = (pricePerYearValue / 1_000_000).toFixed(2)\n setPricePerYearFormatted(`${usdcPerYear} USDC`)\n setEstimatedPrice(`~${usdcPrice} USDC`)\n }\n }\n }, [\n suinsClient,\n currentAccount,\n isMainnet,\n WAL_COIN_TYPE,\n aggregatorClient,\n normalizedName,\n selectedYears,\n suiClient\n ])\n\n // Function to update price estimate for testnet (USDC → SUI)\n // Uses fixed exchange rate: 1 SUI = 1.5 USDC (or 1 USDC = 2/3 SUI)\n const updateTestnetPriceEstimate = useCallback(async () => {\n if (!suinsClient || !currentAccount || !isTestnet || !normalizedName) {\n return\n }\n\n // Get price list (price is in USDC)\n const priceList = await suinsClient.getPriceList()\n const nameLength = normalizedName.length\n\n // Find price for this name length\n let pricePerYearValue = 0\n for (const [[from, to], price] of priceList.entries()) {\n if (nameLength >= from && nameLength <= to) {\n pricePerYearValue = price\n break\n }\n }\n\n if (pricePerYearValue > 0) {\n setPricePerYear(pricePerYearValue)\n\n // Calculate total price (USDC amount) - this is what needs to be paid\n const totalPriceValue = pricePerYearValue * selectedYears\n const usdcAmountAtomic = BigInt(Math.floor(totalPriceValue))\n\n // Fixed exchange rate: 1 SUI = 1.5 USDC\n // So 1 USDC = 2/3 SUI = 0.666666... SUI\n // To calculate: (usdcAmount * 2 * 10^9) / (3 * 10^6)\n // This gives us SUI amount with 9 decimals\n const suiNeededAtomic =\n (usdcAmountAtomic * 2n * 1_000_000_000n) / (3n * 1_000_000n)\n const suiPerYearAtomic =\n (BigInt(Math.floor(pricePerYearValue)) * 2n * 1_000_000_000n) /\n (3n * 1_000_000n)\n\n // Format for display (SUI has 9 decimals)\n const suiNeededFormatted = (\n Number(suiNeededAtomic) / 1_000_000_000\n ).toFixed(4)\n const suiPerYearFormatted = (\n Number(suiPerYearAtomic) / 1_000_000_000\n ).toFixed(4)\n\n // Also store USDC prices for display\n const usdcPrice = (Number(usdcAmountAtomic) / 1_000_000).toFixed(2)\n const usdcPerYear = (pricePerYearValue / 1_000_000).toFixed(2)\n\n setPricePerYearFormatted(`${suiPerYearFormatted} SUI`)\n setEstimatedPrice(`${suiNeededFormatted} SUI`)\n setPricePerYearUsdc(`${usdcPerYear} USDC`)\n setTotalPriceUsdc(`${usdcPrice} USDC`)\n }\n }, [suinsClient, currentAccount, isTestnet, normalizedName, selectedYears])\n\n // Auto-refresh price every 10s when domain is available (mainnet only)\n useEffect(() => {\n if (\n isMainnet &&\n isAvailable &&\n normalizedName &&\n !isRegistering &&\n aggregatorClient\n ) {\n // Clear existing interval\n if (priceRefreshIntervalRef.current) {\n clearInterval(priceRefreshIntervalRef.current)\n }\n\n // Set up interval to refresh price every 10s\n priceRefreshIntervalRef.current = setInterval(() => {\n updatePriceEstimate().catch(err => {\n console.error('Error refreshing price:', err)\n })\n }, 10000)\n\n return () => {\n if (priceRefreshIntervalRef.current) {\n clearInterval(priceRefreshIntervalRef.current)\n }\n }\n }\n }, [\n isMainnet,\n isAvailable,\n normalizedName,\n isRegistering,\n aggregatorClient,\n updatePriceEstimate\n ])\n\n // Update price when years change\n useEffect(() => {\n if (isAvailable && pricePerYear !== null) {\n if (isMainnet && aggregatorClient) {\n updatePriceEstimate().catch(err => {\n console.error('Error updating price:', err)\n })\n } else if (isTestnet) {\n updateTestnetPriceEstimate().catch(err => {\n console.error('Error updating price:', err)\n })\n }\n }\n }, [\n isAvailable,\n pricePerYear,\n isMainnet,\n isTestnet,\n aggregatorClient,\n updatePriceEstimate,\n updateTestnetPriceEstimate\n ])\n\n const handleSearch = useCallback(async () => {\n if (!normalizedName || !suinsClient) return\n\n if (normalizedName.length < 3) {\n setError('Domain name must be at least 3 characters')\n setIsAvailable(null)\n setEstimatedPrice(null)\n return\n }\n\n setIsSearching(true)\n setError(null)\n setIsAvailable(null)\n setEstimatedPrice(null)\n\n try {\n const nameRecord = await suinsClient.getNameRecord(fullName)\n const available = !nameRecord?.nftId\n setIsAvailable(available)\n\n // Show estimated price\n if (available && currentAccount && aggregatorClient) {\n try {\n if (isMainnet && WAL_COIN_TYPE) {\n await updatePriceEstimate()\n } else if (isTestnet) {\n await updateTestnetPriceEstimate()\n }\n } catch (priceError) {\n console.error('Error estimating price:', priceError)\n // Don't set error, just don't show price\n }\n }\n } catch (error) {\n // If getNameRecord throws an error, the name might be available\n console.error('Error checking name:', error)\n setIsAvailable(true)\n } finally {\n setIsSearching(false)\n }\n }, [\n normalizedName,\n fullName,\n suinsClient,\n currentAccount,\n isMainnet,\n isTestnet,\n WAL_COIN_TYPE,\n aggregatorClient,\n updatePriceEstimate,\n updateTestnetPriceEstimate\n ])\n\n const handleRegister = useCallback(async () => {\n if (!suinsClient || !currentAccount || !isAvailable || !normalizedName) {\n return\n }\n\n if (!txExecutor) {\n setError('Transaction executor not available')\n return\n }\n\n setIsRegistering(true)\n setError(null)\n\n try {\n // Get price list\n const priceList = await suinsClient.getPriceList()\n const nameLength = normalizedName.length\n\n // Find price for this name length\n let pricePerYear = 0\n for (const [[from, to], price] of priceList.entries()) {\n if (nameLength >= from && nameLength <= to) {\n pricePerYear = price\n break\n }\n }\n\n if (pricePerYear === 0) {\n throw new Error('Unable to determine price for this domain')\n }\n\n // Register for selected years\n const years = selectedYears\n const totalPrice = pricePerYear * years\n\n // Get coin config (use SUI for testnet, USDC for mainnet)\n const coinType = isTestnet ? 'SUI' : 'USDC'\n const coinConfig = suinsClient.config.coins[coinType]\n\n // Load user balances (only for mainnet USDC/WAL)\n const [usdcCoins, walCoins] = await Promise.all([\n isMainnet\n ? suiClient.getCoins({\n owner: currentAccount.address,\n coinType: suinsClient.config.coins.USDC.type\n })\n : Promise.resolve({ data: [] }),\n isMainnet && WAL_COIN_TYPE\n ? suiClient.getCoins({\n owner: currentAccount.address,\n coinType: WAL_COIN_TYPE\n })\n : Promise.resolve({ data: [] })\n ])\n\n const usdcBalance =\n usdcCoins.data?.reduce((sum, coin) => sum + BigInt(coin.balance), 0n) ??\n 0n\n const walBalance =\n walCoins.data?.reduce((sum, coin) => sum + BigInt(coin.balance), 0n) ??\n 0n\n\n // Calculate required amount with buffer (5%)\n const requiredAmount = BigInt(Math.floor(totalPrice * 1.05))\n\n // On mainnet, check if we need to swap WAL → USDC\n if (isMainnet && coinType === 'USDC') {\n if (usdcBalance < requiredAmount) {\n if (!aggregatorClient || !WAL_COIN_TYPE) {\n throw new Error(\n 'Swap client not ready. Please try again in a few seconds.'\n )\n }\n\n if (walBalance === 0n) {\n throw new Error(\n `Insufficient USDC balance. Need approximately ${(Number(requiredAmount) / 1_000_000).toFixed(2)} USDC, but have ${(Number(usdcBalance) / 1_000_000).toFixed(2)} USDC. No WAL available to swap.`\n )\n }\n\n const missingUsdc = requiredAmount - usdcBalance\n\n // Estimate WAL needed using live rate\n const baseWalAtomic = 1_000_000_000n // 1 WAL (9 decimals)\n const rateRouter = await aggregatorClient.findRouters({\n from: WAL_COIN_TYPE,\n target: suinsClient.config.coins.USDC.type,\n amount: new BN(baseWalAtomic.toString()),\n byAmountIn: true,\n providers: ['CETUS']\n })\n\n if (!rateRouter || rateRouter.error || !rateRouter.amountOut) {\n const msg =\n rateRouter?.error?.msg ||\n 'Failed to fetch WAL → USDC rate from aggregator.'\n throw new Error(msg)\n }\n\n const rawAmountOut = rateRouter.amountOut\n if (!rawAmountOut) {\n throw new Error('Failed to get amount out from rate router')\n }\n const usdcOutForOneWal = BigInt(\n rawAmountOut instanceof BN\n ? rawAmountOut.toString()\n : new BN(String(rawAmountOut)).toString()\n )\n\n if (usdcOutForOneWal === 0n) {\n throw new Error('Aggregator returned zero USDC for 1 WAL.')\n }\n\n const exchangeRate = Number(baseWalAtomic) / Number(usdcOutForOneWal)\n const estimatedWalNeeded =\n missingUsdc * BigInt(Math.ceil(exchangeRate))\n\n if (walBalance < estimatedWalNeeded) {\n throw new Error(\n `Insufficient WAL balance. Need approximately ${(Number(estimatedWalNeeded) / 1_000_000_000).toFixed(4)} WAL to swap for USDC.`\n )\n }\n\n // Perform WAL → USDC swap\n setIsSwapping(true)\n try {\n const amountWalBN = new BN(estimatedWalNeeded.toString())\n\n const routerResult = await aggregatorClient.findRouters({\n from: WAL_COIN_TYPE,\n target: suinsClient.config.coins.USDC.type,\n amount: amountWalBN,\n byAmountIn: true,\n providers: ['CETUS']\n })\n\n if (!routerResult || (routerResult as { error?: unknown }).error) {\n const msg =\n (routerResult as { error?: { msg?: string } })?.error?.msg ||\n 'Failed to find route to swap WAL to USDC for registration.'\n throw new Error(msg)\n }\n\n if (\n (routerResult as { insufficientLiquidity?: boolean })\n .insufficientLiquidity\n ) {\n throw new Error(\n 'Insufficient liquidity to swap WAL to USDC for this registration amount.'\n )\n }\n\n const swapTx = new Transaction()\n swapTx.setSenderIfNotSet(currentAccount.address)\n\n await aggregatorClient.fastRouterSwap({\n router: routerResult,\n txb: swapTx,\n slippage: 0.005 // 0.5% slippage\n })\n\n swapTx.setGasBudget(50_000_000)\n\n const swapDigest = await txExecutor.execute({\n transaction: swapTx,\n description: 'Swap WAL to USDC for SuiNS registration'\n })\n\n // Wait for swap transaction to complete\n await suiClient.waitForTransaction({ digest: swapDigest })\n\n // Refresh USDC balance after swap\n const usdcCoinsAfter = await suiClient.getCoins({\n owner: currentAccount.address,\n coinType: suinsClient.config.coins.USDC.type\n })\n\n const usdcBalanceAfter =\n usdcCoinsAfter.data?.reduce(\n (sum, coin) => sum + BigInt(coin.balance),\n 0n\n ) ?? 0n\n\n if (usdcBalanceAfter < requiredAmount) {\n throw new Error(\n 'Swap completed but still insufficient USDC balance. Please try again.'\n )\n }\n } finally {\n setIsSwapping(false)\n }\n }\n }\n\n // Get user's coins for payment\n const coins = await suiClient.getCoins({\n owner: currentAccount.address,\n coinType: coinConfig.type\n })\n\n if (coins.data.length === 0) {\n throw new Error(`No ${coinType} coins found in your wallet`)\n }\n\n // Calculate max payment with buffer (5%)\n const maxPaymentAmount = Math.floor(totalPrice * 1.05)\n const totalBalance = coins.data.reduce(\n (sum, coin) => sum + BigInt(coin.balance),\n 0n\n )\n\n const gasReserve = 10_000_000n\n const requiredBalance = BigInt(maxPaymentAmount) + gasReserve\n\n if (totalBalance < requiredBalance) {\n throw new Error(\n `Insufficient balance. Need approximately ${(Number(requiredBalance) / 1_000_000_000).toFixed(4)} ${coinType}`\n )\n }\n\n // Create transaction for registration\n const transaction = new Transaction()\n transaction.setSenderIfNotSet(currentAccount.address)\n\n const suinsTransaction = new SuinsTransaction(suinsClient, transaction)\n\n // Prepare payment coin\n let paymentCoin:\n | ReturnType<typeof transaction.object>\n | typeof transaction.gas\n\n if (coinType === 'SUI') {\n // For SUI, use transaction.gas directly\n paymentCoin = transaction.gas\n } else {\n // For USDC, need SUI for gas separately\n const suiCoins = await suiClient.getCoins({\n owner: currentAccount.address,\n coinType: '0x2::sui::SUI'\n })\n\n if (suiCoins.data.length === 0) {\n throw new Error('No SUI coins found for gas fees')\n }\n\n // Merge payment coins if multiple\n const primaryCoin = coins.data[0].coinObjectId\n if (coins.data.length > 1) {\n transaction.mergeCoins(\n transaction.object(primaryCoin),\n coins.data\n .slice(1)\n .map(coin => transaction.object(coin.coinObjectId))\n )\n }\n\n paymentCoin = transaction.object(primaryCoin)\n\n // Merge SUI coins for gas if multiple\n if (suiCoins.data.length > 1) {\n transaction.mergeCoins(\n transaction.object(suiCoins.data[0].coinObjectId),\n suiCoins.data\n .slice(1)\n .map(coin => transaction.object(coin.coinObjectId))\n )\n }\n }\n\n // Prepare registration parameters\n const registerParams: {\n domain: string\n years: number\n coinConfig: typeof coinConfig\n coin: typeof paymentCoin\n priceInfoObjectId?: string\n } = {\n domain: fullName,\n years,\n coinConfig,\n coin: paymentCoin\n }\n\n // Get price info object if feed is available\n if (coinConfig.feed) {\n const priceInfoObjectId = (\n await suinsClient.getPriceInfoObject(transaction, coinConfig.feed)\n )[0]\n registerParams.priceInfoObjectId = priceInfoObjectId\n }\n\n // Register the domain\n const nft = suinsTransaction.register(registerParams)\n\n // Set target address to current account\n suinsTransaction.setTargetAddress({\n nft,\n address: currentAccount.address\n })\n\n // Transfer the NFT to the user\n transaction.transferObjects([nft], currentAccount.address)\n\n // Set gas budget\n transaction.setGasBudget(50_000_000)\n\n // Execute transaction using txExecutor\n if (!txExecutor) {\n throw new Error('Transaction executor not available')\n }\n\n const digest = await txExecutor.execute({\n transaction,\n description: 'Register SuiNS domain'\n })\n\n // Wait for transaction to complete\n await suiClient.waitForTransaction({ digest })\n\n // Invalidate SuiNS domains query to refresh the list\n if (currentAccount?.address) {\n queryClient.invalidateQueries({\n queryKey: ['suins-domains', currentAccount.address, network]\n })\n }\n\n return true\n } catch (err) {\n console.error('Error registering domain:', err)\n setError(err instanceof Error ? err.message : 'Failed to register domain')\n return false\n } finally {\n setIsRegistering(false)\n }\n }, [\n suinsClient,\n currentAccount,\n isAvailable,\n normalizedName,\n fullName,\n selectedYears,\n txExecutor,\n isTestnet,\n isMainnet,\n WAL_COIN_TYPE,\n aggregatorClient,\n suiClient,\n queryClient,\n network\n ])\n\n const reset = useCallback(() => {\n setSearchName('')\n setIsAvailable(null)\n setEstimatedPrice(null)\n setError(null)\n setIsSearching(false)\n setIsRegistering(false)\n setIsSwapping(false)\n setSelectedYears(1)\n setPricePerYear(null)\n setPricePerYearFormatted(null)\n setPricePerYearUsdc(null)\n setTotalPriceUsdc(null)\n if (priceRefreshIntervalRef.current) {\n clearInterval(priceRefreshIntervalRef.current)\n priceRefreshIntervalRef.current = null\n }\n }, [])\n\n return {\n // State\n searchName,\n setSearchName,\n isSearching,\n isAvailable,\n isRegistering,\n isSwapping,\n estimatedPrice,\n error,\n normalizedName,\n fullName,\n selectedYears,\n setSelectedYears,\n pricePerYear,\n pricePerYearFormatted,\n pricePerYearUsdc,\n totalPrice,\n totalPriceFormatted,\n totalPriceUsdc,\n expirationDate,\n // Actions\n handleSearch,\n handleRegister,\n reset\n }\n}\n","import {\n type ISignAndExecuteTransaction,\n type ISponsorConfig,\n WalrusSiteBuilderSdk,\n type WSResources\n} from '@cmdoss/walrus-site-builder'\nimport type { SuiClient } from '@mysten/sui/client'\nimport type { WalletAccount } from '@mysten/wallet-standard'\nimport type { WalrusClient } from '@mysten/walrus'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { useMutation } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { queryKeys } from '~/queries/keys'\n\nexport interface UseUpdateSiteMetadataParams {\n siteId: string\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n walrusClient: WalrusClient\n }\n currentAccount: WalletAccount | null\n signAndExecuteTransaction: ISignAndExecuteTransaction\n sponsorConfig?: ISponsorConfig\n}\n\nexport interface UpdateSiteMetadataInput {\n siteName: string\n metadata: WSResources['metadata']\n}\n\nexport function useUpdateSiteMetadata({\n siteId,\n clients: { suiClient, queryClient, walrusClient },\n currentAccount,\n signAndExecuteTransaction,\n sponsorConfig\n}: UseUpdateSiteMetadataParams) {\n const network = suiClient.network\n\n // Create SDK instance\n const sdk = useMemo(() => {\n if (!currentAccount || !suiClient || !walrusClient) return null\n\n return new WalrusSiteBuilderSdk(\n walrusClient,\n suiClient,\n currentAccount.address,\n signAndExecuteTransaction,\n sponsorConfig\n )\n }, [\n currentAccount,\n suiClient,\n walrusClient,\n signAndExecuteTransaction,\n sponsorConfig\n ])\n\n // Mutation for updating site metadata\n const mutation = useMutation(\n {\n mutationFn: async ({\n siteName,\n metadata\n }: UpdateSiteMetadataInput): Promise<string> => {\n if (!sdk) {\n throw new Error('SDK not initialized')\n }\n\n const digest = await sdk.updateSiteMetadata(siteId, siteName, metadata)\n return digest\n },\n onSuccess: digest => {\n // Invalidate site query to refetch updated data\n queryClient.invalidateQueries({\n queryKey: queryKeys.walrusSite(siteId)\n })\n\n // Also invalidate sites list if needed\n if (currentAccount?.address) {\n queryClient.invalidateQueries({\n queryKey: queryKeys.walrusSites(currentAccount.address, network)\n })\n }\n\n console.log('✅ Site metadata updated successfully:', digest)\n },\n onError: error => {\n console.error('❌ Failed to update site metadata:', error)\n }\n },\n queryClient\n )\n\n return {\n updateSiteMetadata: mutation.mutateAsync,\n isUpdating: mutation.isPending,\n error: mutation.error,\n isSuccess: mutation.isSuccess,\n data: mutation.data\n }\n}\n","import { ZenFsFileManager } from '@cmdoss/file-manager'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { useEffect, useState } from 'react'\n\nexport function useZenFsWorkspace(\n workspaceDir = '/workspace',\n mountDir = '/workspace',\n queryClient: QueryClient\n) {\n const [loading, setLoading] = useState(true)\n const [fileManager, setFileManager] = useState<ZenFsFileManager | null>(null)\n\n // Initialize ZenFS and load existing files\n useEffect(() => {\n setLoading(true)\n console.log('Initializing ZenFS FileManager at', workspaceDir)\n const fm = new ZenFsFileManager(workspaceDir, mountDir)\n setFileManager(fm)\n\n fm.initialize()\n .catch(() => {\n // Ignore errors during initialization\n })\n .then(async () => {\n // Invalidate queries to refresh file listings\n await queryClient.invalidateQueries({\n queryKey: ['zenfs', workspaceDir]\n })\n })\n .finally(() => setLoading(false))\n // Cleanup on unmount\n }, [workspaceDir, mountDir, queryClient])\n\n return {\n loading,\n fileManager\n }\n}\n","import type { WalrusClient } from '@mysten/walrus'\nimport { type QueryClient, useQuery } from '@tanstack/react-query'\nimport { queryKeys } from './keys'\n\nexport function useStorageCostQuery(\n fileSize: number | null,\n epochs: number,\n clients: {\n queryClient: QueryClient\n walrusClient: WalrusClient\n }\n) {\n const { walrusClient, queryClient } = clients\n return useQuery(\n {\n queryKey: queryKeys.storageCost(fileSize, epochs),\n queryFn: async () => {\n if (!walrusClient) throw new Error('Walrus client not available')\n if (fileSize === null) throw new Error('Invalid file size')\n const storageCost = await walrusClient.storageCost(fileSize, epochs)\n return {\n storageCost: storageCost.storageCost.toString(),\n writeCost: storageCost.writeCost.toString(),\n totalCost: storageCost.totalCost.toString()\n }\n },\n enabled:\n !!walrusClient && fileSize !== null && fileSize > 0 && epochs > 0,\n staleTime: 5 * 60 * 1000 // 5 minutes\n },\n queryClient\n )\n}\n","'use strict';\n\nfunction toPrimitive(t, r) {\n if (\"object\" != typeof t || !t) return t;\n var e = t[Symbol.toPrimitive];\n if (void 0 !== e) {\n var i = e.call(t, r || \"default\");\n if (\"object\" != typeof i) return i;\n throw new TypeError(\"@@toPrimitive must return a primitive value.\");\n }\n return (\"string\" === r ? String : Number)(t);\n}\n\nfunction toPropertyKey(t) {\n var i = toPrimitive(t, \"string\");\n return \"symbol\" == typeof i ? i : String(i);\n}\n\nfunction _defineProperty(obj, key, value) {\n key = toPropertyKey(key);\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n return obj;\n}\n\nfunction ownKeys(e, r) {\n var t = Object.keys(e);\n if (Object.getOwnPropertySymbols) {\n var o = Object.getOwnPropertySymbols(e);\n r && (o = o.filter(function (r) {\n return Object.getOwnPropertyDescriptor(e, r).enumerable;\n })), t.push.apply(t, o);\n }\n return t;\n}\nfunction _objectSpread2(e) {\n for (var r = 1; r < arguments.length; r++) {\n var t = null != arguments[r] ? arguments[r] : {};\n r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {\n _defineProperty(e, r, t[r]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {\n Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));\n });\n }\n return e;\n}\n\nfunction mapValues(input, fn) {\n var result = {};\n for (var _key in input) {\n result[_key] = fn(input[_key], _key);\n }\n return result;\n}\n\nvar shouldApplyCompound = (compoundCheck, selections, defaultVariants) => {\n for (var key of Object.keys(compoundCheck)) {\n var _selections$key;\n if (compoundCheck[key] !== ((_selections$key = selections[key]) !== null && _selections$key !== void 0 ? _selections$key : defaultVariants[key])) {\n return false;\n }\n }\n return true;\n};\nvar createRuntimeFn = config => {\n var runtimeFn = options => {\n var className = config.defaultClassName;\n var selections = _objectSpread2(_objectSpread2({}, config.defaultVariants), options);\n for (var variantName in selections) {\n var _selections$variantNa;\n var variantSelection = (_selections$variantNa = selections[variantName]) !== null && _selections$variantNa !== void 0 ? _selections$variantNa : config.defaultVariants[variantName];\n if (variantSelection != null) {\n var selection = variantSelection;\n if (typeof selection === 'boolean') {\n // @ts-expect-error\n selection = selection === true ? 'true' : 'false';\n }\n var selectionClassName =\n // @ts-expect-error\n config.variantClassNames[variantName][selection];\n if (selectionClassName) {\n className += ' ' + selectionClassName;\n }\n }\n }\n for (var [compoundCheck, compoundClassName] of config.compoundVariants) {\n if (shouldApplyCompound(compoundCheck, selections, config.defaultVariants)) {\n className += ' ' + compoundClassName;\n }\n }\n return className;\n };\n runtimeFn.variants = () => Object.keys(config.variantClassNames);\n runtimeFn.classNames = {\n get base() {\n return config.defaultClassName.split(' ')[0];\n },\n get variants() {\n return mapValues(config.variantClassNames, classNames => mapValues(classNames, className => className.split(' ')[0]));\n }\n };\n return runtimeFn;\n};\n\nexports.createRuntimeFn = createRuntimeFn;\nexports.mapValues = mapValues;\n","'use strict';\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar createRuntimeFn_dist_vanillaExtractRecipesCreateRuntimeFn = require('../../dist/createRuntimeFn-166334d7.cjs.prod.js');\n\n\n\nexports.createRuntimeFn = createRuntimeFn_dist_vanillaExtractRecipesCreateRuntimeFn.createRuntimeFn;\n","'use strict';\n\nfunction toPrimitive(t, r) {\n if (\"object\" != typeof t || !t) return t;\n var e = t[Symbol.toPrimitive];\n if (void 0 !== e) {\n var i = e.call(t, r || \"default\");\n if (\"object\" != typeof i) return i;\n throw new TypeError(\"@@toPrimitive must return a primitive value.\");\n }\n return (\"string\" === r ? String : Number)(t);\n}\n\nfunction toPropertyKey(t) {\n var i = toPrimitive(t, \"string\");\n return \"symbol\" == typeof i ? i : String(i);\n}\n\nfunction _defineProperty(obj, key, value) {\n key = toPropertyKey(key);\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n return obj;\n}\n\nfunction ownKeys(e, r) {\n var t = Object.keys(e);\n if (Object.getOwnPropertySymbols) {\n var o = Object.getOwnPropertySymbols(e);\n r && (o = o.filter(function (r) {\n return Object.getOwnPropertyDescriptor(e, r).enumerable;\n })), t.push.apply(t, o);\n }\n return t;\n}\nfunction _objectSpread2(e) {\n for (var r = 1; r < arguments.length; r++) {\n var t = null != arguments[r] ? arguments[r] : {};\n r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {\n _defineProperty(e, r, t[r]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {\n Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));\n });\n }\n return e;\n}\n\nfunction mapValues(input, fn) {\n var result = {};\n for (var _key in input) {\n result[_key] = fn(input[_key], _key);\n }\n return result;\n}\n\nvar shouldApplyCompound = (compoundCheck, selections, defaultVariants) => {\n for (var key of Object.keys(compoundCheck)) {\n var _selections$key;\n if (compoundCheck[key] !== ((_selections$key = selections[key]) !== null && _selections$key !== void 0 ? _selections$key : defaultVariants[key])) {\n return false;\n }\n }\n return true;\n};\nvar createRuntimeFn = config => {\n var runtimeFn = options => {\n var className = config.defaultClassName;\n var selections = _objectSpread2(_objectSpread2({}, config.defaultVariants), options);\n for (var variantName in selections) {\n var _selections$variantNa;\n var variantSelection = (_selections$variantNa = selections[variantName]) !== null && _selections$variantNa !== void 0 ? _selections$variantNa : config.defaultVariants[variantName];\n if (variantSelection != null) {\n var selection = variantSelection;\n if (typeof selection === 'boolean') {\n // @ts-expect-error\n selection = selection === true ? 'true' : 'false';\n }\n var selectionClassName =\n // @ts-expect-error\n config.variantClassNames[variantName][selection];\n if (selectionClassName) {\n className += ' ' + selectionClassName;\n }\n }\n }\n for (var [compoundCheck, compoundClassName] of config.compoundVariants) {\n if (shouldApplyCompound(compoundCheck, selections, config.defaultVariants)) {\n className += ' ' + compoundClassName;\n }\n }\n return className;\n };\n runtimeFn.variants = () => Object.keys(config.variantClassNames);\n runtimeFn.classNames = {\n get base() {\n return config.defaultClassName.split(' ')[0];\n },\n get variants() {\n return mapValues(config.variantClassNames, classNames => mapValues(classNames, className => className.split(' ')[0]));\n }\n };\n return runtimeFn;\n};\n\nexports.createRuntimeFn = createRuntimeFn;\nexports.mapValues = mapValues;\n","'use strict';\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar createRuntimeFn_dist_vanillaExtractRecipesCreateRuntimeFn = require('../../dist/createRuntimeFn-2f250aaf.cjs.dev.js');\n\n\n\nexports.createRuntimeFn = createRuntimeFn_dist_vanillaExtractRecipesCreateRuntimeFn.createRuntimeFn;\n","'use strict';\n\nif (process.env.NODE_ENV === \"production\") {\n module.exports = require(\"./vanilla-extract-recipes-createRuntimeFn.cjs.prod.js\");\n} else {\n module.exports = require(\"./vanilla-extract-recipes-createRuntimeFn.cjs.dev.js\");\n}\n","import { style } from '@vanilla-extract/css'\nimport { recipe } from '@vanilla-extract/recipes'\nimport { themeVars } from '~/theme.css'\n\nexport const banner = recipe({\n base: {\n position: 'relative',\n isolation: 'isolate',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'space-between',\n gap: themeVars.spacing.xs,\n overflow: 'hidden',\n borderRadius: themeVars.radius.lg,\n marginTop: themeVars.spacing.sm,\n borderWidth: '1px',\n borderStyle: 'solid',\n paddingTop: themeVars.spacing.xs,\n paddingBottom: themeVars.spacing.xs,\n paddingLeft: themeVars.spacing.sm,\n paddingRight: '3rem',\n '@media': {\n 'screen and (min-width: 640px)': {\n flexDirection: 'row',\n alignItems: 'center',\n paddingTop: themeVars.spacing.sm,\n paddingBottom: themeVars.spacing.sm\n }\n }\n },\n variants: {\n variant: {\n info: {\n background:\n 'linear-gradient(to right, oklch(0.951 0.026 236.824 / 0.8), oklch(0.882 0.059 254.128 / 0.8))',\n borderColor: 'oklch(0.546 0.245 262.881 / 0.15)',\n selectors: {\n '.dark &': {\n background:\n 'linear-gradient(to right, oklch(0.282 0.091 267.935 / 0.6), oklch(0.379 0.146 265.522 / 0.6))',\n borderColor: 'oklch(0.746 0.16 232.661 / 0.2)'\n }\n }\n },\n success: {\n background:\n 'linear-gradient(to right, oklch(0.95 0.052 163.051 / 0.8), oklch(0.925 0.084 155.995 / 0.8))',\n borderColor: 'oklch(0.627 0.194 149.214 / 0.15)',\n selectors: {\n '.dark &': {\n background:\n 'linear-gradient(to right, oklch(0.262 0.051 172.552 / 0.6), oklch(0.393 0.095 152.535 / 0.6))',\n borderColor: 'oklch(0.792 0.209 151.711 / 0.2)'\n }\n }\n },\n warning: {\n background:\n 'linear-gradient(to right, oklch(0.962 0.059 95.617 / 0.8), oklch(0.973 0.071 103.193 / 0.8))',\n borderColor: 'oklch(0.666 0.179 58.318 / 0.15)',\n selectors: {\n '.dark &': {\n background:\n 'linear-gradient(to right, oklch(0.279 0.077 45.635 / 0.6), oklch(0.421 0.095 57.708 / 0.6))',\n borderColor: 'oklch(0.828 0.189 84.429 / 0.2)'\n }\n }\n },\n alert: {\n background:\n 'linear-gradient(to right, oklch(0.954 0.038 75.164 / 0.8), oklch(0.954 0.038 75.164 / 0.8))',\n borderColor: 'oklch(0.646 0.222 41.116 / 0.15)',\n selectors: {\n '.dark &': {\n background:\n 'linear-gradient(to right, oklch(0.266 0.079 36.259 / 0.6), oklch(0.408 0.123 38.172 / 0.6))',\n borderColor: 'oklch(0.75 0.183 55.934 / 0.2)'\n }\n }\n },\n error: {\n background:\n 'linear-gradient(to right, oklch(0.936 0.032 17.717 / 0.8), oklch(0.892 0.058 10.001 / 0.8))',\n borderColor: 'oklch(0.577 0.245 27.325 / 0.15)',\n selectors: {\n '.dark &': {\n background:\n 'linear-gradient(to right, oklch(0.258 0.092 26.042 / 0.6), oklch(0.41 0.159 10.272 / 0.6))',\n borderColor: 'oklch(0.704 0.191 22.216 / 0.2)'\n }\n }\n }\n }\n },\n defaultVariants: {\n variant: 'info'\n }\n})\n\nexport const gridPattern = style({\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n color: 'oklch(0 0 0 / 0.3)',\n mixBlendMode: 'overlay',\n maskImage: 'linear-gradient(to right, oklch(0 0 0), transparent)',\n '@media': {\n 'screen and (min-width: 768px)': {\n maskImage: 'linear-gradient(to right, oklch(0 0 0) 60%, transparent)'\n }\n },\n selectors: {\n '.dark &': {\n color: 'oklch(1 0 0 / 0.2)'\n }\n }\n})\n\nexport const content = style({\n display: 'flex',\n alignItems: 'center',\n gap: themeVars.spacing.sm,\n position: 'relative',\n zIndex: 10\n})\n\nexport const iconContainer = recipe({\n base: {\n display: 'none',\n borderRadius: '9999px',\n borderWidth: '1px',\n borderStyle: 'solid',\n padding: themeVars.spacing.xs,\n boxShadow: 'inset 0 0 1px 1px oklch(1 0 0)',\n '@media': {\n 'screen and (min-width: 640px)': {\n display: 'block'\n }\n },\n selectors: {\n '.dark &': {\n boxShadow: 'inset 0 0 1px 1px oklch(1 0 0 / 0.1)'\n }\n }\n },\n variants: {\n variant: {\n info: {\n backgroundColor: 'oklch(1 0 0 / 0.5)',\n borderColor: 'oklch(0.546 0.245 262.881 / 0.5)',\n selectors: {\n '.dark &': {\n backgroundColor: 'oklch(0.282 0.091 267.935 / 0.4)',\n borderColor: 'oklch(0.746 0.16 232.661 / 0.4)'\n }\n }\n },\n success: {\n backgroundColor: 'oklch(1 0 0 / 0.5)',\n borderColor: 'oklch(0.627 0.194 149.214 / 0.5)',\n selectors: {\n '.dark &': {\n backgroundColor: 'oklch(0.262 0.051 172.552 / 0.4)',\n borderColor: 'oklch(0.792 0.209 151.711 / 0.4)'\n }\n }\n },\n warning: {\n backgroundColor: 'oklch(1 0 0 / 0.5)',\n borderColor: 'oklch(0.666 0.179 58.318 / 0.5)',\n selectors: {\n '.dark &': {\n backgroundColor: 'oklch(0.279 0.077 45.635 / 0.4)',\n borderColor: 'oklch(0.828 0.189 84.429 / 0.4)'\n }\n }\n },\n alert: {\n backgroundColor: 'oklch(1 0 0 / 0.5)',\n borderColor: 'oklch(0.646 0.222 41.116 / 0.5)',\n selectors: {\n '.dark &': {\n backgroundColor: 'oklch(0.266 0.079 36.259 / 0.4)',\n borderColor: 'oklch(0.75 0.183 55.934 / 0.4)'\n }\n }\n },\n error: {\n backgroundColor: 'oklch(1 0 0 / 0.5)',\n borderColor: 'oklch(0.577 0.245 27.325 / 0.5)',\n selectors: {\n '.dark &': {\n backgroundColor: 'oklch(0.258 0.092 26.042 / 0.4)',\n borderColor: 'oklch(0.704 0.191 22.216 / 0.4)'\n }\n }\n }\n }\n }\n})\n\nexport const icon = recipe({\n base: {},\n variants: {\n variant: {\n info: {\n color: 'oklch(0.424 0.199 265.638)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.809 0.105 251.813)'\n }\n }\n },\n success: {\n color: 'oklch(0.448 0.119 151.328)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.845 0.143 164.978)'\n }\n }\n },\n warning: {\n color: 'oklch(0.473 0.137 46.201)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.879 0.169 91.605)'\n }\n }\n },\n alert: {\n color: 'oklch(0.47 0.157 37.304)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.837 0.128 66.29)'\n }\n }\n },\n error: {\n color: 'oklch(0.444 0.177 26.899)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.808 0.114 19.571)'\n }\n }\n }\n }\n }\n})\n\nexport const textContainer = style({\n display: 'flex',\n flexDirection: 'column'\n})\n\nexport const title = recipe({\n base: {\n fontSize: '0.875rem',\n fontWeight: 600\n },\n variants: {\n variant: {\n info: {\n color: 'oklch(0.379 0.146 265.522)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.932 0.032 255.585)'\n }\n }\n },\n success: {\n color: 'oklch(0.393 0.095 152.535)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.962 0.044 156.743)'\n }\n }\n },\n warning: {\n color: 'oklch(0.414 0.112 45.904)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.962 0.059 95.617)'\n }\n }\n },\n alert: {\n color: 'oklch(0.408 0.123 38.172)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.954 0.038 75.164)'\n }\n }\n },\n error: {\n color: 'oklch(0.396 0.141 25.723)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.936 0.032 17.717)'\n }\n }\n }\n }\n }\n})\n\nexport const description = recipe({\n base: {\n fontSize: '0.75rem'\n },\n variants: {\n variant: {\n info: {\n color: 'oklch(0.424 0.199 265.638 / 0.8)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.882 0.059 254.128 / 0.7)'\n }\n }\n },\n success: {\n color: 'oklch(0.448 0.119 151.328 / 0.8)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.905 0.093 164.15 / 0.7)'\n }\n }\n },\n warning: {\n color: 'oklch(0.473 0.137 46.201 / 0.8)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.924 0.12 95.746 / 0.7)'\n }\n }\n },\n alert: {\n color: 'oklch(0.47 0.157 37.304 / 0.8)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.901 0.076 70.697 / 0.7)'\n }\n }\n },\n error: {\n color: 'oklch(0.444 0.177 26.899 / 0.8)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.885 0.062 18.334 / 0.7)'\n }\n }\n }\n }\n }\n})\n\nexport const closeButton = recipe({\n base: {\n position: 'absolute',\n right: themeVars.spacing.sm,\n top: '50%',\n transform: 'translateY(-50%)',\n transition: 'colors 0.2s ease-in-out',\n cursor: 'pointer',\n border: 'none',\n background: 'transparent',\n padding: 0,\n '@media': {\n 'screen and (min-width: 640px)': {\n position: 'relative',\n right: 0,\n transform: 'none'\n }\n }\n },\n variants: {\n variant: {\n info: {\n color: 'oklch(0.546 0.245 262.881 / 0.5)',\n ':hover': {\n color: 'oklch(0.546 0.245 262.881)'\n },\n selectors: {\n '.dark &': {\n color: 'oklch(0.746 0.16 232.661 / 0.5)'\n },\n '.dark &:hover': {\n color: 'oklch(0.809 0.105 251.813)'\n }\n }\n },\n success: {\n color: 'oklch(0.627 0.194 149.214 / 0.5)',\n ':hover': {\n color: 'oklch(0.627 0.194 149.214)'\n },\n selectors: {\n '.dark &': {\n color: 'oklch(0.792 0.209 151.711 / 0.5)'\n },\n '.dark &:hover': {\n color: 'oklch(0.845 0.143 164.978)'\n }\n }\n },\n warning: {\n color: 'oklch(0.666 0.179 58.318 / 0.5)',\n ':hover': {\n color: 'oklch(0.666 0.179 58.318)'\n },\n selectors: {\n '.dark &': {\n color: 'oklch(0.828 0.189 84.429 / 0.5)'\n },\n '.dark &:hover': {\n color: 'oklch(0.879 0.169 91.605)'\n }\n }\n },\n alert: {\n color: 'oklch(0.646 0.222 41.116 / 0.5)',\n ':hover': {\n color: 'oklch(0.646 0.222 41.116)'\n },\n selectors: {\n '.dark &': {\n color: 'oklch(0.75 0.183 55.934 / 0.5)'\n },\n '.dark &:hover': {\n color: 'oklch(0.837 0.128 66.29)'\n }\n }\n },\n error: {\n color: 'oklch(0.577 0.245 27.325 / 0.5)',\n ':hover': {\n color: 'oklch(0.577 0.245 27.325)'\n },\n selectors: {\n '.dark &': {\n color: 'oklch(0.704 0.191 22.216 / 0.5)'\n },\n '.dark &:hover': {\n color: 'oklch(0.808 0.114 19.571)'\n }\n }\n }\n }\n }\n})\n\nexport const closeIcon = style({\n width: '1.25rem',\n height: '1.25rem'\n})\n\nexport const link = recipe({\n base: {\n fontWeight: 600,\n textDecoration: 'underline',\n textUnderlineOffset: '2px',\n transition: 'opacity 0.2s ease-in-out',\n ':hover': {\n opacity: 0.8\n }\n },\n variants: {\n variant: {\n info: {\n color: 'oklch(0.424 0.199 265.638)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.809 0.105 251.813)'\n }\n }\n },\n success: {\n color: 'oklch(0.448 0.119 151.328)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.845 0.143 164.978)'\n }\n }\n },\n warning: {\n color: 'oklch(0.473 0.137 46.201)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.879 0.169 91.605)'\n }\n }\n },\n alert: {\n color: 'oklch(0.47 0.157 37.304)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.837 0.128 66.29)'\n }\n }\n },\n error: {\n color: 'oklch(0.444 0.177 26.899)',\n selectors: {\n '.dark &': {\n color: 'oklch(0.808 0.114 19.571)'\n }\n }\n }\n }\n }\n})\n","import {\n AlertCircle,\n AlertTriangle,\n CheckCircle,\n Link2,\n XCircle\n} from 'lucide-react'\nimport type { FC, ReactNode } from 'react'\nimport {\n banner,\n closeButton,\n closeIcon,\n content,\n description,\n gridPattern,\n icon,\n iconContainer,\n link,\n textContainer,\n title\n} from './Banner.css'\n\ntype BannerVariant = 'info' | 'success' | 'warning' | 'alert' | 'error'\n\nexport interface BannerProps {\n title: string\n description?: string\n icon?: ReactNode\n showIcon?: boolean\n className?: string\n variant?: BannerVariant\n onClose?: () => void\n url?: string\n urlName?: string\n}\n\nconst defaultIcons: Record<BannerVariant, ReactNode> = {\n info: <Link2 style={{ width: '1rem', height: '1rem' }} strokeWidth={1.5} />,\n success: (\n <CheckCircle style={{ width: '1rem', height: '1rem' }} strokeWidth={1.5} />\n ),\n warning: (\n <AlertTriangle\n style={{ width: '1rem', height: '1rem' }}\n strokeWidth={1.5}\n />\n ),\n alert: (\n <AlertCircle style={{ width: '1rem', height: '1rem' }} strokeWidth={1.5} />\n ),\n error: <XCircle style={{ width: '1rem', height: '1rem' }} strokeWidth={1.5} />\n}\n\nexport const Banner: FC<BannerProps> = ({\n title: titleText,\n description: descriptionText,\n icon: customIcon,\n showIcon = true,\n className = '',\n variant = 'info',\n onClose,\n url,\n urlName\n}) => {\n return (\n <div className={`${banner({ variant })} ${className}`}>\n {/* Grid pattern overlay */}\n <svg\n className={gridPattern}\n width=\"100%\"\n height=\"100%\"\n aria-hidden=\"true\"\n >\n <defs>\n <pattern\n id={`grid-pattern-${variant}`}\n x=\"-1\"\n y=\"-2\"\n width=\"13\"\n height=\"13\"\n patternUnits=\"userSpaceOnUse\"\n >\n <path\n d=\"M 13 0 L 0 0 0 13\"\n fill=\"transparent\"\n stroke=\"currentColor\"\n strokeWidth=\"1\"\n >\n <title>Grid pattern</title>\n </path>\n </pattern>\n </defs>\n <rect\n fill={`url(#grid-pattern-${variant})`}\n width=\"100%\"\n height=\"100%\"\n />\n </svg>\n\n {/* Content */}\n <div className={content}>\n {showIcon && (\n <div className={iconContainer({ variant })}>\n <div className={icon({ variant })}>\n {customIcon || defaultIcons[variant]}\n </div>\n </div>\n )}\n <div className={textContainer}>\n <h3 className={title({ variant })}>{titleText}</h3>\n {descriptionText && (\n <p className={description({ variant })}>\n {descriptionText}\n {url && urlName && (\n <>\n {' '}\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={link({ variant })}\n >\n {urlName}\n </a>\n </>\n )}\n </p>\n )}\n </div>\n </div>\n\n {/* Close button */}\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n className={closeButton({ variant })}\n aria-label=\"Close banner\"\n >\n <svg\n className={closeIcon}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n >\n <title>Close icon</title>\n </path>\n </svg>\n </button>\n )}\n </div>\n )\n}\n","import { recipe } from '@vanilla-extract/recipes'\nimport { themeVars } from '~/theme.css'\n\nexport const button = recipe({\n base: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: themeVars.spacing.sm,\n borderRadius: themeVars.radius.md,\n fontSize: '0.875rem',\n fontWeight: 500,\n transition: 'all 0.2s ease-in-out',\n cursor: 'pointer',\n border: 'none',\n outline: 'none',\n whiteSpace: 'nowrap',\n ':disabled': {\n opacity: 0.5,\n cursor: 'not-allowed',\n pointerEvents: 'none'\n },\n ':focus-visible': {\n outline: `2px solid ${themeVars.colors.primary}`,\n outlineOffset: '2px'\n }\n },\n variants: {\n variant: {\n default: {\n backgroundColor: themeVars.colors.primary,\n color: themeVars.colors.primaryForeground,\n ':hover': {\n opacity: 0.9\n }\n },\n outline: {\n backgroundColor: 'transparent',\n border: `1px solid ${themeVars.colors.border}`,\n color: themeVars.colors.foreground,\n ':hover': {\n backgroundColor: themeVars.colors.accent,\n color: themeVars.colors.accentForeground\n }\n },\n ghost: {\n backgroundColor: 'transparent',\n color: themeVars.colors.foreground,\n ':hover': {\n backgroundColor: themeVars.colors.accent,\n color: themeVars.colors.accentForeground\n }\n },\n destructive: {\n backgroundColor: themeVars.colors.destructive,\n color: themeVars.colors.destructiveForeground,\n ':hover': {\n opacity: 0.9\n }\n },\n gradient: {\n background: `linear-gradient(to right, ${themeVars.colors.blue}, ${themeVars.colors.cyan})`,\n color: '#ffffff',\n ':hover': {\n opacity: 0.9\n }\n }\n },\n size: {\n default: {\n height: '2.5rem',\n padding: `0 ${themeVars.spacing.md}`\n },\n sm: {\n height: '2rem',\n padding: `0 ${themeVars.spacing.sm}`,\n fontSize: '0.75rem'\n },\n lg: {\n height: '3rem',\n padding: `0 ${themeVars.spacing.lg}`,\n fontSize: '1rem'\n },\n icon: {\n height: '2.5rem',\n width: '2.5rem',\n padding: 0\n }\n }\n },\n defaultVariants: {\n variant: 'default',\n size: 'default'\n }\n})\n","import type { ButtonHTMLAttributes, FC } from 'react'\nimport { button } from './Button.css'\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: 'default' | 'outline' | 'ghost' | 'destructive' | 'gradient'\n size?: 'default' | 'sm' | 'lg' | 'icon'\n asChild?: boolean\n}\n\nexport const Button: FC<ButtonProps> = ({\n variant = 'default',\n size = 'default',\n className = '',\n children,\n ...props\n}) => {\n return (\n <button className={`${button({ variant, size })} ${className}`} {...props}>\n {children}\n </button>\n )\n}\n","import { style } from '@vanilla-extract/css'\n\nexport const container = style({\n height: '100%',\n width: '100%',\n position: 'relative'\n})\n\nexport const canvas = style({\n pointerEvents: 'none'\n})\n","import type { FC, HTMLAttributes } from 'react'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { canvas, container } from './FlickeringGrid.css'\n\nexport interface FlickeringGridProps extends HTMLAttributes<HTMLDivElement> {\n squareSize?: number\n gridGap?: number\n flickerChance?: number\n color?: string\n width?: number\n height?: number\n maxOpacity?: number\n}\n\nexport const FlickeringGrid: FC<FlickeringGridProps> = ({\n squareSize = 4,\n gridGap = 6,\n flickerChance = 0.3,\n color = 'rgb(0, 0, 0)',\n width,\n height,\n className = '',\n maxOpacity = 0.3,\n ...props\n}) => {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const [isInView, setIsInView] = useState(false)\n const [canvasSize, setCanvasSize] = useState({ width: 0, height: 0 })\n\n const memoizedColor = useMemo(() => {\n const toRGBA = (color: string) => {\n if (typeof window === 'undefined') {\n return 'rgba(0, 0, 0,'\n }\n const canvasEl = document.createElement('canvas')\n canvasEl.width = canvasEl.height = 1\n const ctx = canvasEl.getContext('2d')\n if (!ctx) return 'rgba(255, 0, 0,'\n ctx.fillStyle = color\n ctx.fillRect(0, 0, 1, 1)\n const [r, g, b] = Array.from(ctx.getImageData(0, 0, 1, 1).data)\n return `rgba(${r}, ${g}, ${b},`\n }\n return toRGBA(color)\n }, [color])\n\n const setupCanvas = useCallback(\n (canvasEl: HTMLCanvasElement, width: number, height: number) => {\n const dpr = window.devicePixelRatio || 1\n canvasEl.width = width * dpr\n canvasEl.height = height * dpr\n canvasEl.style.width = `${width}px`\n canvasEl.style.height = `${height}px`\n const cols = Math.floor(width / (squareSize + gridGap))\n const rows = Math.floor(height / (squareSize + gridGap))\n\n const squares = new Float32Array(cols * rows)\n for (let i = 0; i < squares.length; i++) {\n squares[i] = Math.random() * maxOpacity\n }\n\n return { cols, rows, squares, dpr }\n },\n [squareSize, gridGap, maxOpacity]\n )\n\n const updateSquares = useCallback(\n (squares: Float32Array, deltaTime: number) => {\n for (let i = 0; i < squares.length; i++) {\n if (Math.random() < flickerChance * deltaTime) {\n squares[i] = Math.random() * maxOpacity\n }\n }\n },\n [flickerChance, maxOpacity]\n )\n\n const drawGrid = useCallback(\n (\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n cols: number,\n rows: number,\n squares: Float32Array,\n dpr: number\n ) => {\n ctx.clearRect(0, 0, width, height)\n ctx.fillStyle = 'transparent'\n ctx.fillRect(0, 0, width, height)\n\n for (let i = 0; i < cols; i++) {\n for (let j = 0; j < rows; j++) {\n const opacity = squares[i * rows + j]\n ctx.fillStyle = `${memoizedColor}${opacity})`\n ctx.fillRect(\n i * (squareSize + gridGap) * dpr,\n j * (squareSize + gridGap) * dpr,\n squareSize * dpr,\n squareSize * dpr\n )\n }\n }\n },\n [memoizedColor, squareSize, gridGap]\n )\n\n useEffect(() => {\n const canvasEl = canvasRef.current\n const container = containerRef.current\n if (!canvasEl || !container) return\n\n const ctx = canvasEl.getContext('2d')\n if (!ctx) return\n\n let animationFrameId: number\n let gridParams: ReturnType<typeof setupCanvas>\n\n const updateCanvasSize = () => {\n const newWidth = width || container.clientWidth\n const newHeight = height || container.clientHeight\n setCanvasSize({ width: newWidth, height: newHeight })\n gridParams = setupCanvas(canvasEl, newWidth, newHeight)\n }\n\n updateCanvasSize()\n\n let lastTime = 0\n const animate = (time: number) => {\n if (!isInView) return\n\n const deltaTime = (time - lastTime) / 1000\n lastTime = time\n\n updateSquares(gridParams.squares, deltaTime)\n drawGrid(\n ctx,\n canvasEl.width,\n canvasEl.height,\n gridParams.cols,\n gridParams.rows,\n gridParams.squares,\n gridParams.dpr\n )\n animationFrameId = requestAnimationFrame(animate)\n }\n\n const resizeObserver = new ResizeObserver(() => {\n updateCanvasSize()\n })\n\n resizeObserver.observe(container)\n\n const intersectionObserver = new IntersectionObserver(\n ([entry]) => {\n setIsInView(entry.isIntersecting)\n },\n { threshold: 0 }\n )\n\n intersectionObserver.observe(canvasEl)\n\n if (isInView) {\n animationFrameId = requestAnimationFrame(animate)\n }\n\n return () => {\n cancelAnimationFrame(animationFrameId)\n resizeObserver.disconnect()\n intersectionObserver.disconnect()\n }\n }, [setupCanvas, updateSquares, drawGrid, width, height, isInView])\n\n return (\n <div ref={containerRef} className={`${container} ${className}`} {...props}>\n <canvas\n ref={canvasRef}\n className={canvas}\n style={{\n width: canvasSize.width,\n height: canvasSize.height\n }}\n />\n </div>\n )\n}\n","import { style } from '@vanilla-extract/css'\nimport { themeVars } from '~/theme.css'\n\nexport const input = style({\n display: 'flex',\n width: '100%',\n borderRadius: themeVars.radius.md,\n border: `1px solid ${themeVars.colors.border}`,\n backgroundColor: themeVars.colors.background,\n padding: `${themeVars.spacing.sm} ${themeVars.spacing.md}`,\n fontSize: '0.875rem',\n color: themeVars.colors.foreground,\n transition: 'all 0.2s ease-in-out',\n outline: 'none',\n ':focus': {\n borderColor: themeVars.colors.primary,\n boxShadow: `0 0 0 1px ${themeVars.colors.primary}`\n },\n ':disabled': {\n cursor: 'not-allowed',\n opacity: 0.5\n },\n '::placeholder': {\n color: themeVars.colors.mutedForeground\n }\n})\n\nexport const label = style({\n fontSize: '0.875rem',\n fontWeight: 500,\n color: themeVars.colors.foreground,\n display: 'block',\n marginBottom: themeVars.spacing.xs\n})\n\nexport const textarea = style({\n display: 'flex',\n width: '100%',\n borderRadius: themeVars.radius.md,\n border: `1px solid ${themeVars.colors.border}`,\n backgroundColor: themeVars.colors.background,\n padding: `${themeVars.spacing.sm} ${themeVars.spacing.md}`,\n fontSize: '0.875rem',\n color: themeVars.colors.foreground,\n transition: 'all 0.2s ease-in-out',\n outline: 'none',\n minHeight: '5rem',\n resize: 'vertical',\n ':focus': {\n borderColor: themeVars.colors.primary,\n boxShadow: `0 0 0 1px ${themeVars.colors.primary}`\n },\n ':disabled': {\n cursor: 'not-allowed',\n opacity: 0.5\n },\n '::placeholder': {\n color: themeVars.colors.mutedForeground\n }\n})\n","import type {\n InputHTMLAttributes,\n LabelHTMLAttributes,\n TextareaHTMLAttributes\n} from 'react'\nimport { type FC, forwardRef, type ReactNode } from 'react'\nimport {\n input,\n label as labelStyle,\n textarea as textareaStyle\n} from './Input.css'\n\nexport interface InputProps extends InputHTMLAttributes<HTMLInputElement> {}\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(\n ({ className = '', ...props }, ref) => {\n return <input ref={ref} className={`${input} ${className}`} {...props} />\n }\n)\n\nInput.displayName = 'Input'\n\nexport interface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {\n children?: ReactNode\n}\n\nexport const Label: FC<LabelProps> = ({\n className = '',\n children,\n ...props\n}) => {\n return (\n // biome-ignore lint/a11y/noLabelWithoutControl: Label will be associated with input when used\n <label className={`${labelStyle} ${className}`} {...props}>\n {children}\n </label>\n )\n}\n\nexport interface TextareaProps\n extends TextareaHTMLAttributes<HTMLTextAreaElement> {}\n\nexport const Textarea: FC<TextareaProps> = ({ className = '', ...props }) => {\n return <textarea className={`${textareaStyle} ${className}`} {...props} />\n}\n","import { keyframes, style } from '@vanilla-extract/css'\nimport { themeVars } from '~/theme.css'\n\nconst spin = keyframes({\n '0%': { transform: 'rotate(0deg)' },\n '100%': { transform: 'rotate(360deg)' }\n})\n\nexport const stepperContainer = style({\n width: '100%',\n marginTop: '0.5rem'\n})\n\nexport const stepperWrapper = style({\n display: 'flex',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n position: 'relative',\n paddingTop: '0.5rem'\n})\n\nexport const stepContainer = style({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n position: 'relative',\n flex: 1\n})\n\nexport const stepIndicator = style({\n width: '1rem',\n height: '1rem',\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: 'all 0.2s'\n})\n\nexport const stepIndicatorCompleted = style({\n backgroundColor: '#15803d',\n color: 'white'\n})\n\nexport const stepIndicatorActive = style({\n backgroundColor: '#3b82f6',\n color: 'white'\n})\n\nexport const stepIndicatorPending = style({\n backgroundColor: themeVars.colors.muted,\n color: themeVars.colors.mutedForeground\n})\n\nexport const stepLine = style({\n position: 'absolute',\n top: '0.5rem',\n left: '50%',\n width: '100%',\n height: '0.125rem',\n transform: 'translateY(-50%) translateX(0.5rem)',\n transition: 'background-color 0.2s'\n})\n\nexport const stepLineCompleted = style({\n backgroundColor: '#3b82f6'\n})\n\nexport const stepLinePending = style({\n backgroundColor: themeVars.colors.border\n})\n\nexport const stepLabel = style({\n marginTop: '0.25rem',\n fontSize: '0.625rem',\n fontWeight: 500,\n textAlign: 'center',\n transition: 'color 0.2s'\n})\n\nexport const stepLabelActive = style({\n color: themeVars.colors.foreground\n})\n\nexport const stepLabelInactive = style({\n color: themeVars.colors.mutedForeground\n})\n\nexport const stepDot = style({\n width: '0.5rem',\n height: '0.5rem',\n borderRadius: '50%',\n backgroundColor: 'currentColor'\n})\n\nexport const stepSpinner = style({\n width: '0.75rem',\n height: '0.75rem',\n border: '2px solid white',\n borderTop: '2px solid transparent',\n borderRadius: '50%',\n animation: `${spin} 1s linear infinite`\n})\n","import type { FC } from 'react'\nimport * as styles from './Stepper.css'\n\ninterface StepProps {\n title: string\n description?: string\n isCompleted?: boolean\n isActive?: boolean\n isLast?: boolean\n isLoading?: boolean\n}\n\nconst Step: FC<StepProps> = ({\n title,\n isLoading,\n isCompleted,\n isActive,\n isLast\n}) => {\n return (\n <div className={styles.stepContainer}>\n {/* Step indicator */}\n <div\n className={`${styles.stepIndicator} ${\n isCompleted\n ? styles.stepIndicatorCompleted\n : isActive\n ? styles.stepIndicatorActive\n : styles.stepIndicatorPending\n }`}\n >\n {isCompleted ? (\n <svg\n width=\"16\"\n height=\"16\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <title>Check</title>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 13l4 4L19 7\"\n />\n </svg>\n ) : isLoading ? (\n <div className={styles.stepSpinner} />\n ) : (\n <div className={styles.stepDot} />\n )}\n </div>\n\n {/* Connection line */}\n {!isLast && (\n <div\n className={`${styles.stepLine} ${\n isCompleted ? styles.stepLineCompleted : styles.stepLinePending\n }`}\n />\n )}\n\n {/* Step label */}\n <span\n className={`${styles.stepLabel} ${\n isActive || isCompleted\n ? styles.stepLabelActive\n : styles.stepLabelInactive\n }`}\n >\n {title}\n </span>\n </div>\n )\n}\n\ninterface StepperProps {\n steps: Array<{ title: string; description?: string }>\n currentStep: number\n isLoading?: boolean\n}\n\nexport const Stepper: FC<StepperProps> = ({\n steps,\n currentStep,\n isLoading\n}) => {\n return (\n <div className={styles.stepperContainer}>\n <div className={styles.stepperWrapper}>\n {steps.map((step, index) => (\n <Step\n key={step.title}\n title={step.title}\n description={step.description}\n isCompleted={index < currentStep}\n isLoading={isLoading && index === currentStep}\n isActive={index === currentStep}\n isLast={index === steps.length - 1}\n />\n ))}\n </div>\n </div>\n )\n}\n","import { keyframes, style } from '@vanilla-extract/css'\nimport { themeVars } from '~/theme.css'\n\nconst spin = keyframes({\n '0%': { transform: 'rotate(0deg)' },\n '100%': { transform: 'rotate(360deg)' }\n})\n\nexport const overlay = style({\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n position: 'fixed',\n inset: 0,\n zIndex: 50\n})\n\nexport const content = style({\n backgroundColor: themeVars.colors.background,\n borderRadius: themeVars.radius.lg,\n boxShadow:\n '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n width: '90vw',\n maxWidth: '42rem',\n maxHeight: '90vh',\n overflow: 'auto',\n zIndex: 51,\n border: `1px solid ${themeVars.colors.border}`,\n padding: themeVars.spacing.md,\n display: 'flex',\n flexDirection: 'column'\n})\n\nexport const loadingOverlay = style({\n position: 'absolute',\n inset: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n backdropFilter: 'blur(4px)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 100,\n borderRadius: themeVars.radius.lg\n})\n\nexport const loadingContent = style({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: themeVars.spacing.md\n})\n\nexport const spinner = style({\n width: '2rem',\n height: '2rem',\n animation: `${spin} 1s linear infinite`,\n color: 'white'\n})\n\nexport const header = style({\n position: 'relative',\n marginBottom: themeVars.spacing.sm\n})\n\nexport const title = style({\n fontSize: '1rem',\n fontWeight: 600,\n color: themeVars.colors.foreground,\n marginBottom: '0.25rem'\n})\n\nexport const description = style({\n fontSize: '0.875rem',\n color: themeVars.colors.mutedForeground\n})\n\nexport const closeButton = style({\n position: 'absolute',\n top: 0,\n right: 0,\n padding: '0.25rem',\n cursor: 'pointer',\n border: 'none',\n background: 'transparent',\n color: themeVars.colors.foreground,\n borderRadius: themeVars.radius.md,\n transition: 'background-color 0.2s',\n ':hover': {\n backgroundColor: themeVars.colors.muted\n }\n})\n\nexport const body = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.sm,\n flex: 1,\n overflow: 'auto'\n})\n\nexport const formSection = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.sm\n})\n\nexport const fieldGroup = style({\n display: 'flex',\n flexDirection: 'column',\n gap: '0.375rem'\n})\n\nexport const dateInputWrapper = style({\n position: 'relative'\n})\n\nexport const dateIcon = style({\n position: 'absolute',\n left: '0.75rem',\n top: '50%',\n transform: 'translateY(-50%)',\n color: themeVars.colors.mutedForeground,\n pointerEvents: 'none'\n})\n\nexport const inputError = style({\n borderColor: themeVars.colors.destructive\n})\n\nexport const infoText = style({\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem',\n fontSize: '0.75rem',\n color: themeVars.colors.mutedForeground\n})\n\nexport const errorText = style({\n fontSize: '0.75rem',\n color: themeVars.colors.destructive\n})\n\nexport const summaryGrid = style({\n display: 'grid',\n gridTemplateColumns: 'repeat(2, 1fr)',\n gap: themeVars.spacing.sm,\n marginTop: '0.5rem',\n '@media': {\n '(max-width: 768px)': {\n gridTemplateColumns: '1fr'\n }\n }\n})\n\nexport const summaryCard = style({\n borderRadius: themeVars.radius.md,\n border: `1px solid ${themeVars.colors.border}`,\n backgroundColor: `${themeVars.colors.muted}40`,\n padding: themeVars.spacing.md,\n display: 'flex',\n flexDirection: 'column',\n gap: '0.375rem',\n transition: 'all 0.2s ease',\n ':hover': {\n borderColor: themeVars.colors.border,\n backgroundColor: `${themeVars.colors.muted}60`\n }\n})\n\nexport const summaryHeader = style({\n display: 'flex',\n alignItems: 'center',\n gap: '0.375rem',\n fontSize: '0.75rem',\n color: themeVars.colors.mutedForeground,\n marginBottom: '0.25rem'\n})\n\nexport const summaryContent = style({\n display: 'flex',\n flexDirection: 'column',\n gap: '0.25rem'\n})\n\nexport const summaryValue = style({\n fontSize: '0.8125rem',\n fontWeight: 600,\n color: themeVars.colors.foreground\n})\n\nexport const summarySubtext = style({\n fontSize: '0.75rem',\n color: themeVars.colors.mutedForeground\n})\n\nexport const summaryError = style({\n fontSize: '0.75rem',\n color: themeVars.colors.destructive\n})\n\nexport const summaryList = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.xs\n})\n\nexport const summaryRow = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n fontSize: '0.875rem',\n color: themeVars.colors.mutedForeground,\n paddingTop: themeVars.spacing.xs,\n borderTop: `1px solid ${themeVars.colors.border}50`,\n ':first-child': {\n borderTop: 'none',\n paddingTop: 0\n }\n})\n\nexport const footer = style({\n display: 'flex',\n gap: themeVars.spacing.sm,\n justifyContent: 'flex-end',\n marginTop: themeVars.spacing.sm,\n paddingTop: themeVars.spacing.sm,\n borderTop: `1px solid ${themeVars.colors.border}`\n})\n\nexport const costSection = style({\n borderRadius: themeVars.radius.md,\n border: `1px solid ${themeVars.colors.border}`,\n backgroundColor: `${themeVars.colors.muted}40`,\n padding: themeVars.spacing.md,\n display: 'flex',\n flexDirection: 'column',\n gap: '0.5rem',\n marginTop: '0.5rem',\n transition: 'all 0.2s ease',\n ':hover': {\n borderColor: themeVars.colors.border,\n backgroundColor: `${themeVars.colors.muted}60`\n }\n})\n\nexport const costHeader = style({\n display: 'flex',\n alignItems: 'center',\n gap: '0.375rem',\n fontSize: '0.875rem',\n fontWeight: 600,\n color: themeVars.colors.foreground,\n marginBottom: '0.25rem'\n})\n\nexport const costContent = style({\n display: 'flex',\n flexDirection: 'column',\n gap: '0.375rem'\n})\n\nexport const costRow = style({\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n fontSize: '0.8125rem'\n})\n\nexport const costLabel = style({\n color: themeVars.colors.mutedForeground\n})\n\nexport const costValue = style({\n fontWeight: 500,\n color: themeVars.colors.foreground\n})\n\nexport const costLoading = style({\n display: 'flex',\n alignItems: 'center',\n gap: '0.375rem',\n fontSize: '0.875rem',\n color: themeVars.colors.mutedForeground,\n padding: '0.5rem',\n justifyContent: 'center'\n})\n\nexport const costError = style({\n fontSize: '0.875rem',\n color: themeVars.colors.destructive,\n padding: '0.5rem',\n display: 'flex',\n alignItems: 'center',\n gap: '0.375rem',\n justifyContent: 'center',\n borderRadius: themeVars.radius.sm,\n backgroundColor: `${themeVars.colors.destructive}10`\n})\n\nexport const costWarning = style({\n fontSize: '0.75rem',\n color: themeVars.colors.mutedForeground,\n padding: '0.5rem',\n display: 'flex',\n alignItems: 'flex-start',\n gap: '0.375rem',\n borderRadius: themeVars.radius.sm,\n backgroundColor: 'rgba(245, 158, 11, 0.1)',\n border: '1px solid rgba(245, 158, 11, 0.2)',\n marginTop: '0.25rem'\n})\n\nexport const costDivider = style({\n height: '1px',\n backgroundColor: themeVars.colors.border,\n margin: '0.5rem 0'\n})\n\nexport const costTotalRow = style({\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n paddingTop: '0.5rem',\n marginTop: '0.25rem',\n borderTop: `1px solid ${themeVars.colors.border}`\n})\n\nexport const costTotalLabel = style({\n fontSize: '0.875rem',\n fontWeight: 600,\n color: themeVars.colors.foreground\n})\n\nexport const costTotalValue = style({\n fontSize: '0.9375rem',\n fontWeight: 700,\n color: themeVars.colors.foreground\n})\n\nexport const estimatedBadge = style({\n fontSize: '0.625rem',\n fontWeight: 600,\n padding: '0.125rem 0.375rem',\n borderRadius: themeVars.radius.sm,\n backgroundColor: 'rgba(245, 158, 11, 0.2)',\n color: '#f59e0b',\n textTransform: 'uppercase',\n letterSpacing: '0.025em',\n marginLeft: 'auto'\n})\n","import type {\n ISignAndExecuteTransaction,\n ISponsorConfig\n} from '@cmdoss/walrus-site-builder'\nimport { mainPackage } from '@cmdoss/walrus-site-builder'\nimport type { SuiClient } from '@mysten/sui/client'\nimport { Transaction } from '@mysten/sui/transactions'\nimport type { WalletAccount } from '@mysten/wallet-standard'\nimport {\n MAINNET_WALRUS_PACKAGE_CONFIG,\n TESTNET_WALRUS_PACKAGE_CONFIG,\n type WalrusClient\n} from '@mysten/walrus'\nimport { useStore } from '@nanostores/react'\nimport * as Dialog from '@radix-ui/react-dialog'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { Calendar, Clock, DollarSign, Info, Loader2, X } from 'lucide-react'\nimport type { FC } from 'react'\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport { useEpochDuration, useTransactionExecutor } from '~/hooks'\nimport { useStorageCostQuery } from '~/queries/storage-cost.query'\nimport { useWalrusSiteQuery } from '~/queries/walrus-site.query'\nimport { isExtendTimeDialogOpen } from '~/stores/site-domain.store'\nimport { Banner } from '../ui'\nimport { Button } from '../ui/Button'\nimport { Input, Label } from '../ui/Input'\nimport * as styles from './ExtendTimeDialog.css'\n\ninterface ExtendTimeDialogProps {\n siteId: string | undefined\n currentAccount: WalletAccount | null\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n walrusClient: WalrusClient\n }\n signAndExecuteTransaction: ISignAndExecuteTransaction\n sponsorConfig?: ISponsorConfig\n onSuccess?: (message: string, digest: string) => void\n}\n\nconst ExtendTimeDialog: FC<ExtendTimeDialogProps> = ({\n siteId,\n currentAccount,\n clients: { suiClient, queryClient, walrusClient },\n signAndExecuteTransaction,\n sponsorConfig,\n onSuccess\n}) => {\n const isOpen = useStore(isExtendTimeDialogOpen)\n const [selectedDate, setSelectedDate] = useState<string>('')\n const [epochs, setEpochs] = useState<number>(1)\n const [isExtending, setIsExtending] = useState(false)\n const [dateError, setDateError] = useState<string | null>(null)\n const [currentEpochsRemaining, setCurrentEpochsRemaining] = useState<\n number | null\n >(null)\n const [expirationDates, setExpirationDates] = useState<Map<string, Date>>(\n new Map()\n )\n const [totalFileSize, setTotalFileSize] = useState<number | null>(null)\n\n const { epochDurationMs, formatDate } = useEpochDuration(walrusClient)\n const txExecutor = useTransactionExecutor({\n suiClient,\n walletAddress: currentAccount?.address,\n signAndExecuteTransaction,\n sponsorConfig\n })\n\n const { data: siteData } = useWalrusSiteQuery(siteId, {\n suiClient,\n queryClient\n })\n\n // Function to fetch expiration dates and blob sizes\n const fetchExpirationDates = useCallback(async () => {\n if (!siteId || !walrusClient || !currentAccount || !siteData?.resources) {\n return\n }\n\n try {\n const blobType = await walrusClient.getBlobType()\n const datesMap = new Map<string, Date>()\n let totalSize = 0\n\n // Get staking state once before the loop\n const stakingState = await walrusClient.stakingState()\n const currentEpoch = Number(stakingState.epoch)\n const epochDuration = Number(stakingState.epoch_duration)\n\n let cursor: string | null | undefined = null\n let hasNextPage = true\n\n while (hasNextPage) {\n const ownedObjects = await suiClient.getOwnedObjects({\n owner: currentAccount.address,\n filter: { StructType: blobType },\n options: { showContent: true },\n cursor\n })\n\n for (const resource of siteData.resources) {\n const blobId = resource.blob_id\n if (datesMap.has(blobId)) continue\n\n for (const obj of ownedObjects.data) {\n if (obj.data?.content && 'fields' in obj.data.content) {\n const fields = obj.data.content.fields as Record<string, unknown>\n if ('blob_id' in fields) {\n const objBlobId = String(fields.blob_id)\n if (objBlobId === blobId) {\n const storage = fields.storage as\n | {\n fields?: { end_epoch?: unknown }\n }\n | undefined\n\n if (storage?.fields?.end_epoch !== undefined) {\n const endEpoch = Number(storage.fields.end_epoch)\n const remainingEpochs = endEpoch - currentEpoch\n const expirationTime =\n Date.now() + remainingEpochs * epochDuration\n datesMap.set(blobId, new Date(expirationTime))\n\n // Get blob size from fields.size (onchain data has this field)\n const sizeField = fields.size\n if (sizeField !== undefined) {\n // Size can be string or number\n const size =\n typeof sizeField === 'string'\n ? Number(sizeField)\n : Number(sizeField)\n if (!Number.isNaN(size) && size > 0) {\n totalSize += size\n }\n }\n break\n }\n }\n }\n }\n }\n }\n\n hasNextPage = ownedObjects.hasNextPage\n cursor = ownedObjects.nextCursor\n }\n\n setExpirationDates(datesMap)\n setTotalFileSize(totalSize > 0 ? totalSize : null)\n } catch (error) {\n console.error('Error fetching expiration dates:', error)\n }\n }, [siteId, walrusClient, currentAccount, suiClient, siteData])\n\n // Query storage cost (only when we have file size)\n const {\n data: storageCostData,\n isLoading: isStorageCostLoading,\n error: storageCostError\n } = useStorageCostQuery(totalFileSize, epochs, {\n queryClient,\n walrusClient\n })\n\n // Calculate estimated cost as fallback (rough estimate: ~1KB per resource)\n const estimatedFileSize = useMemo(() => {\n if (totalFileSize !== null) return null\n if (!siteData?.resources) return null\n // Estimate: average 10KB per resource\n return siteData.resources.length * 10 * 1024\n }, [totalFileSize, siteData?.resources])\n\n // Query estimated cost as fallback\n const { data: estimatedCostData, isLoading: isEstimatedCostLoading } =\n useStorageCostQuery(estimatedFileSize, epochs, {\n queryClient,\n walrusClient\n })\n\n // Format file size helper\n const formatFileSize = useCallback((bytes: number | null): string => {\n if (bytes === null || bytes === 0) return 'Unknown'\n const units = ['B', 'KB', 'MB', 'GB']\n let size = bytes\n let unitIndex = 0\n while (size >= 1024 && unitIndex < units.length - 1) {\n size /= 1024\n unitIndex++\n }\n return `${size.toFixed(2)} ${units[unitIndex]}`\n }, [])\n\n // Format WAL amount helper\n const formatWalAmount = useCallback((amount: string | undefined): string => {\n if (!amount) return '—'\n const num = BigInt(amount)\n // WAL has 9 decimals\n const formatted = Number(num) / 1_000_000_000\n return formatted.toFixed(6)\n }, [])\n\n // Query blob expiration dates\n useEffect(() => {\n if (isOpen && siteId) {\n fetchExpirationDates()\n }\n }, [isOpen, siteId, fetchExpirationDates])\n\n // Calculate current expiration date (earliest expiration from all resources)\n const currentExpiredDateMemo = useMemo(() => {\n if (!siteData?.resources || siteData.resources.length === 0) {\n return null\n }\n\n const timestamps = siteData.resources\n .map(resource => expirationDates.get(resource.blob_id)?.getTime())\n .filter((timestamp): timestamp is number => typeof timestamp === 'number')\n\n if (timestamps.length === 0) {\n return null\n }\n\n return new Date(Math.min(...timestamps))\n }, [siteData?.resources, expirationDates])\n\n // Calculate current epochs remaining\n useEffect(() => {\n if (!currentExpiredDateMemo || !epochDurationMs) {\n setCurrentEpochsRemaining(null)\n return\n }\n\n const now = Date.now()\n if (currentExpiredDateMemo.getTime() <= now) {\n setCurrentEpochsRemaining(0)\n return\n }\n\n const remaining = Math.ceil(\n (currentExpiredDateMemo.getTime() - now) / epochDurationMs\n )\n setCurrentEpochsRemaining(remaining)\n }, [currentExpiredDateMemo, epochDurationMs])\n\n // Calculate min and max dates for date picker\n const minDate = useMemo(() => {\n if (!epochDurationMs || !currentExpiredDateMemo) return ''\n const now = Date.now()\n const currentExpiration = currentExpiredDateMemo.getTime()\n\n // Min date is either current expiration or now + 1 epoch, whichever is later\n const minEpochs = 1\n const minFromNow = now + minEpochs * epochDurationMs\n const minTimestamp = Math.max(currentExpiration, minFromNow)\n\n return new Date(minTimestamp).toISOString().slice(0, 10)\n }, [epochDurationMs, currentExpiredDateMemo])\n\n const maxDate = useMemo(() => {\n if (!epochDurationMs || !currentExpiredDateMemo) return ''\n const currentExpiration = currentExpiredDateMemo.getTime()\n const maxEpochs = 365\n const maxTimestamp = currentExpiration + maxEpochs * epochDurationMs\n return new Date(maxTimestamp).toISOString().slice(0, 10)\n }, [epochDurationMs, currentExpiredDateMemo])\n\n // Calculate epochs from selected date\n const calculateEpochsFromDate = (dateString: string) => {\n if (!epochDurationMs || !dateString || !currentExpiredDateMemo) return 1\n\n const targetTime = new Date(dateString).getTime()\n const currentExpiration = currentExpiredDateMemo.getTime()\n const diffMs = targetTime - currentExpiration\n\n if (diffMs <= 0) return 1\n\n // Calculate epochs and round up\n const exactEpochs = diffMs / epochDurationMs\n const roundedEpochs = Math.ceil(exactEpochs)\n\n // Clamp between 1 and 365\n return Math.max(1, Math.min(365, roundedEpochs))\n }\n\n // Handle date change\n const handleDateChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newDate = e.target.value\n setSelectedDate(newDate)\n setDateError(null)\n\n if (!newDate) {\n setEpochs(1)\n return\n }\n\n const calculatedEpochs = calculateEpochsFromDate(newDate)\n setEpochs(calculatedEpochs)\n }\n\n // Get projected date from epochs\n const projectedDate = useMemo(() => {\n if (!epochDurationMs || !currentExpiredDateMemo) return null\n const currentExpiration = currentExpiredDateMemo.getTime()\n const projectedTimestamp = currentExpiration + epochs * epochDurationMs\n return new Date(projectedTimestamp)\n }, [epochs, currentExpiredDateMemo, epochDurationMs])\n\n // Initialize selected date when dialog opens\n useEffect(() => {\n if (isOpen && epochDurationMs && currentExpiredDateMemo) {\n // Default to current expiration + 1 epoch\n const defaultTimestamp =\n currentExpiredDateMemo.getTime() + epochDurationMs\n const defaultDate = new Date(defaultTimestamp).toISOString().slice(0, 10)\n setSelectedDate(defaultDate)\n setEpochs(1)\n setDateError(null)\n }\n }, [isOpen, epochDurationMs, currentExpiredDateMemo])\n\n const handleExtend = useCallback(async () => {\n if (\n !walrusClient ||\n !currentAccount ||\n !siteData?.resources ||\n siteData.resources.length === 0 ||\n !siteId\n ) {\n setDateError('Cannot extend blobs: missing required data')\n return\n }\n\n if (!epochs || epochs <= 0 || epochs > 365) {\n setDateError('Invalid epoch count. Must be between 1 and 365')\n return\n }\n\n if (!selectedDate) {\n setDateError('Please select an expiration date')\n return\n }\n\n if (!txExecutor) {\n setDateError('Transaction executor not available')\n return\n }\n\n setIsExtending(true)\n setDateError(null)\n\n try {\n const blobType = await walrusClient.getBlobType()\n const network = suiClient.network\n\n // Determine network-specific constants\n const walCoinType =\n mainPackage[network as keyof typeof mainPackage]?.walrusCoinType\n const walrusPackageId =\n mainPackage[network as keyof typeof mainPackage]?.walrusPackageId\n const systemObjectId =\n network === 'mainnet'\n ? MAINNET_WALRUS_PACKAGE_CONFIG.systemObjectId\n : TESTNET_WALRUS_PACKAGE_CONFIG.systemObjectId\n\n if (!walCoinType || !walrusPackageId) {\n throw new Error('Network configuration not found')\n }\n\n // Map blob_id to blobObjectId\n const blobIdToObjectIdMap = new Map<string, string>()\n let cursor: string | null | undefined = null\n let hasNextPage = true\n\n while (hasNextPage) {\n const ownedObjects = await suiClient.getOwnedObjects({\n owner: currentAccount.address,\n filter: { StructType: blobType },\n options: { showContent: true },\n cursor\n })\n\n for (const resource of siteData.resources) {\n const blobId = resource.blob_id\n if (blobIdToObjectIdMap.has(blobId)) continue\n\n for (const obj of ownedObjects.data) {\n if (obj.data?.content && 'fields' in obj.data.content) {\n const fields = obj.data.content.fields as Record<string, unknown>\n if ('blob_id' in fields) {\n const objBlobId = String(fields.blob_id)\n if (objBlobId === blobId) {\n blobIdToObjectIdMap.set(blobId, obj.data.objectId)\n break\n }\n }\n }\n }\n }\n\n hasNextPage = ownedObjects.hasNextPage\n cursor = ownedObjects.nextCursor\n }\n\n if (blobIdToObjectIdMap.size === 0) {\n throw new Error(\n 'No blob objects found for this site. Make sure you own the blob objects.'\n )\n }\n\n const tx = new Transaction()\n tx.setSender(currentAccount.address)\n\n const walCoin = await suiClient.getCoins({\n owner: currentAccount.address,\n coinType: walCoinType\n })\n\n if (walCoin.data.length === 0) {\n throw new Error(\n 'No WAL coins found in wallet. Please acquire WAL tokens first.'\n )\n }\n\n // Merge all WAL coins\n if (walCoin.data.length > 1) {\n tx.mergeCoins(\n tx.object(walCoin.data[0].coinObjectId),\n walCoin.data.slice(1).map(coin => tx.object(coin.coinObjectId))\n )\n }\n\n // Extend all blobs by adding epochs to their current expiration\n for (const [_blobId, objectId] of blobIdToObjectIdMap.entries()) {\n tx.moveCall({\n package: walrusPackageId,\n module: 'system',\n function: 'extend_blob',\n arguments: [\n tx.object(systemObjectId),\n tx.object(objectId),\n tx.pure.u32(epochs),\n tx.object(walCoin.data[0].coinObjectId)\n ]\n })\n }\n\n const digest = await txExecutor.execute({\n transaction: tx,\n description: `Extending ${blobIdToObjectIdMap.size} blob(s) by ${epochs} epoch(s)`\n })\n\n // Wait for transaction to complete\n await suiClient.waitForTransaction({ digest })\n\n // Invalidate queries to refetch updated data\n await queryClient.invalidateQueries({\n predicate: query => {\n const key = query.queryKey\n return (\n (Array.isArray(key) &&\n (key[0] === 'walrus-site' || key[0] === 'walrus-sites')) ||\n false\n )\n }\n })\n\n // Refresh expiration dates to reflect the extension\n await fetchExpirationDates()\n\n // Show success message\n const successMessage = `Successfully extended ${blobIdToObjectIdMap.size} blob(s) by ${epochs} epoch(s)`\n onSuccess?.(successMessage, digest)\n\n // Close dialog and reset\n isExtendTimeDialogOpen.set(false)\n setSelectedDate('')\n setEpochs(1)\n setDateError(null)\n } catch (error) {\n console.error('Error extending blobs:', error)\n setDateError(\n `Failed to extend: ${error instanceof Error ? error.message : 'Unknown error'}`\n )\n } finally {\n setIsExtending(false)\n }\n }, [\n walrusClient,\n currentAccount,\n siteData,\n siteId,\n epochs,\n selectedDate,\n txExecutor,\n suiClient,\n queryClient,\n onSuccess,\n fetchExpirationDates\n ])\n\n const handleClose = () => {\n isExtendTimeDialogOpen.set(false)\n setSelectedDate('')\n setEpochs(1)\n setDateError(null)\n }\n\n if (!siteId || !siteData) {\n return null\n }\n\n return (\n <Dialog.Root open={isOpen} onOpenChange={open => !open && handleClose()}>\n <Dialog.Portal>\n <Dialog.Overlay className={styles.overlay} />\n <Dialog.Content className={styles.content}>\n {/* Loading Overlay */}\n {isExtending && (\n <div className={styles.loadingOverlay}>\n <div className={styles.loadingContent}>\n <Loader2 className={styles.spinner} />\n <p>Extending storage time...</p>\n </div>\n </div>\n )}\n\n {/* Header */}\n <div className={styles.header}>\n <Dialog.Title className={styles.title}>\n Extend Time for {siteData.name}\n </Dialog.Title>\n <Dialog.Description className={styles.description}>\n Add epochs to extend the storage time for blobs in this site.\n Epochs will be added to the current expiration time.\n </Dialog.Description>\n <Dialog.Close asChild>\n <button type=\"button\" className={styles.closeButton}>\n <X size={20} />\n </button>\n </Dialog.Close>\n </div>\n\n {/* Content */}\n <div className={styles.body}>\n {/* Expired Warning Banner */}\n {currentEpochsRemaining === 0 && (\n <Banner\n title=\"Site Expired\"\n description=\"This site has expired and cannot be extended. The blobs are no longer available on the Walrus network.\"\n variant=\"warning\"\n />\n )}\n\n {/* Info Banner */}\n {currentEpochsRemaining !== 0 && (\n <Banner\n title=\"How Extension Works\"\n description=\"Select a target expiration date. The system will calculate the required epochs to extend your blobs to that date. Duration is rounded up to the nearest epoch.\"\n variant=\"info\"\n />\n )}\n\n <div className={styles.formSection}>\n <div className={styles.fieldGroup}>\n <Label htmlFor=\"expiration-date\">Target Expiration Date</Label>\n <div className={styles.dateInputWrapper}>\n <Input\n id=\"expiration-date\"\n type=\"date\"\n value={selectedDate}\n min={minDate}\n max={maxDate}\n onChange={handleDateChange}\n disabled={currentEpochsRemaining === 0 || isExtending}\n className={dateError ? styles.inputError : ''}\n />\n </div>\n\n {/* Compact Info */}\n {epochDurationMs && (\n <div className={styles.infoText}>\n <Info size={14} />\n <span>\n 1 epoch ≈{' '}\n {(epochDurationMs / (1000 * 60 * 60 * 24)).toFixed(1)}{' '}\n days • Duration rounded up. Maximum 365 epochs per extend.\n </span>\n </div>\n )}\n {dateError && <p className={styles.errorText}>{dateError}</p>}\n </div>\n\n {/* Summary Cards */}\n <div className={styles.summaryGrid}>\n {/* Current Expiration Card */}\n <div className={styles.summaryCard}>\n <div className={styles.summaryHeader}>\n <Calendar size={14} />\n <span>Current Expiration</span>\n </div>\n {currentExpiredDateMemo ? (\n <div className={styles.summaryContent}>\n <div className={styles.summaryValue}>\n {formatDate(currentExpiredDateMemo)}\n </div>\n {currentEpochsRemaining !== null &&\n currentEpochsRemaining > 0 && (\n <div className={styles.summarySubtext}>\n {currentEpochsRemaining} epoch\n {currentEpochsRemaining !== 1 ? 's' : ''} remaining\n </div>\n )}\n {currentEpochsRemaining === 0 && (\n <div className={styles.summaryError}>Expired</div>\n )}\n </div>\n ) : (\n <div className={styles.summaryValue}>Unavailable</div>\n )}\n </div>\n\n {/* Projected Expiration Card */}\n <div className={styles.summaryCard}>\n <div className={styles.summaryHeader}>\n <Clock size={14} />\n <span>New Expiration Date</span>\n </div>\n {projectedDate ? (\n <div className={styles.summaryContent}>\n <div className={styles.summaryValue}>\n {formatDate(projectedDate)}\n </div>\n {currentEpochsRemaining !== null && (\n <div className={styles.summarySubtext}>\n {currentEpochsRemaining} →{' '}\n {currentEpochsRemaining + epochs} epochs (+{epochs}{' '}\n epoch{epochs !== 1 ? 's' : ''})\n </div>\n )}\n </div>\n ) : (\n <div className={styles.summaryValue}>Select a date</div>\n )}\n </div>\n </div>\n\n {/* Storage Cost Section */}\n <div className={styles.costSection}>\n <div className={styles.costHeader}>\n <DollarSign size={16} />\n <span>Storage Cost</span>\n {totalFileSize === null && estimatedFileSize !== null && (\n <span className={styles.estimatedBadge}>Estimated</span>\n )}\n </div>\n <div className={styles.costContent}>\n <div className={styles.costRow}>\n <span className={styles.costLabel}>Size:</span>\n <span className={styles.costValue}>\n {totalFileSize !== null\n ? formatFileSize(totalFileSize)\n : estimatedFileSize !== null\n ? formatFileSize(estimatedFileSize)\n : 'Unknown'}\n </span>\n </div>\n <div className={styles.costRow}>\n <span className={styles.costLabel}>Resources:</span>\n <span className={styles.costValue}>\n {siteData?.resources?.length || 0} resources • {epochs}{' '}\n epoch\n {epochs !== 1 ? 's' : ''}\n </span>\n </div>\n {isStorageCostLoading || isEstimatedCostLoading ? (\n <div className={styles.costLoading}>\n <Loader2 size={14} className={styles.spinner} />\n <span>Calculating cost...</span>\n </div>\n ) : storageCostData || estimatedCostData ? (\n <>\n {totalFileSize === null && estimatedFileSize !== null && (\n <div className={styles.costWarning}>\n <Info size={12} />\n <span>\n Estimated cost based on{' '}\n {siteData?.resources?.length || 0} resource\n {siteData?.resources?.length !== 1 ? 's' : ''}\n </span>\n </div>\n )}\n <div className={styles.costDivider} />\n <div className={styles.costRow}>\n <span className={styles.costLabel}>Storage Cost:</span>\n <span className={styles.costValue}>\n {formatWalAmount(\n storageCostData?.storageCost ||\n estimatedCostData?.storageCost\n )}{' '}\n WAL\n </span>\n </div>\n </>\n ) : storageCostError ? (\n <div className={styles.costError}>\n <Info size={14} />\n <span>\n Unable to calculate cost. Please ensure you have\n sufficient WAL balance.\n </span>\n </div>\n ) : (\n <div className={styles.costError}>\n <Info size={14} />\n <span>Unable to calculate cost</span>\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n\n {/* Footer */}\n <div className={styles.footer}>\n <Button\n variant=\"outline\"\n onClick={handleClose}\n disabled={isExtending}\n >\n Cancel\n </Button>\n <Button\n onClick={handleExtend}\n disabled={\n isExtending ||\n !epochs ||\n !selectedDate ||\n !!dateError ||\n currentEpochsRemaining === 0\n }\n >\n {isExtending ? 'Extending...' : 'Extend Time'}\n </Button>\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n )\n}\n\nexport default ExtendTimeDialog\n","import { style } from '@vanilla-extract/css'\nimport { themeVars } from '~/theme.css'\n\nexport const content = style({\n minWidth: '20rem',\n maxWidth: '24rem',\n backgroundColor: themeVars.colors.background,\n borderRadius: themeVars.radius.lg,\n padding: themeVars.spacing.sm,\n boxShadow:\n '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',\n border: `1px solid ${themeVars.colors.border}`,\n zIndex: 50\n})\n\nexport const item = style({\n display: 'flex',\n alignItems: 'center',\n gap: themeVars.spacing.sm,\n padding: `${themeVars.spacing.sm} ${themeVars.spacing.md}`,\n fontSize: '0.875rem',\n borderRadius: themeVars.radius.sm,\n cursor: 'pointer',\n outline: 'none',\n userSelect: 'none',\n transition: 'all 0.15s ease-in-out',\n color: themeVars.colors.foreground,\n ':hover': {\n backgroundColor: themeVars.colors.accent,\n color: themeVars.colors.accentForeground\n },\n ':focus': {\n backgroundColor: themeVars.colors.accent,\n color: themeVars.colors.accentForeground\n },\n selectors: {\n '&[data-disabled]': {\n opacity: 0.5,\n cursor: 'not-allowed',\n pointerEvents: 'none'\n }\n }\n})\n\nexport const header = style({\n padding: `${themeVars.spacing.md} ${themeVars.spacing.md} ${themeVars.spacing.md}`\n})\n\nexport const title = style({\n fontWeight: 600,\n fontSize: '0.875rem',\n marginBottom: themeVars.spacing.xs,\n color: themeVars.colors.foreground\n})\n\nexport const description = style({\n fontSize: '0.75rem',\n lineHeight: 1.5,\n color: themeVars.colors.mutedForeground\n})\n\nexport const link = style({\n color: themeVars.colors.cyan,\n textDecoration: 'none',\n ':hover': { textDecoration: 'underline' }\n})\n\nexport const footer = style({\n padding: `${themeVars.spacing.sm} ${themeVars.spacing.sm}`\n})\n\nexport const buttonGroup = style({\n display: 'grid',\n gridTemplateColumns: '1fr 1fr',\n gap: themeVars.spacing.sm\n})\n\nexport const separator = style({\n height: '1px',\n backgroundColor: themeVars.colors.border,\n margin: `${themeVars.spacing.xs} 0`\n})\n","import {\n objectIdToWalrusSiteUrl,\n suinsDomainToWalrusSiteUrl\n} from '@cmdoss/walrus-site-builder'\nimport type { SuiClient } from '@mysten/sui/client'\nimport type { WalletAccount } from '@mysten/wallet-standard'\nimport { useStore } from '@nanostores/react'\nimport * as DropdownMenu from '@radix-ui/react-dropdown-menu'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { CalendarClock, ExternalLink, Globe2 } from 'lucide-react'\nimport type { FC, ReactNode } from 'react'\nimport { useSuiNsDomainsQuery } from '~/queries'\nimport {\n isDomainDialogOpen,\n isExtendTimeDialogOpen,\n siteMetadataStore\n} from '~/stores'\nimport { Banner } from '../ui'\nimport { button } from '../ui/Button.css'\nimport * as styles from './PublishMenu.css'\n\ninterface PublishMenuProps {\n children?: ReactNode\n siteId: string | undefined\n onPublishClick?: () => void\n onDomainClick?: () => void\n network?: 'mainnet' | 'testnet'\n /** Optional domain for the portal to view published site. */\n portalDomain?: string\n /** Whether to use HTTPS for the portal URL. */\n portalHttps?: boolean\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n }\n currentAccount: WalletAccount | null\n}\n\nconst PublishMenu: FC<PublishMenuProps> = ({\n children,\n siteId,\n onPublishClick,\n onDomainClick,\n portalDomain,\n portalHttps,\n network = 'testnet',\n clients,\n currentAccount\n}) => {\n const isDeployed = !!siteId\n const walrusSiteUrl = siteId\n ? objectIdToWalrusSiteUrl(siteId, portalDomain, portalHttps)\n : undefined\n\n const { data: nsDomains } = useSuiNsDomainsQuery(currentAccount, {\n suiClient: clients.suiClient,\n queryClient: clients.queryClient\n })\n\n const associatedDomains = nsDomains.filter(d => d.walrusSiteId === siteId)\n\n const suiNSUrlArray = useStore(siteMetadataStore.suiNSUrl)\n const suiNSUrl = suiNSUrlArray.length > 0 ? suiNSUrlArray[0].suins : undefined\n\n return (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger asChild>{children}</DropdownMenu.Trigger>\n <DropdownMenu.Portal>\n <DropdownMenu.Content className={styles.content}>\n {/* Header */}\n <div className={styles.header}>\n <h4 className={styles.title}>\n {isDeployed ? 'Update your Site' : 'Publish your Site'}\n </h4>\n {isDeployed && walrusSiteUrl ? (\n associatedDomains.length > 0 && suiNSUrl ? (\n <p className={styles.description}>\n Your site is live at{' '}\n <a\n href={suiNSUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={styles.link}\n >\n {suiNSUrl}\n </a>\n . You can update your site to reflect the latest changes.\n </p>\n ) : (\n <p className={styles.description}>\n Your site is live at{' '}\n <a\n href={\n network === 'testnet'\n ? `https://testnet.suivision.xyz/object/${siteId}`\n : `https://suivision.xyz/object/${siteId}`\n }\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={styles.link}\n >\n Explorer\n <ExternalLink\n style={{\n display: 'inline',\n width: '0.75rem',\n height: '0.75rem',\n marginLeft: '0.25rem'\n }}\n />\n </a>\n . You can link SuiNS domains to view your site in the portal.\n </p>\n )\n ) : (\n <p className={styles.description}>\n Deploy your app to{' '}\n <a\n href=\"https://www.walrus.xyz/\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={styles.link}\n >\n Walrus Sites\n </a>\n , a decentralized web hosting platform. After publishing, you\n can customize your domain and feature it in the community.\n </p>\n )}\n </div>\n\n <DropdownMenu.Separator className={styles.separator} />\n\n {/* Menu Items */}\n <DropdownMenu.Item\n className={styles.item}\n onSelect={onDomainClick}\n disabled={!siteId}\n >\n <Globe2 style={{ width: '1rem', height: '1rem' }} />\n <span style={{ flex: 1 }}>Customize Domain</span>\n {!siteId && (\n <span\n style={{\n fontSize: '0.75rem',\n color: 'var(--muted-foreground)'\n }}\n >\n Not Published Yet\n </span>\n )}\n </DropdownMenu.Item>\n\n <DropdownMenu.Item\n className={styles.item}\n onSelect={() => {\n isExtendTimeDialogOpen.set(true)\n }}\n disabled={!siteId}\n >\n <CalendarClock style={{ width: '1rem', height: '1rem' }} />\n <span style={{ flex: 1 }}>Extend Time</span>\n {!siteId && (\n <span\n style={{\n fontSize: '0.75rem',\n color: 'var(--muted-foreground)'\n }}\n >\n Not Published Yet\n </span>\n )}\n </DropdownMenu.Item>\n\n <DropdownMenu.Separator className={styles.separator} />\n\n {/* Footer */}\n <div className={styles.footer}>\n {isDeployed && walrusSiteUrl ? (\n <div className={styles.buttonGroup}>\n {suiNSUrl ? (\n <DropdownMenu.Item\n className={button({\n variant: 'outline',\n size: 'default'\n })}\n style={{ width: '100%' }}\n onSelect={() => {\n window.open(\n suinsDomainToWalrusSiteUrl(\n suiNSUrl,\n portalDomain,\n portalHttps\n ),\n '_blank',\n 'noopener,noreferrer'\n )\n }}\n >\n Visit Site\n </DropdownMenu.Item>\n ) : (\n <DropdownMenu.Item\n className={button({ variant: 'outline', size: 'default' })}\n style={{ width: '100%' }}\n onSelect={() => {\n isDomainDialogOpen.set(true)\n }}\n >\n Link SuiNS\n </DropdownMenu.Item>\n )}\n <DropdownMenu.Item\n className={button({ variant: 'gradient', size: 'default' })}\n onSelect={onPublishClick}\n >\n Update Site\n </DropdownMenu.Item>\n </div>\n ) : (\n <DropdownMenu.Item\n className={button({ variant: 'gradient', size: 'default' })}\n style={{ width: '100%' }}\n onSelect={onPublishClick}\n >\n Publish to Walrus\n </DropdownMenu.Item>\n )}\n\n {/* banner */}\n {network === 'testnet' && (\n <Banner\n title=\"You are publishing to the testnet\"\n description=\"You must run a local Walrus Site Portal to view published site.\"\n variant=\"info\"\n url=\"https://docs.wal.app/walrus-sites/portal.html\"\n urlName=\"Portal Documentation\"\n />\n )}\n </div>\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n )\n}\n\nexport default PublishMenu\n","import { keyframes, style } from '@vanilla-extract/css'\nimport { themeVars } from '~/theme.css'\n\nconst spin = keyframes({\n '0%': { transform: 'rotate(0deg)' },\n '100%': { transform: 'rotate(360deg)' }\n})\n\nexport const overlay = style({\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n position: 'fixed',\n inset: 0,\n zIndex: 50,\n animation: 'fadeIn 150ms ease-in-out'\n})\n\nexport const content = style({\n backgroundColor: themeVars.colors.background,\n borderRadius: themeVars.radius.lg,\n boxShadow:\n '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n width: '90vw',\n maxWidth: '56rem',\n maxHeight: '85vh',\n overflow: 'auto',\n zIndex: 51,\n animation: 'slideIn 200ms ease-in-out',\n border: `1px solid ${themeVars.colors.border}`,\n padding: themeVars.spacing.md\n})\n\nexport const title = style({\n fontSize: '1.125rem',\n fontWeight: 600,\n color: themeVars.colors.foreground,\n marginBottom: themeVars.spacing.xs\n})\n\nexport const description = style({\n fontSize: '0.875rem',\n color: themeVars.colors.mutedForeground\n})\n\nexport const body = style({\n paddingTop: themeVars.spacing.md,\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.sm\n})\n\nexport const section = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.xs,\n marginTop: themeVars.spacing.md\n})\n\nexport const twoColumnSection = style({\n display: 'grid',\n gridTemplateColumns: '1fr 1.5fr',\n gap: themeVars.spacing.lg,\n marginTop: themeVars.spacing.md,\n '@media': {\n '(max-width: 768px)': {\n gridTemplateColumns: '1fr',\n gap: themeVars.spacing.md\n }\n }\n})\n\nexport const leftColumn = style({\n display: 'flex',\n flexDirection: 'column'\n})\n\nexport const rightColumn = style({\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'flex-start'\n})\n\nexport const metadataFields = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.sm\n})\n\nexport const fieldDisplay = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.xs\n})\n\nexport const fieldValue = style({\n fontSize: '0.875rem',\n color: themeVars.colors.foreground,\n padding: themeVars.spacing.sm,\n backgroundColor: 'rgba(var(--muted-rgb), 0.3)',\n borderRadius: themeVars.radius.md,\n border: `1px solid ${themeVars.colors.border}`,\n minHeight: '2.5rem',\n display: 'flex',\n alignItems: 'center',\n wordBreak: 'break-word'\n})\n\nexport const sectionTitle = style({\n fontSize: '0.875rem',\n fontWeight: 600,\n paddingTop: themeVars.spacing.md,\n paddingBottom: themeVars.spacing.sm\n})\n\nexport const buttonGroup = style({\n display: 'flex',\n gap: themeVars.spacing.sm,\n paddingTop: themeVars.spacing.sm\n})\n\nexport const warningText = style({\n fontSize: '0.75rem',\n borderRadius: themeVars.radius.md,\n backgroundColor: themeVars.colors.muted,\n color: themeVars.colors.accentForeground,\n padding: themeVars.spacing.sm,\n marginTop: themeVars.spacing.sm\n})\n\nexport const previewContainer = style({\n position: 'relative'\n})\n\nexport const previewArea = style({\n border: `2px solid ${themeVars.colors.border}`,\n borderRadius: themeVars.radius.lg,\n backgroundColor: 'rgba(var(--muted-rgb), 0.3)',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n aspectRatio: '1 / 1',\n width: '100%',\n position: 'relative',\n overflow: 'hidden'\n})\n\nexport const flickeringGrid = style({\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 0\n})\n\nexport const maskLayer = style({\n position: 'absolute',\n inset: 0,\n zIndex: 1,\n background: `radial-gradient(ellipse 40% 80% at center, ${themeVars.colors.background} 50%, transparent 100%)`,\n opacity: 0.8,\n pointerEvents: 'none'\n})\n\nexport const placeholderContent = style({\n position: 'absolute',\n zIndex: 2,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: themeVars.spacing.sm\n})\n\nexport const previewImageWrapper = style({\n width: '100%',\n height: '100%',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center'\n})\n\nexport const previewImage = style({\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n borderRadius: themeVars.radius.lg\n})\n\nexport const placeholderIcon = style({\n width: '64px',\n height: '64px',\n borderRadius: themeVars.radius.lg,\n border: `2px dashed ${themeVars.colors.border}`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n position: 'relative',\n zIndex: 1,\n marginBottom: themeVars.spacing.sm,\n color: themeVars.colors.mutedForeground\n})\n\nexport const editButton = style({\n position: 'absolute',\n top: themeVars.spacing.sm,\n right: themeVars.spacing.sm,\n padding: themeVars.spacing.sm,\n backgroundColor: themeVars.colors.background,\n border: `1px solid ${themeVars.colors.border}`,\n borderRadius: themeVars.radius.lg,\n cursor: 'pointer',\n transition: 'background-color 0.2s',\n ':hover': {\n backgroundColor: themeVars.colors.muted\n }\n})\n\nexport const metadataText = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.xs\n})\n\nexport const dialogOverlay = style({\n position: 'fixed',\n inset: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n zIndex: 60\n})\n\nexport const dialogContent = style({\n position: 'fixed',\n left: '50%',\n top: '50%',\n transform: 'translate(-50%, -50%)',\n width: '30vw',\n minWidth: '300px',\n maxWidth: '500px',\n maxHeight: '90vh',\n overflowY: 'auto',\n backgroundColor: themeVars.colors.background,\n border: `1px solid ${themeVars.colors.border}`,\n borderRadius: themeVars.radius.lg,\n boxShadow: '0 20px 25px -5px rgba(0, 0, 0, 0.1)',\n zIndex: 70\n})\n\nexport const dialogHeader = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: themeVars.spacing.md,\n borderBottom: `1px solid ${themeVars.colors.border}`,\n position: 'sticky',\n top: 0,\n backgroundColor: themeVars.colors.background,\n zIndex: 10\n})\n\nexport const dialogBody = style({\n padding: themeVars.spacing.md,\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.md\n})\n\nexport const dialogBodyTwoColumn = style({\n padding: themeVars.spacing.md,\n display: 'grid',\n gridTemplateColumns: '1fr',\n gap: themeVars.spacing.lg,\n '@media': {\n '(max-width: 768px)': {\n gridTemplateColumns: '1fr',\n gap: themeVars.spacing.md\n }\n }\n})\n\nexport const dialogRightColumn = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.md\n})\n\nexport const dialogFooter = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: themeVars.spacing.md,\n borderTop: `1px solid ${themeVars.colors.border}`,\n backgroundColor: 'rgba(var(--muted-rgb), 0.3)',\n position: 'sticky',\n bottom: 0\n})\n\nexport const uploadArea = style({\n border: `2px dashed ${themeVars.colors.border}`,\n borderRadius: themeVars.radius.lg,\n padding: themeVars.spacing.lg,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n transition: 'background-color 0.2s',\n ':hover': {\n backgroundColor: 'rgba(var(--muted-rgb), 0.5)'\n }\n})\n\nexport const uploadAreaSquare = style({\n border: `2px dashed ${themeVars.colors.border}`,\n borderRadius: themeVars.radius.lg,\n aspectRatio: '1 / 1',\n width: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n transition: 'background-color 0.2s',\n overflow: 'hidden',\n position: 'relative',\n ':hover': {\n backgroundColor: 'rgba(var(--muted-rgb), 0.5)'\n }\n})\n\nexport const uploadPlaceholder = style({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n padding: themeVars.spacing.lg\n})\n\nexport const fieldLabel = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: themeVars.spacing.xs\n})\n\nexport const charCount = style({\n fontSize: '0.75rem',\n color: themeVars.colors.mutedForeground\n})\n\nexport const collapsibleTrigger = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n padding: themeVars.spacing.sm,\n fontSize: '0.875rem',\n fontWeight: 500,\n color: themeVars.colors.foreground,\n backgroundColor: themeVars.colors.muted,\n border: `1px solid ${themeVars.colors.border}`,\n borderRadius: themeVars.radius.md,\n cursor: 'pointer',\n transition: 'background-color 0.2s',\n ':hover': {\n backgroundColor: 'rgba(var(--muted-rgb), 0.8)'\n }\n})\n\nexport const collapsibleIcon = style({\n transition: 'transform 0.2s ease-in-out'\n})\n\nexport const collapsibleIconExpanded = style({\n transform: 'rotate(180deg)'\n})\n\nexport const collapsibleContent = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.xs,\n marginTop: themeVars.spacing.xs,\n overflow: 'hidden',\n transition: 'all 0.2s ease-in-out',\n padding: themeVars.spacing.sm\n})\n\nexport const collapsibleContentHidden = style({\n maxHeight: 0,\n opacity: 0,\n marginTop: 0\n})\n\nexport const collapsibleContentVisible = style({\n maxHeight: '500px',\n opacity: 1\n})\n\nexport const storageCostSection = style({\n padding: themeVars.spacing.sm,\n backgroundColor: themeVars.colors.muted,\n borderRadius: themeVars.radius.md\n})\n\nexport const storageCostSummary = style({\n display: 'flex',\n flexDirection: 'column'\n})\n\nexport const storageCostLabel = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n fontSize: '0.875rem',\n color: themeVars.colors.foreground\n})\n\nexport const storageCostValue = style({\n display: 'flex',\n alignItems: 'center',\n gap: '0.25rem',\n fontSize: '0.875rem'\n})\n\nexport const storageDetailsGrid = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.sm,\n marginTop: themeVars.spacing.sm\n})\n\nexport const storageDetailsBox = style({\n padding: themeVars.spacing.xs,\n backgroundColor: themeVars.colors.muted,\n borderRadius: themeVars.radius.md\n})\n\nexport const spinner = style({\n animation: `${spin} 1s linear infinite`\n})\n","import type { IAsset } from '@cmdoss/walrus-site-builder'\nimport type { WalrusClient } from '@mysten/walrus'\nimport { useStore } from '@nanostores/react'\nimport * as Dialog from '@radix-ui/react-dialog'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { CalendarClock, Info, Loader2, Pencil, Upload, X } from 'lucide-react'\nimport type { FC } from 'react'\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { useEpochDuration } from '~/hooks'\nimport { useStorageCostQuery } from '~/queries/storage-cost.query'\nimport { siteMetadataStore } from '~/stores/site-metadata.store'\nimport { sitePublishingStore } from '~/stores/site-publishing.store'\nimport { Banner } from '../ui'\nimport { Button } from '../ui/Button'\nimport { FlickeringGrid } from '../ui/FlickeringGrid'\nimport { Input, Label, Textarea } from '../ui/Input'\nimport { Stepper } from '../ui/Stepper'\nimport * as styles from './PublishModal.css'\n\ninterface PublishModalProps {\n siteId: string | undefined\n assets: IAsset[]\n onDeploy?: () => void\n onSaveMetadata?: () => Promise<void>\n onExtendBlobs?: (extendEpochs: number) => Promise<void>\n clients: {\n queryClient: QueryClient\n walrusClient: WalrusClient\n }\n}\n\nconst PublishModal: FC<PublishModalProps> = ({\n siteId,\n assets,\n onDeploy,\n onSaveMetadata,\n onExtendBlobs,\n clients: { queryClient, walrusClient }\n}) => {\n const [isMetadataDialogOpen, setIsMetadataDialogOpen] = useState(false)\n const [isStorageDetailsExpanded, setIsStorageDetailsExpanded] =\n useState(false)\n const [isExtending, setIsExtending] = useState(false)\n const [previousEpochs, setPreviousEpochs] = useState<number>(0)\n const [pendingEpochs, setPendingEpochs] = useState<number>(0)\n\n const isOpen = useStore(sitePublishingStore.isPublishDialogOpen)\n const isWorking = useStore(sitePublishingStore.isWorking)\n const deployStatusText = useStore(sitePublishingStore.deployStatusText)\n const deployStepIndex = useStore(sitePublishingStore.deploymentStepIndex)\n const imageDisplayUrl = useStore(siteMetadataStore.imageDisplayUrl)\n const projectUrl = useStore(siteMetadataStore.projectUrl)\n const epochs = useStore(siteMetadataStore.epochs)\n const isDirty = useStore(siteMetadataStore.isDirty)\n const isLoading = useStore(siteMetadataStore.loading)\n const title = useStore(siteMetadataStore.title)\n const description = useStore(siteMetadataStore.description)\n\n const { epochDurationMs, getExpirationDate } = useEpochDuration(walrusClient)\n\n // Track initial epochs value when editing a site\n useEffect(() => {\n if (siteId && epochs && previousEpochs === 0) {\n setPreviousEpochs(epochs)\n }\n }, [siteId, epochs, previousEpochs])\n\n // Calculate assets size\n const assetsSize = useMemo(\n () => assets.reduce((sum, a) => sum + a.content.byteLength, 0),\n [assets]\n )\n\n // Calculate min and max dates for date picker\n const minDate = useMemo(() => {\n if (!epochDurationMs) return ''\n const now = Date.now()\n const minEpochs = 5\n const minDateTime = now + minEpochs * epochDurationMs\n return new Date(minDateTime).toISOString().slice(0, 10)\n }, [epochDurationMs])\n\n const maxDate = useMemo(() => {\n if (!epochDurationMs) return ''\n const now = Date.now()\n const maxEpochs = 30\n const maxDateTime = now + maxEpochs * epochDurationMs\n return new Date(maxDateTime).toISOString().slice(0, 10)\n }, [epochDurationMs])\n\n // Calculate epochs from selected date\n const calculateEpochsFromDate = (selectedDate: string) => {\n if (!epochDurationMs || !selectedDate) return 5\n\n const now = Date.now()\n const targetTime = new Date(selectedDate).getTime()\n const diffMs = targetTime - now\n\n if (diffMs <= 0) return 5\n\n // Calculate epochs and round up\n const exactEpochs = diffMs / epochDurationMs\n const roundedEpochs = Math.ceil(exactEpochs)\n\n // Clamp between 5 and 30\n return Math.max(5, Math.min(30, roundedEpochs))\n }\n\n // Handle date change\n const handleDateChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const selectedDate = e.target.value\n if (!selectedDate) return\n\n const calculatedEpochs = calculateEpochsFromDate(selectedDate)\n\n // If editing existing site, store pending epochs for later processing\n if (siteId && previousEpochs > 0) {\n setPendingEpochs(calculatedEpochs)\n }\n\n siteMetadataStore.epochs.set(calculatedEpochs)\n }\n\n // Handle save metadata with automatic extend if needed\n const handleSaveMetadataWithExtend = async () => {\n if (!onSaveMetadata) return\n\n // First, save metadata\n await onSaveMetadata()\n\n // Then, if there's a pending extension, extend blobs\n if (\n siteId &&\n onExtendBlobs &&\n previousEpochs > 0 &&\n pendingEpochs > previousEpochs\n ) {\n const extensionEpochs = pendingEpochs - previousEpochs\n\n if (extensionEpochs > 0) {\n setIsExtending(true)\n try {\n await onExtendBlobs(extensionEpochs)\n // Update the previous epochs baseline after successful extension\n setPreviousEpochs(pendingEpochs)\n setPendingEpochs(0)\n } catch (error) {\n console.error('Failed to extend blobs:', error)\n } finally {\n setIsExtending(false)\n }\n }\n }\n }\n\n // Get current selected date from epochs\n const selectedDate = useMemo(() => {\n if (!epochDurationMs || !epochs) return ''\n const now = Date.now()\n const targetTime = now + epochs * epochDurationMs\n return new Date(targetTime).toISOString().slice(0, 10)\n }, [epochs, epochDurationMs])\n\n const {\n data: storageCost = {\n storageCost: '0',\n writeCost: '0',\n totalCost: '0'\n },\n isLoading: storageCostLoading,\n isError: storageCostError\n } = useStorageCostQuery(assetsSize, epochs, { walrusClient, queryClient })\n\n const deploymentSteps = [\n {\n title: 'Prepare',\n description: 'Build and register blobs for deployment'\n },\n { title: 'Upload', description: 'Upload assets to Walrus network' },\n { title: 'Certify', description: 'Certify the uploaded assets' },\n { title: 'Deploy', description: 'Deploy and update the site' }\n ]\n\n // Calculate expiration date using the hook\n const expirationDate = getExpirationDate(epochs)\n\n return (\n <Dialog.Root\n open={isOpen}\n onOpenChange={sitePublishingStore.closePublishDialog}\n >\n <Dialog.Portal>\n <Dialog.Overlay className={styles.overlay} />\n <Dialog.Content className={styles.content}>\n <Dialog.Title className={styles.title}>\n {siteId ? 'Edit Site' : 'Publish New Site'}\n </Dialog.Title>\n <Dialog.Description className={styles.description}>\n Make your project live in the Walrus network.\n </Dialog.Description>\n\n <Stepper\n steps={deploymentSteps}\n currentStep={deployStepIndex}\n isLoading={isWorking}\n />\n\n {/* Website Info Section - Two Column Layout */}\n <section className={styles.twoColumnSection}>\n {/* Left Column: Preview Image */}\n <div className={styles.leftColumn}>\n <div className={styles.previewContainer}>\n <div className={styles.previewArea}>\n {imageDisplayUrl ? (\n <div className={styles.previewImageWrapper}>\n <img\n src={imageDisplayUrl}\n alt=\"Site preview\"\n className={styles.previewImage}\n />\n {/* Gradient Overlay */}\n <div\n style={{\n position: 'absolute',\n inset: 0,\n background:\n 'linear-gradient(to bottom, transparent 0%, transparent 50%, rgba(0, 0, 0, 0.7) 100%)',\n pointerEvents: 'none'\n }}\n />\n {/* Title and Description Overlay */}\n {(title || description) && (\n <div\n style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n padding: '1rem',\n color: 'white',\n pointerEvents: 'none'\n }}\n >\n {title && (\n <h3\n style={{\n fontSize: '0.875rem',\n fontWeight: 600,\n marginBottom: '0.25rem',\n lineHeight: 1.3,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical'\n }}\n >\n {title}\n </h3>\n )}\n {description && (\n <p\n style={{\n fontSize: '0.75rem',\n opacity: 0.9,\n lineHeight: 1.4,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical'\n }}\n >\n {description}\n </p>\n )}\n </div>\n )}\n </div>\n ) : (\n <>\n <FlickeringGrid\n className={styles.flickeringGrid}\n squareSize={2}\n gridGap={6}\n color=\"rgb(0, 0, 0)\"\n maxOpacity={0.3}\n flickerChance={0.3}\n />\n <div className={styles.maskLayer} />\n <div className={styles.placeholderContent}>\n <div className={styles.placeholderIcon}>\n <svg\n width=\"32\"\n height=\"32\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <title>Image placeholder icon</title>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n </div>\n <p\n style={{\n fontWeight: 500,\n color: 'var(--foreground)',\n textAlign: 'center'\n }}\n >\n Add a preview image\n </p>\n <p\n style={{\n color: 'var(--muted-foreground)',\n textAlign: 'center',\n fontSize: '0.875rem'\n }}\n >\n Click the edit button to customize\n </p>\n </div>\n </>\n )}\n </div>\n <button\n type=\"button\"\n className={styles.editButton}\n onClick={() => setIsMetadataDialogOpen(true)}\n >\n <Pencil size={20} />\n </button>\n </div>\n {/* Storage Cost Section */}\n <div\n className={styles.storageCostSection}\n style={{ marginTop: '0.5rem' }}\n >\n <div className={styles.storageCostSummary}>\n <div className={styles.storageCostLabel}>\n <span style={{ fontWeight: 500 }}>Storage Cost</span>\n {assetsSize !== null && (\n <button\n type=\"button\"\n onClick={() =>\n setIsStorageDetailsExpanded(!isStorageDetailsExpanded)\n }\n style={{\n padding: '0.25rem',\n cursor: 'pointer',\n border: 'none',\n background: 'transparent',\n color: 'var(--muted-foreground)',\n borderRadius: '0.25rem',\n transition: 'background-color 0.2s'\n }}\n onMouseEnter={e => {\n e.currentTarget.style.backgroundColor = 'var(--muted)'\n }}\n onMouseLeave={e => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n aria-label=\"View storage cost details\"\n >\n <Info size={16} />\n </button>\n )}\n </div>\n <div className={styles.storageCostValue}>\n {assetsSize === null ? (\n <span\n style={{\n color: 'var(--warning, #f59e0b)',\n display: 'flex',\n alignItems: 'center',\n gap: '0.375rem'\n }}\n >\n <Info size={14} />\n Assets not prepared yet\n </span>\n ) : storageCostLoading ? (\n <span style={{ color: 'var(--muted-foreground)' }}>\n Calculating...\n </span>\n ) : storageCostError ? (\n <span style={{ color: 'var(--destructive)' }}>\n Cost unavailable\n </span>\n ) : (\n <>\n <span\n style={{\n fontSize: '0.875rem',\n color: 'var(--muted-foreground)'\n }}\n >\n {(assetsSize / 1024).toFixed(2)} KB •{' '}\n </span>\n <span\n style={{\n fontWeight: 600,\n color: 'var(--foreground)'\n }}\n >\n {(\n (Number(storageCost.storageCost) +\n Number(storageCost.writeCost)) /\n 1_000_000_000\n ).toFixed(9)}{' '}\n WAL\n </span>\n </>\n )}\n </div>\n </div>\n\n {/* Storage Details Collapsible */}\n {isStorageDetailsExpanded && (\n <div className={styles.storageDetailsBox}>\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '0.2rem'\n }}\n >\n <div style={{ fontSize: '0.875rem' }}>\n <span style={{ fontWeight: 500 }}>Storage Cost:</span>{' '}\n <span style={{ color: '#10b981' }}>\n {(\n Number(storageCost.storageCost) / 1_000_000_000\n ).toFixed(9)}{' '}\n WAL\n </span>\n </div>\n <div style={{ fontSize: '0.875rem' }}>\n <span style={{ fontWeight: 500 }}>Write Cost:</span>{' '}\n <span style={{ color: '#f97316' }}>\n {(\n Number(storageCost.writeCost) / 1_000_000_000\n ).toFixed(9)}{' '}\n WAL\n </span>\n </div>\n <div\n style={{\n fontSize: '0.875rem',\n borderTop: '1px solid var(--border)',\n paddingTop: '0.1rem',\n marginTop: '0.1rem'\n }}\n >\n <span style={{ fontWeight: 500 }}>Total Cost:</span>{' '}\n <span style={{ color: '#3b82f6', fontWeight: 600 }}>\n {(\n (Number(storageCost.storageCost) +\n Number(storageCost.writeCost)) /\n 1_000_000_000\n ).toFixed(9)}{' '}\n WAL\n </span>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Right Column: Metadata Information */}\n <div className={styles.rightColumn}>\n <div className={styles.metadataFields}>\n {/* Right Column: Text Fields */}\n <div className={styles.dialogRightColumn}>\n {/* Title Section */}\n <fieldset>\n <div className={styles.fieldLabel}>\n <Label>Title</Label>\n <span className={styles.charCount}>\n {siteMetadataStore.title.get().length}/120\n </span>\n </div>\n <Input\n value={siteMetadataStore.title.get()}\n onChange={e =>\n siteMetadataStore.title.set(\n e.target.value.slice(0, 120)\n )\n }\n placeholder=\"Add a title...\"\n />\n </fieldset>\n\n {/* Description Section */}\n <fieldset>\n <div className={styles.fieldLabel}>\n <Label>Description</Label>\n <span className={styles.charCount}>\n {siteMetadataStore.description.get().length}/150\n </span>\n </div>\n <Textarea\n value={siteMetadataStore.description.get()}\n onChange={e =>\n siteMetadataStore.description.set(\n e.target.value.slice(0, 150)\n )\n }\n placeholder=\"Add a description...\"\n rows={4}\n />\n </fieldset>\n\n {/* Project URL */}\n <fieldset>\n <Label>\n Project URL\n <span\n style={{\n fontSize: '0.75rem',\n color: 'var(--muted-foreground)'\n }}\n >\n (Optional)\n </span>\n </Label>\n <Input\n value={projectUrl}\n onChange={e =>\n siteMetadataStore.projectUrl.set(e.target.value)\n }\n placeholder=\"https://github.com/username/project\"\n />\n </fieldset>\n\n {/* Storage Duration Section - Only show for new sites */}\n {!siteId && (\n <fieldset>\n <div className={styles.fieldLabel}>\n <Label>Storage Duration</Label>\n {epochs > 0 && (\n <span\n style={{\n fontSize: '0.75rem',\n color: 'var(--muted-foreground)',\n display: 'flex',\n alignItems: 'center',\n gap: '0.25rem'\n }}\n >\n <span\n style={{\n fontWeight: 600,\n color: 'var(--foreground)'\n }}\n >\n {epochs}\n </span>\n epochs\n </span>\n )}\n </div>\n\n {/* Date Picker */}\n <div style={{ position: 'relative' }}>\n <Input\n type=\"date\"\n value={selectedDate}\n min={minDate}\n max={maxDate}\n onChange={handleDateChange}\n disabled={isWorking}\n style={{\n paddingLeft: '2.5rem',\n cursor: isWorking ? 'wait' : 'pointer'\n }}\n />\n <CalendarClock\n size={18}\n style={{\n position: 'absolute',\n left: '0.75rem',\n top: '50%',\n transform: 'translateY(-50%)',\n color: 'var(--muted-foreground)',\n pointerEvents: 'none'\n }}\n />\n </div>\n\n {/* Compact Info */}\n {expirationDate && epochDurationMs && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem',\n fontSize: '0.75rem',\n color: 'var(--muted-foreground)',\n marginTop: '0.5rem'\n }}\n >\n <Info size={14} style={{ flexShrink: 0 }} />\n <span>\n 1 epoch ≈{' '}\n {(epochDurationMs / (1000 * 60 * 60 * 24)).toFixed(\n 1\n )}{' '}\n days\n {' • '}\n Duration rounded up. Can be extended later.\n </span>\n </div>\n )}\n </fieldset>\n )}\n </div>\n </div>\n </div>\n </section>\n\n {isDirty ? (\n <section className={styles.section}>\n <div className={styles.buttonGroup}>\n <Button\n variant=\"outline\"\n style={{ flex: 1 }}\n onClick={siteMetadataStore.cancelEdit}\n disabled={isLoading}\n >\n Cancel\n </Button>\n <Button\n style={{\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '0.5rem'\n }}\n onClick={handleSaveMetadataWithExtend}\n disabled={isLoading || isExtending}\n >\n {isLoading || isExtending ? (\n <>\n <Loader2 size={16} className={styles.spinner} />\n {isExtending ? 'Extending Storage...' : 'Saving...'}\n </>\n ) : (\n 'Save'\n )}\n </Button>\n </div>\n </section>\n ) : (\n <section className={styles.section}>\n <div className={styles.buttonGroup}>\n <Button\n variant=\"gradient\"\n style={{\n width: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '0.5rem'\n }}\n onClick={onDeploy}\n disabled={isWorking}\n >\n {isWorking && (\n <Loader2 size={16} className={styles.spinner} />\n )}\n {deployStatusText}\n </Button>\n </div>\n <Banner\n title=\"Warning\"\n description=\"Please don't close the website\n until the deployment is complete.\"\n variant=\"warning\"\n />\n </section>\n )}\n </Dialog.Content>\n </Dialog.Portal>\n\n {/* Metadata Edit Dialog */}\n <MetadataEditDialog\n isOpen={isMetadataDialogOpen}\n onClose={() => setIsMetadataDialogOpen(false)}\n />\n </Dialog.Root>\n )\n}\n\ninterface MetadataEditDialogProps {\n isOpen: boolean\n onClose: () => void\n onImageChange?: (file: File) => void\n}\n\nfunction MetadataEditDialog({ isOpen, onClose }: MetadataEditDialogProps) {\n const imageDisplayUrl = useStore(siteMetadataStore.imageDisplayUrl)\n const isDirty = useStore(siteMetadataStore.isDirty)\n const isLoading = useStore(siteMetadataStore.loading)\n\n const [uploadMode, setUploadMode] = useState<'file' | 'url'>('file')\n const [imageUrl, setImageUrl] = useState('')\n const [urlError, setUrlError] = useState('')\n const [fileSizeError, setFileSizeError] = useState('')\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n const MAX_FILE_SIZE = 5 * 1024 * 1024 // 5MB in bytes\n\n const handleImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file) return\n\n // Check file size\n if (file.size > MAX_FILE_SIZE) {\n setFileSizeError(\n `File size exceeds 5MB limit (${(file.size / 1024 / 1024).toFixed(2)}MB)`\n )\n e.target.value = '' // Reset input\n return\n }\n\n setFileSizeError('')\n siteMetadataStore.imageUrl.set(file)\n }\n\n const handleUrlSubmit = () => {\n if (!imageUrl.trim()) {\n setUrlError('Please enter a valid URL')\n return\n }\n\n try {\n new URL(imageUrl)\n siteMetadataStore.imageUrl.set(imageUrl)\n setImageUrl('')\n setUrlError('')\n setUploadMode('file')\n } catch {\n setUrlError('Please enter a valid URL')\n }\n }\n\n const handleCancel = () => {\n siteMetadataStore.cancelEdit()\n setUploadMode('file')\n setImageUrl('')\n setUrlError('')\n setFileSizeError('')\n onClose()\n }\n\n return (\n <Dialog.Root open={isOpen} onOpenChange={onClose}>\n <Dialog.Portal>\n <Dialog.Overlay className={styles.dialogOverlay} />\n <Dialog.Content className={styles.dialogContent}>\n {/* Header */}\n <div className={styles.dialogHeader}>\n <Dialog.Title\n style={{\n fontSize: '1.125rem',\n fontWeight: 600,\n color: 'var(--foreground)'\n }}\n >\n Edit Site Image\n </Dialog.Title>\n <Dialog.Close asChild>\n <button\n type=\"button\"\n style={{\n padding: '0.25rem',\n cursor: 'pointer',\n border: 'none',\n background: 'transparent',\n color: 'var(--foreground)',\n borderRadius: '0.5rem',\n transition: 'background-color 0.2s'\n }}\n onMouseEnter={e => {\n e.currentTarget.style.backgroundColor = 'var(--muted)'\n }}\n onMouseLeave={e => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n <X size={20} />\n </button>\n </Dialog.Close>\n </div>\n\n {/* Content */}\n <div className={styles.dialogBodyTwoColumn}>\n {/* Left Column: Image Section */}\n <div>\n <div className={styles.fieldLabel}>\n <Label>Preview Image</Label>\n <span\n style={{\n fontSize: '0.75rem',\n color: 'var(--muted-foreground)'\n }}\n >\n Max 5MB\n </span>\n </div>\n\n {/* Upload Mode Toggle */}\n <div\n style={{\n display: 'flex',\n gap: '0.5rem',\n marginBottom: '1rem',\n padding: '0.25rem',\n backgroundColor: 'var(--muted)',\n borderRadius: '0.5rem'\n }}\n >\n <button\n type=\"button\"\n onClick={() => {\n setUploadMode('file')\n setUrlError('')\n }}\n style={{\n flex: 1,\n padding: '0.5rem 1rem',\n fontSize: '0.875rem',\n fontWeight: 500,\n border: 'none',\n borderRadius: '0.375rem',\n cursor: 'pointer',\n transition: 'all 0.2s',\n backgroundColor:\n uploadMode === 'file'\n ? 'var(--background)'\n : 'transparent',\n color:\n uploadMode === 'file'\n ? 'var(--foreground)'\n : 'var(--muted-foreground)',\n boxShadow:\n uploadMode === 'file'\n ? '0 1px 3px rgba(0, 0, 0, 0.1)'\n : 'none'\n }}\n >\n Upload File\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setUploadMode('url')\n setFileSizeError('')\n }}\n style={{\n flex: 1,\n padding: '0.5rem 1rem',\n fontSize: '0.875rem',\n fontWeight: 500,\n border: 'none',\n borderRadius: '0.375rem',\n cursor: 'pointer',\n transition: 'all 0.2s',\n backgroundColor:\n uploadMode === 'url'\n ? 'var(--background)'\n : 'transparent',\n color:\n uploadMode === 'url'\n ? 'var(--foreground)'\n : 'var(--muted-foreground)',\n boxShadow:\n uploadMode === 'url'\n ? '0 1px 3px rgba(0, 0, 0, 0.1)'\n : 'none'\n }}\n >\n From URL\n </button>\n </div>\n\n {uploadMode === 'file' ? (\n <>\n <div\n className={styles.uploadAreaSquare}\n onClick={() => !isLoading && fileInputRef.current?.click()}\n style={{\n cursor: isLoading ? 'wait' : 'pointer',\n opacity: isLoading ? 0.6 : 1\n }}\n >\n {isLoading ? (\n <div className={styles.uploadPlaceholder}>\n <div\n style={{\n width: '32px',\n height: '32px',\n border: '3px solid var(--muted)',\n borderTop: '3px solid var(--foreground)',\n borderRadius: '50%',\n animation: 'spin 1s linear infinite',\n marginBottom: '0.75rem'\n }}\n />\n <p\n style={{\n fontWeight: 500,\n color: 'var(--foreground)',\n textAlign: 'center'\n }}\n >\n Uploading...\n </p>\n </div>\n ) : imageDisplayUrl ? (\n <img\n src={imageDisplayUrl}\n alt=\"Preview\"\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n borderRadius: '0.5rem'\n }}\n />\n ) : (\n <div className={styles.uploadPlaceholder}>\n <Upload\n size={32}\n style={{\n marginBottom: '0.75rem',\n color: 'var(--muted-foreground)'\n }}\n />\n <p\n style={{\n fontWeight: 500,\n color: 'var(--foreground)',\n textAlign: 'center'\n }}\n >\n Click to upload\n </p>\n <p\n style={{\n fontSize: '0.875rem',\n color: 'var(--muted-foreground)',\n textAlign: 'center',\n marginTop: '0.25rem'\n }}\n >\n Square image recommended\n </p>\n </div>\n )}\n </div>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleImageChange}\n style={{ display: 'none' }}\n />\n {fileSizeError && (\n <p\n style={{\n fontSize: '0.75rem',\n color: 'var(--destructive)',\n marginTop: '0.5rem',\n display: 'flex',\n alignItems: 'center',\n gap: '0.25rem'\n }}\n >\n <Info size={14} />\n {fileSizeError}\n </p>\n )}\n </>\n ) : (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '1rem'\n }}\n >\n {imageDisplayUrl && (\n <div\n style={{\n width: '100%',\n aspectRatio: '1',\n borderRadius: '0.5rem',\n overflow: 'hidden',\n border: '1px solid var(--border)'\n }}\n >\n <img\n src={imageDisplayUrl}\n alt=\"Preview\"\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover'\n }}\n />\n </div>\n )}\n <div>\n <Label>Image URL</Label>\n <div\n style={{\n display: 'flex',\n gap: '0.5rem',\n marginTop: '0.5rem'\n }}\n >\n <Input\n value={imageUrl}\n onChange={e => {\n setImageUrl(e.target.value)\n setUrlError('')\n }}\n onKeyDown={e => {\n if (e.key === 'Enter') {\n handleUrlSubmit()\n }\n }}\n placeholder=\"https://example.com/image.png\"\n style={{ flex: 1 }}\n />\n <Button\n onClick={handleUrlSubmit}\n style={{ flexShrink: 0 }}\n >\n Apply\n </Button>\n </div>\n {urlError && (\n <p\n style={{\n fontSize: '0.75rem',\n color: 'var(--destructive)',\n marginTop: '0.5rem',\n display: 'flex',\n alignItems: 'center',\n gap: '0.25rem'\n }}\n >\n <Info size={14} />\n {urlError}\n </p>\n )}\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Footer */}\n <div className={styles.dialogFooter}>\n <button\n type=\"button\"\n onClick={() => {\n siteMetadataStore.imageUrl.set(\n 'https://www.walrus.xyz/walrus-site'\n )\n onClose()\n }}\n style={{\n fontSize: '0.875rem',\n fontWeight: 500,\n color: 'var(--muted-foreground)',\n cursor: 'pointer',\n border: 'none',\n background: 'transparent',\n transition: 'color 0.2s'\n }}\n onMouseEnter={e => {\n e.currentTarget.style.color = 'var(--foreground)'\n }}\n onMouseLeave={e => {\n e.currentTarget.style.color = 'var(--muted-foreground)'\n }}\n >\n Reset to default\n </button>\n <div style={{ display: 'flex', gap: '0.75rem' }}>\n <Button onClick={handleCancel} variant=\"outline\">\n Close\n </Button>\n <Dialog.Close asChild>\n <Button disabled={!isDirty || isLoading}>\n {isLoading ? 'Saving...' : 'Save Changes'}\n </Button>\n </Dialog.Close>\n </div>\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n )\n}\n\nexport default PublishModal\n","'use client'\n\nimport type { FC } from 'react'\n\ntype DomainCardSvgProps = {\n className?: string\n}\n\n// Sub-component: Background with decorative patterns\nconst CardBackground: FC = () => {\n return (\n <>\n <g clipPath=\"url(#clip0_2_8065)\">\n <rect width=\"440\" height=\"440\" rx=\"24.6939\" fill=\"#221C36\" />\n <g clipPath=\"url(#clip1_2_8065)\">\n <g style={{ mixBlendMode: 'plus-lighter' }}>\n <mask\n id=\"mask0_2_8065\"\n style={{ maskType: 'alpha' }}\n maskUnits=\"userSpaceOnUse\"\n x=\"-371\"\n y=\"-402\"\n width=\"1183\"\n height=\"685\"\n >\n <rect\n x=\"-370.026\"\n y=\"-401.408\"\n width=\"1181.24\"\n height=\"684.133\"\n fill=\"url(#paint0_linear_2_8065)\"\n />\n </mask>\n <g mask=\"url(#mask0_2_8065)\">\n <g opacity=\"0.3\">\n <g clipPath=\"url(#clip2_2_8065)\">\n <path\n d=\"M55.6533 284.621C54.582 285.692 54.5918 287.425 55.6562 288.489L99.9621 332.795C106.892 339.724 106.906 350.929 100.015 357.821C93.1228 364.712 81.9185 364.697 74.989 357.768L30.6831 313.462C15.7599 298.539 15.7201 274.398 30.5751 259.543C45.4302 244.688 69.5712 244.727 84.4945 259.651L114.326 289.482C115.39 290.546 117.123 290.556 118.194 289.485C119.265 288.414 119.255 286.681 118.191 285.617L73.8851 241.311C66.9557 234.381 66.9408 223.177 73.8326 216.285C80.7244 209.393 91.9287 209.408 98.8582 216.338L143.164 260.644C158.087 275.567 158.127 299.708 143.272 314.563C128.417 329.418 104.276 329.378 89.3527 314.455L59.5214 284.624C58.4571 283.559 56.7247 283.55 55.6533 284.621Z\"\n stroke=\"url(#paint1_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M142.429 198.7C141.359 199.77 141.361 201.504 142.429 202.572C143.497 203.64 145.231 203.642 146.301 202.573L176.132 172.741C191.05 157.823 215.251 157.833 230.185 172.767C245.119 187.7 245.128 211.901 230.21 226.819L185.904 271.125C178.98 278.049 167.747 278.046 160.814 271.113C153.881 264.18 153.877 252.946 160.801 246.022L205.107 201.716C206.177 200.647 206.175 198.913 205.107 197.845C204.039 196.777 202.305 196.774 201.235 197.844L171.404 227.675C156.486 242.593 132.285 242.584 117.351 227.65C102.417 212.716 102.408 188.516 117.326 173.598L161.632 129.292C168.556 122.368 179.789 122.371 186.722 129.304C193.655 136.237 193.659 147.47 186.735 154.395L142.429 198.7Z\"\n stroke=\"url(#paint2_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n <g clipPath=\"url(#clip3_2_8065)\">\n <path\n d=\"M230.049 110.225C228.978 111.297 228.988 113.029 230.052 114.094L274.358 158.399C281.288 165.329 281.303 176.533 274.411 183.425C267.519 190.317 256.315 190.302 249.385 183.373L205.079 139.067C190.156 124.143 190.116 100.002 204.971 85.1473C219.826 70.2923 243.967 70.332 258.891 85.2553L288.722 115.087C289.786 116.151 291.519 116.161 292.59 115.089C293.661 114.018 293.651 112.286 292.587 111.221L248.281 66.9155C241.352 59.986 241.337 48.7817 248.229 41.8899C255.121 34.998 266.325 35.013 273.254 41.9424L317.56 86.2483C332.483 101.172 332.523 125.313 317.668 140.168C302.813 155.023 278.672 154.983 263.749 140.06L233.918 110.228C232.853 109.164 231.121 109.154 230.049 110.225Z\"\n stroke=\"url(#paint3_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M316.825 24.3051C315.755 25.3747 315.757 27.1086 316.825 28.1767C317.893 29.2447 319.627 29.247 320.697 28.1773L350.528 -1.65402C365.446 -16.572 389.647 -16.5627 404.581 -1.62882C419.515 13.305 419.524 37.5057 404.606 52.4236L360.3 96.7295C353.376 103.654 342.143 103.65 335.21 96.7173C328.277 89.7844 328.273 78.551 335.197 71.6268L379.503 27.3209C380.573 26.2513 380.571 24.5174 379.503 23.4494C378.435 22.3813 376.701 22.3791 375.631 23.4487L345.8 53.28C330.882 68.198 306.681 68.1887 291.747 53.2548C276.813 38.321 276.804 14.1203 291.722 -0.797645L336.028 -45.1035C342.952 -52.0277 354.186 -52.0242 361.118 -45.0913C368.051 -38.1583 368.055 -26.925 361.131 -20.0008L316.825 24.3051Z\"\n stroke=\"url(#paint4_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n <g clipPath=\"url(#clip4_2_8065)\">\n <path\n d=\"M404.445 -64.1706C403.374 -63.0993 403.384 -61.3669 404.448 -60.3026L448.754 -15.9967C455.684 -9.06721 455.699 2.13713 448.807 9.02895C441.915 15.9208 430.711 15.9059 423.781 8.9764L379.475 -35.3295C364.552 -50.2527 364.512 -74.3938 379.367 -89.2488C394.222 -104.104 418.363 -104.064 433.287 -89.1409L463.118 -59.3095C464.182 -58.2452 465.915 -58.2353 466.986 -59.3067C468.057 -60.378 468.048 -62.1104 466.983 -63.1747L422.677 -107.481C415.748 -114.41 415.733 -125.614 422.625 -132.506C429.517 -139.398 440.721 -139.383 447.65 -132.454L491.956 -88.1478C506.879 -73.2246 506.919 -49.0835 492.064 -34.2285C477.209 -19.3735 453.068 -19.4132 438.145 -34.3365L408.314 -64.1678C407.249 -65.2321 405.517 -65.242 404.445 -64.1706Z\"\n stroke=\"url(#paint5_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n <g clipPath=\"url(#clip5_2_8065)\">\n <path\n d=\"M230.586 286.856C229.516 287.926 229.518 289.66 230.586 290.728C231.654 291.796 233.388 291.798 234.458 290.729L264.289 260.897C279.207 245.979 303.408 245.989 318.342 260.923C333.276 275.856 333.285 300.057 318.367 314.975L274.061 359.281C267.137 366.205 255.903 366.202 248.971 359.269C242.038 352.336 242.034 341.102 248.958 334.178L293.264 289.872C294.334 288.803 294.332 287.069 293.263 286.001C292.195 284.933 290.462 284.93 289.392 286L259.561 315.831C244.643 330.749 220.442 330.74 205.508 315.806C190.574 300.872 190.565 276.672 205.483 261.754L249.789 217.448C256.713 210.524 267.946 210.527 274.879 217.46C281.812 224.393 281.816 235.626 274.892 242.551L230.586 286.856Z\"\n stroke=\"url(#paint6_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n <g clipPath=\"url(#clip6_2_8065)\">\n <path\n d=\"M318.205 198.382C317.133 199.453 317.143 201.186 318.208 202.25L362.513 246.556C369.443 253.485 369.458 264.69 362.566 271.581C355.674 278.473 344.47 278.458 337.54 271.529L293.234 227.223C278.311 212.3 278.271 188.159 293.126 173.304C307.981 158.449 332.123 158.488 347.046 173.412L376.877 203.243C377.941 204.307 379.674 204.317 380.745 203.246C381.817 202.174 381.807 200.442 380.742 199.378L336.436 155.072C329.507 148.142 329.492 136.938 336.384 130.046C343.276 123.154 354.48 123.169 361.41 130.099L405.715 174.405C420.639 189.328 420.678 213.469 405.823 228.324C390.968 243.179 366.827 243.139 351.904 228.216L322.073 198.385C321.008 197.32 319.276 197.31 318.205 198.382Z\"\n stroke=\"url(#paint7_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M404.98 112.461C403.91 113.531 403.913 115.265 404.981 116.333C406.049 117.401 407.783 117.403 408.852 116.334L438.684 86.5023C453.602 71.5843 477.802 71.5936 492.736 86.5275C507.67 101.461 507.679 125.662 492.761 140.58L448.455 184.886C441.531 191.81 430.298 191.807 423.365 184.874C416.432 177.941 416.428 166.707 423.353 159.783L467.659 115.477C468.728 114.408 468.726 112.674 467.658 111.606C466.59 110.538 464.856 110.535 463.786 111.605L433.955 141.436C419.037 156.354 394.836 156.345 379.902 141.411C364.969 126.477 364.959 102.277 379.877 87.3587L424.183 43.0528C431.107 36.1286 442.341 36.1321 449.274 43.065C456.207 49.998 456.21 61.2313 449.286 68.1555L404.98 112.461Z\"\n stroke=\"url(#paint8_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n <g clipPath=\"url(#clip7_2_8065)\">\n <path\n d=\"M492.601 23.9857C491.529 25.0571 491.539 26.7895 492.604 27.8538L536.91 72.1597C543.839 79.0892 543.854 90.2935 536.962 97.1853C530.07 104.077 518.866 104.062 511.936 97.1328L467.631 52.8269C452.707 37.9036 452.668 13.7626 467.523 -1.09245C482.378 -15.9475 506.519 -15.9077 521.442 -0.984478L551.273 28.8469C552.338 29.9112 554.07 29.9211 555.141 28.8497C556.213 27.7783 556.203 26.046 555.138 24.9816L510.833 -19.3243C503.903 -26.2537 503.888 -37.4581 510.78 -44.3499C517.672 -51.2417 528.876 -51.2268 535.806 -44.2973L580.112 0.00856119C595.035 14.9318 595.075 39.0729 580.22 53.9279C565.364 68.7829 541.223 68.7432 526.3 53.8199L496.469 23.9886C495.405 22.9242 493.672 22.9144 492.601 23.9857Z\"\n stroke=\"url(#paint9_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n <g clipPath=\"url(#clip8_2_8065)\">\n <path\n d=\"M406.362 286.537C405.29 287.608 405.3 289.34 406.365 290.405L450.67 334.71C457.6 341.64 457.615 352.844 450.723 359.736C443.831 366.628 432.627 366.613 425.697 359.684L381.392 315.378C366.468 300.454 366.429 276.313 381.284 261.458C396.139 246.603 420.28 246.643 435.203 261.566L465.034 291.398C466.099 292.462 467.831 292.472 468.902 291.4C469.974 290.329 469.964 288.597 468.899 287.532L424.594 243.227C417.664 236.297 417.649 225.093 424.541 218.201C431.433 211.309 442.637 211.324 449.567 218.253L493.872 262.559C508.796 277.483 508.835 301.624 493.98 316.479C479.125 331.334 454.984 331.294 440.061 316.371L410.23 286.539C409.165 285.475 407.433 285.465 406.362 286.537Z\"\n stroke=\"url(#paint10_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M493.137 200.616C492.067 201.686 492.07 203.42 493.138 204.488C494.206 205.556 495.94 205.558 497.009 204.488L526.841 174.657C541.759 159.739 565.959 159.748 580.893 174.682C595.827 189.616 595.836 213.817 580.918 228.735L536.612 273.041C529.688 279.965 518.455 279.961 511.522 273.028C504.589 266.095 504.586 254.862 511.51 247.938L555.816 203.632C556.885 202.562 556.883 200.828 555.815 199.76C554.747 198.692 553.013 198.69 551.943 199.76L522.112 229.591C507.194 244.509 482.993 244.5 468.06 229.566C453.126 214.632 453.116 190.431 468.034 175.513L512.34 131.207C519.264 124.283 530.498 124.287 537.431 131.22C544.364 138.153 544.367 149.386 537.443 156.31L493.137 200.616Z\"\n stroke=\"url(#paint11_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n </g>\n <g opacity=\"0.3\">\n <g clipPath=\"url(#clip9_2_8065)\">\n <path\n d=\"M-33.3645 22.9074C-34.4342 23.977 -34.4319 25.7109 -33.3638 26.7789C-32.2958 27.847 -30.5619 27.8493 -29.4923 26.7796L0.339089 -3.05172C15.257 -17.9697 39.4577 -17.9604 54.3916 -3.02652C69.3254 11.9073 69.3347 36.108 54.4168 51.0259L10.1109 95.3318C3.18672 102.256 -8.04665 102.252 -14.9796 95.3196C-21.9125 88.3866 -21.916 77.1533 -14.9918 70.2291L29.3141 25.9232C30.3837 24.8536 30.3814 23.1197 29.3134 22.0517C28.2454 20.9836 26.5114 20.9814 25.4418 22.051L-4.38954 51.8823C-19.3075 66.8003 -43.5082 66.791 -58.442 51.8571C-73.3759 36.9233 -73.3852 12.7226 -58.4672 -2.19535L-14.1613 -46.5012C-7.23718 -53.4254 3.99619 -53.4219 10.9291 -46.489C17.862 -39.556 17.8655 -28.3227 10.9414 -21.3985L-33.3645 22.9074Z\"\n stroke=\"url(#paint12_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n <g clipPath=\"url(#clip10_2_8065)\">\n <path\n d=\"M54.2562 -65.5677C53.1849 -64.4964 53.1947 -62.764 54.2591 -61.6997L98.565 -17.3938C105.494 -10.4643 105.509 0.740023 98.6175 7.63184C91.7257 14.5237 80.5214 14.5088 73.5919 7.57929L29.286 -36.7266C14.3628 -51.6498 14.323 -75.7909 29.1781 -90.6459C44.0331 -105.501 68.1741 -105.461 83.0974 -90.5379L112.929 -60.7066C113.993 -59.6423 115.725 -59.6324 116.797 -60.7038C117.868 -61.7751 117.858 -63.5075 116.794 -64.5718L72.488 -108.878C65.5586 -115.807 65.5437 -127.012 72.4355 -133.903C79.3273 -140.795 90.5317 -140.78 97.4611 -133.851L141.767 -89.5449C156.69 -74.6217 156.73 -50.4806 141.875 -35.6256C127.02 -20.7706 102.879 -20.8103 87.9556 -35.7336L58.1243 -65.5649C57.06 -66.6292 55.3276 -66.6391 54.2562 -65.5677Z\"\n stroke=\"url(#paint13_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n <g clipPath=\"url(#clip11_2_8065)\">\n <path\n d=\"M-31.983 196.985C-33.0543 198.056 -33.0445 199.788 -31.9801 200.853L12.3258 245.159C19.2552 252.088 19.2701 263.292 12.3783 270.184C5.4865 277.076 -5.71784 277.061 -12.6473 270.132L-56.9532 225.826C-71.8764 210.902 -71.9162 186.761 -57.0611 171.906C-42.2061 157.051 -18.0651 157.091 -3.14183 172.014L26.6895 201.846C27.7538 202.91 29.4862 202.92 30.5576 201.849C31.629 200.777 31.6191 199.045 30.5547 197.98L-13.7512 153.675C-20.6806 146.745 -20.6955 135.541 -13.8037 128.649C-6.91189 121.757 4.29245 121.772 11.2219 128.702L55.5278 173.007C70.451 187.931 70.4908 212.072 55.6358 226.927C40.7807 241.782 16.6397 241.742 1.71644 226.819L-28.1149 196.987C-29.1792 195.923 -30.9116 195.913 -31.983 196.985Z\"\n stroke=\"url(#paint14_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M54.7925 111.064C53.7228 112.134 53.7251 113.868 54.7931 114.936C55.8611 116.004 57.5951 116.006 58.6647 114.936L88.4961 85.1051C103.414 70.1871 127.615 70.1964 142.549 85.1303C157.482 100.064 157.492 124.265 142.574 139.183L98.2678 183.489C91.3437 190.413 80.1103 190.409 73.1774 183.476C66.2445 176.543 66.241 165.31 73.1651 158.386L117.471 114.08C118.541 113.01 118.538 111.276 117.47 110.208C116.402 109.14 114.668 109.138 113.599 110.208L83.7674 140.039C68.8495 154.957 44.6488 154.948 29.715 140.014C14.7811 125.08 14.7718 100.879 29.6898 85.9614L73.9956 41.6556C80.9198 34.7314 92.1532 34.7349 99.0861 41.6678C106.019 48.6008 106.023 59.8341 99.0984 66.7583L54.7925 111.064Z\"\n stroke=\"url(#paint15_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n <g clipPath=\"url(#clip12_2_8065)\">\n <path\n d=\"M142.413 22.5881C141.342 23.6595 141.352 25.3918 142.416 26.4562L186.722 70.762C193.651 77.6915 193.666 88.8958 186.774 95.7877C179.883 102.679 168.678 102.665 161.749 95.7351L117.443 51.4292C102.52 36.506 102.48 12.3649 117.335 -2.49009C132.19 -17.3451 156.331 -17.3054 171.254 -2.38212L201.086 27.4492C202.15 28.5135 203.882 28.5234 204.954 27.4521C206.025 26.3807 206.015 24.6483 204.951 23.584L160.645 -20.7219C153.715 -27.6514 153.701 -38.8557 160.592 -45.7475C167.484 -52.6393 178.689 -52.6244 185.618 -45.695L229.924 -1.38908C244.847 13.5342 244.887 37.6752 230.032 52.5302C215.177 67.3853 191.036 67.3455 176.113 52.4223L146.281 22.5909C145.217 21.5266 143.484 21.5167 142.413 22.5881Z\"\n stroke=\"url(#paint16_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M229.189 -63.3323C228.119 -62.2627 228.121 -60.5287 229.189 -59.4607C230.257 -58.3927 231.991 -58.3904 233.061 -59.4601L262.892 -89.2914C277.81 -104.209 302.011 -104.2 316.945 -89.2662C331.878 -74.3323 331.888 -50.1317 316.97 -35.2137L272.664 9.09215C265.74 16.0163 254.506 16.0128 247.573 9.07988C240.641 2.14696 240.637 -9.08641 247.561 -16.0106L291.867 -60.3164C292.937 -61.3861 292.934 -63.12 291.866 -64.188C290.798 -65.2561 289.064 -65.2583 287.995 -64.1887L258.163 -34.3574C243.246 -19.4394 219.045 -19.4487 204.111 -34.3826C189.177 -49.3164 189.168 -73.5171 204.086 -88.435L248.392 -132.741C255.316 -139.665 266.549 -139.662 273.482 -132.729C280.415 -125.796 280.419 -114.562 273.494 -107.638L229.189 -63.3323Z\"\n stroke=\"url(#paint17_linear_2_8065)\"\n strokeWidth=\"3.36735\"\n strokeMiterlimit=\"10\"\n strokeLinecap=\"round\"\n />\n </g>\n </g>\n </g>\n </g>\n </g>\n </g>\n <rect\n x=\"1.12245\"\n y=\"1.12245\"\n width=\"437.755\"\n height=\"437.755\"\n rx=\"23.5714\"\n stroke=\"url(#paint18_linear_2_8065)\"\n strokeWidth=\"2.2449\"\n />\n </>\n )\n}\n\n// Sub-component: SuiNS Logo\nconst SuiNSLogo: FC = () => {\n return (\n <>\n <g clipPath=\"url(#clip13_2_8065)\">\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M330.479 342.088C330.237 342.088 330.041 342.285 330.041 342.527V368.61C330.041 373.074 326.429 376.692 321.974 376.692C317.518 376.692 313.906 373.074 313.906 368.61V342.527C313.906 333.357 321.326 325.923 330.479 325.923C339.632 325.923 347.052 333.357 347.052 342.527V360.088C347.052 360.331 347.248 360.527 347.49 360.527C347.731 360.527 347.927 360.331 347.927 360.088V334.006C347.927 329.542 351.539 325.923 355.995 325.923C360.45 325.923 364.062 329.542 364.062 334.006V360.088C364.062 369.258 356.642 376.692 347.49 376.692C338.337 376.692 330.917 369.258 330.917 360.088V342.527C330.917 342.285 330.721 342.088 330.479 342.088Z\"\n fill=\"#DAD0FF\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M381.32 342.348C381.079 342.348 380.883 342.544 380.883 342.786C380.883 343.028 381.079 343.225 381.32 343.225H398.849C408.002 343.225 415.422 350.659 415.422 359.828C415.422 368.998 408.002 376.432 398.849 376.432H372.815C368.359 376.432 364.747 372.813 364.747 368.35C364.747 363.886 368.359 360.267 372.815 360.267H398.849C399.091 360.267 399.287 360.07 399.287 359.828C399.287 359.586 399.091 359.39 398.849 359.39H381.32C372.168 359.39 364.747 351.956 364.747 342.786C364.747 333.616 372.168 326.182 381.32 326.182H407.355C411.81 326.182 415.422 329.801 415.422 334.265C415.422 338.729 411.81 342.348 407.355 342.348H381.32Z\"\n fill=\"#DAD0FF\"\n />\n </g>\n <rect\n x=\"287.089\"\n y=\"351.359\"\n width=\"25.156\"\n height=\"25.1977\"\n rx=\"12.578\"\n fill=\"#DAD0FF\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M303.198 362.795V362.796C303.812 363.575 304.178 364.563 304.178 365.637C304.178 366.711 303.801 367.728 303.171 368.513L303.116 368.58L303.102 368.494C303.09 368.421 303.075 368.347 303.059 368.273C302.744 366.869 301.716 365.665 300.025 364.69C298.883 364.034 298.229 363.243 298.058 362.345C297.947 361.764 298.029 361.181 298.189 360.681C298.348 360.182 298.585 359.763 298.786 359.511L299.444 358.696C299.559 358.553 299.775 358.553 299.89 358.696L303.199 362.795L303.198 362.795ZM304.239 361.981V361.98L299.83 356.517C299.746 356.413 299.588 356.413 299.504 356.517L295.095 361.981V361.981L295.08 361.999C294.269 363.019 293.784 364.316 293.784 365.727C293.784 369.014 296.418 371.679 299.667 371.679C302.916 371.679 305.55 369.014 305.55 365.727C305.55 364.316 305.065 363.019 304.253 361.999L304.239 361.981H304.239ZM296.15 362.777L296.544 362.289L296.556 362.379C296.566 362.45 296.577 362.522 296.591 362.594C296.846 363.951 297.757 365.082 299.281 365.959C300.606 366.722 301.377 367.601 301.6 368.565C301.692 368.967 301.709 369.363 301.669 369.708L301.666 369.73L301.647 369.739C301.049 370.035 300.377 370.202 299.667 370.202C297.175 370.202 295.155 368.158 295.155 365.637C295.155 364.555 295.527 363.56 296.15 362.778L296.15 362.777Z\"\n fill=\"#221C36\"\n />\n </>\n )\n}\n\nconst DomainCardSvg: FC<DomainCardSvgProps> = ({ className }) => {\n return (\n <svg\n viewBox=\"0 0 440 440\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n role=\"img\"\n aria-label=\"Domain card background\"\n className={className}\n >\n {/* Background with decorative patterns */}\n <CardBackground />\n\n {/* SuiNS Logo */}\n <SuiNSLogo />\n\n {/* SVG Definitions (gradients and clip paths) */}\n <defs>\n <linearGradient id=\"gradient\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" stopColor=\"#4bffa6\" />\n <stop offset=\"56%\" stopColor=\"#ff794b\" />\n <stop offset=\"100%\" stopColor=\"#d962ff\" />\n </linearGradient>\n <linearGradient\n id=\"paint0_linear_2_8065\"\n x1=\"220.592\"\n y1=\"-52.8804\"\n x2=\"220.592\"\n y2=\"282.725\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"white\" />\n <stop offset=\"1\" stopColor=\"white\" stopOpacity=\"0\" />\n </linearGradient>\n <linearGradient\n id=\"paint1_linear_2_8065\"\n x1=\"13.27\"\n y1=\"274.467\"\n x2=\"134.549\"\n y2=\"215.647\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint2_linear_2_8065\"\n x1=\"100.083\"\n y1=\"188.459\"\n x2=\"223.203\"\n y2=\"129.859\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint3_linear_2_8065\"\n x1=\"187.666\"\n y1=\"100.071\"\n x2=\"308.945\"\n y2=\"41.2512\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint4_linear_2_8065\"\n x1=\"274.479\"\n y1=\"14.064\"\n x2=\"397.599\"\n y2=\"-44.5362\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint5_linear_2_8065\"\n x1=\"362.062\"\n y1=\"-74.3248\"\n x2=\"483.341\"\n y2=\"-133.145\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint6_linear_2_8065\"\n x1=\"188.24\"\n y1=\"276.615\"\n x2=\"311.36\"\n y2=\"218.015\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint7_linear_2_8065\"\n x1=\"275.821\"\n y1=\"188.228\"\n x2=\"397.1\"\n y2=\"129.408\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint8_linear_2_8065\"\n x1=\"362.634\"\n y1=\"102.22\"\n x2=\"485.754\"\n y2=\"43.6201\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint9_linear_2_8065\"\n x1=\"450.217\"\n y1=\"13.8316\"\n x2=\"571.496\"\n y2=\"-44.9885\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint10_linear_2_8065\"\n x1=\"363.978\"\n y1=\"276.382\"\n x2=\"485.257\"\n y2=\"217.562\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint11_linear_2_8065\"\n x1=\"450.792\"\n y1=\"190.375\"\n x2=\"573.912\"\n y2=\"131.775\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint12_linear_2_8065\"\n x1=\"-75.71\"\n y1=\"12.6663\"\n x2=\"47.41\"\n y2=\"-45.9339\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint13_linear_2_8065\"\n x1=\"11.8729\"\n y1=\"-75.7219\"\n x2=\"133.151\"\n y2=\"-134.542\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint14_linear_2_8065\"\n x1=\"-74.3663\"\n y1=\"186.83\"\n x2=\"46.9122\"\n y2=\"128.01\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint15_linear_2_8065\"\n x1=\"12.447\"\n y1=\"100.823\"\n x2=\"135.567\"\n y2=\"42.2229\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint16_linear_2_8065\"\n x1=\"100.03\"\n y1=\"12.434\"\n x2=\"221.308\"\n y2=\"-46.3862\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint17_linear_2_8065\"\n x1=\"186.843\"\n y1=\"-73.5734\"\n x2=\"309.963\"\n y2=\"-132.174\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"0.345634\" stopColor=\"#EB8865\" />\n <stop offset=\"0.554579\" stopColor=\"#D34BFF\" />\n <stop offset=\"1\" stopColor=\"#4CA2FF\" />\n </linearGradient>\n <linearGradient\n id=\"paint18_linear_2_8065\"\n x1=\"541.75\"\n y1=\"220\"\n x2=\"134.237\"\n y2=\"-134.348\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#4BFFA6\" />\n <stop offset=\"1\" stopColor=\"#D34BFF\" />\n </linearGradient>\n <clipPath id=\"clip0_2_8065\">\n <rect width=\"440\" height=\"440\" rx=\"24.6939\" fill=\"white\" />\n </clipPath>\n <clipPath id=\"clip1_2_8065\">\n <rect width=\"440\" height=\"440\" fill=\"white\" />\n </clipPath>\n <clipPath id=\"clip2_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(1.28839 286.448) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip3_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(175.685 112.053) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip4_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(350.081 -62.3431) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip5_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(89.4453 374.604) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip6_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(263.84 200.209) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip7_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(438.236 25.8132) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip8_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(351.997 288.364) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip9_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(-174.505 110.655) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip10_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(-0.108704 -63.7402) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip11_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(-86.3479 198.812) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip12_2_8065\">\n <rect\n width=\"243.923\"\n height=\"121.961\"\n fill=\"white\"\n transform=\"translate(88.0482 24.4156) rotate(-45)\"\n />\n </clipPath>\n <clipPath id=\"clip13_2_8065\">\n <rect\n width=\"101.516\"\n height=\"50.7692\"\n fill=\"white\"\n transform=\"translate(313.906 325.923)\"\n />\n </clipPath>\n </defs>\n </svg>\n )\n}\n\nexport default DomainCardSvg\n","import { style } from '@vanilla-extract/css'\nimport { themeVars } from '~/theme.css'\n\nexport const overlay = style({\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n position: 'fixed',\n inset: 0,\n zIndex: 50\n})\n\nexport const content = style({\n backgroundColor: themeVars.colors.background,\n borderRadius: themeVars.radius.lg,\n boxShadow:\n '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n width: '90vw',\n maxWidth: '56rem',\n maxHeight: '85vh',\n overflow: 'auto',\n zIndex: 51,\n border: `1px solid ${themeVars.colors.border}`\n})\n\nexport const header = style({\n padding: themeVars.spacing.md,\n paddingBottom: 0\n})\n\nexport const title = style({\n fontSize: '1.125rem',\n fontWeight: 600,\n color: themeVars.colors.foreground,\n marginBottom: themeVars.spacing.xs\n})\n\nexport const description = style({\n fontSize: '0.875rem',\n color: themeVars.colors.mutedForeground\n})\n\nexport const body = style({\n padding: themeVars.spacing.md,\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.xs\n})\n\nexport const section = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.xs\n})\n\nexport const sectionTitle = style({\n fontSize: '0.875rem',\n fontWeight: 500,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between'\n})\n\nexport const domainList = style({\n border: `1px solid ${themeVars.colors.border}`,\n borderRadius: themeVars.radius.md,\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column'\n})\n\nexport const domainItem = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: `${themeVars.spacing.sm} ${themeVars.spacing.md}`,\n borderBottom: `1px solid ${themeVars.colors.border}`,\n ':last-child': {\n borderBottom: 'none'\n }\n})\n\nexport const domainCardGrid = style({\n display: 'flex',\n flexWrap: 'wrap',\n gap: themeVars.spacing.lg,\n maxHeight: '25rem',\n overflowY: 'auto',\n padding: themeVars.spacing.xs\n})\n\nexport const domainCard = style({\n width: '9rem',\n height: '9rem',\n position: 'relative',\n padding: themeVars.spacing.md,\n border: 'none',\n cursor: 'pointer',\n transition: 'all 0.2s ease-in-out',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'space-between',\n alignItems: 'flex-start',\n background: 'none',\n selectors: {\n '&:hover:not(:disabled)': {\n transform: 'scale(0.98)',\n borderColor: themeVars.colors.primary\n },\n '&:active:not(:disabled)': {\n transform: 'scale(0.95)'\n },\n '&:disabled': {\n cursor: 'not-allowed',\n opacity: 0.5,\n filter: 'grayscale(1)'\n }\n }\n})\n\nexport const domainCardBg = style({\n position: 'absolute',\n inset: 0,\n zIndex: -1,\n pointerEvents: 'none'\n})\n\nexport const domainName = style({\n fontSize: '1.25rem',\n fontWeight: 700,\n background: 'linear-gradient(90deg, #4bffa6 0%, #ff794b 56%, #d962ff 100%)',\n WebkitBackgroundClip: 'text',\n WebkitTextFillColor: 'transparent',\n wordBreak: 'break-all',\n lineHeight: 1.2\n})\n\nexport const domainExpiry = style({\n fontSize: '0.75rem',\n color: '#DAD0FF'\n})\n\nexport const infoPanel = style({\n display: 'flex',\n gap: themeVars.spacing.md,\n padding: themeVars.spacing.lg,\n backgroundColor: 'rgba(59, 130, 246, 0.1)',\n border: '1px solid rgba(59, 130, 246, 0.2)',\n borderRadius: themeVars.radius.lg\n})\n\nexport const link = style({\n color: themeVars.colors.cyan,\n textDecoration: 'none',\n wordBreak: 'break-all',\n ':hover': {\n textDecoration: 'underline'\n }\n})\n\nexport const loadingSpinner = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: `${themeVars.spacing.xl} 0`,\n color: themeVars.colors.mutedForeground\n})\n","import type {\n ISignAndExecuteTransaction,\n ISponsorConfig\n} from '@cmdoss/walrus-site-builder'\nimport type { SuiClient } from '@mysten/sui/client'\nimport type { SuinsClient } from '@mysten/suins'\nimport type { WalletAccount } from '@mysten/wallet-standard'\nimport * as Dialog from '@radix-ui/react-dialog'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { CheckCircle2, Loader2, Search, X } from 'lucide-react'\nimport type { FC } from 'react'\nimport { useSuiNsRegistration } from '~/hooks'\nimport { Button } from '../ui/Button'\nimport { Input } from '../ui/Input'\nimport * as styles from './SuiNsModal.css'\n\ninterface RegisterSuiNsDialogProps {\n isOpen: boolean\n onClose: () => void\n onRegistered?: () => void\n currentAccount: WalletAccount | null\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n suinsClient: SuinsClient\n }\n signAndExecuteTransaction: ISignAndExecuteTransaction\n sponsorConfig?: ISponsorConfig\n}\n\nexport const RegisterSuiNsDialog: FC<RegisterSuiNsDialogProps> = ({\n isOpen,\n onClose,\n onRegistered,\n currentAccount,\n clients: { suiClient, queryClient, suinsClient },\n signAndExecuteTransaction,\n sponsorConfig\n}) => {\n const {\n searchName,\n setSearchName,\n isSearching,\n isAvailable,\n isRegistering,\n isSwapping,\n estimatedPrice,\n error,\n normalizedName,\n fullName,\n selectedYears,\n setSelectedYears,\n pricePerYearFormatted,\n pricePerYearUsdc,\n totalPriceFormatted,\n totalPriceUsdc,\n expirationDate,\n handleSearch,\n handleRegister: handleRegisterInternal,\n reset\n } = useSuiNsRegistration({\n currentAccount,\n clients: { suiClient, queryClient, suinsClient },\n signAndExecuteTransaction,\n sponsorConfig\n })\n\n const network = suiClient.network\n const isTestnet = network === 'testnet'\n\n const handleRegister = async () => {\n const success = await handleRegisterInternal()\n if (success) {\n if (onRegistered) {\n onRegistered()\n }\n handleClose()\n }\n }\n\n const handleClose = () => {\n reset()\n onClose()\n }\n\n if (!currentAccount) {\n return null\n }\n\n return (\n <Dialog.Root open={isOpen} onOpenChange={open => !open && handleClose()}>\n <Dialog.Portal>\n <Dialog.Overlay\n className={styles.overlay}\n style={{\n zIndex: 51,\n backgroundColor: 'rgba(0, 0, 0, 0.7)'\n }}\n />\n <Dialog.Content\n className={styles.content}\n style={{ maxWidth: '32rem', zIndex: 52 }}\n >\n {/* Loading Overlay */}\n {(isRegistering || isSwapping) && (\n <div\n style={{\n position: 'absolute',\n inset: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n backdropFilter: 'blur(4px)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 100,\n borderRadius: '0.75rem'\n }}\n >\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '0.75rem'\n }}\n >\n <Loader2\n style={{\n width: '2rem',\n height: '2rem',\n animation: 'spin 1s linear infinite',\n color: 'white'\n }}\n />\n <p style={{ fontSize: '0.875rem', color: 'white' }}>\n {isSwapping\n ? 'Swapping WAL to USDC...'\n : 'Registering domain...'}\n </p>\n </div>\n </div>\n )}\n\n {/* Header */}\n <div className={styles.header}>\n <Dialog.Title className={styles.title}>\n Register SuiNS Domain\n </Dialog.Title>\n <Dialog.Description className={styles.description}>\n Search and register a new .sui domain name\n </Dialog.Description>\n <Dialog.Close asChild>\n <button\n type=\"button\"\n onClick={handleClose}\n disabled={isRegistering}\n style={{\n position: 'absolute',\n right: '1rem',\n top: '1rem',\n padding: '0.5rem',\n borderRadius: '0.375rem',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center'\n }}\n >\n <X style={{ width: '1rem', height: '1rem' }} />\n </button>\n </Dialog.Close>\n </div>\n\n {/* Content */}\n <div className={styles.body}>\n {/* Search Section */}\n <div style={{ marginBottom: '1rem' }}>\n <label\n htmlFor=\"domain-search\"\n style={{\n display: 'block',\n fontSize: '0.875rem',\n fontWeight: 500,\n marginBottom: '0.5rem'\n }}\n >\n Search for a domain\n </label>\n <div style={{ display: 'flex', gap: '0.5rem' }}>\n <div style={{ position: 'relative', flex: 1 }}>\n <Input\n id=\"domain-search\"\n type=\"text\"\n value={searchName}\n onChange={e => {\n setSearchName(e.target.value)\n }}\n onKeyDown={e => {\n if (e.key === 'Enter' && normalizedName) {\n handleSearch()\n }\n }}\n placeholder=\"Enter domain name\"\n disabled={isSearching || isRegistering}\n style={{ paddingRight: '3rem' }}\n />\n <span\n style={{\n position: 'absolute',\n right: '0.75rem',\n top: '50%',\n transform: 'translateY(-50%)',\n fontSize: '0.875rem',\n color: 'var(--muted-foreground)',\n pointerEvents: 'none'\n }}\n >\n .sui\n </span>\n </div>\n <Button\n onClick={handleSearch}\n disabled={isSearching || isRegistering || !normalizedName}\n size=\"default\"\n >\n {isSearching ? (\n <Loader2\n style={{\n width: '1rem',\n height: '1rem',\n animation: 'spin 1s linear infinite'\n }}\n />\n ) : (\n <Search style={{ width: '1rem', height: '1rem' }} />\n )}\n </Button>\n </div>\n </div>\n\n {/* Availability Alert */}\n {isAvailable !== null && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '0.625rem',\n padding: '0.875rem',\n borderRadius: '0.5rem',\n border: `1px solid ${\n isAvailable\n ? 'rgba(34, 197, 94, 0.2)'\n : 'rgba(239, 68, 68, 0.2)'\n }`,\n backgroundColor: isAvailable\n ? 'rgba(34, 197, 94, 0.1)'\n : 'rgba(239, 68, 68, 0.1)',\n color: isAvailable ? 'rgb(22, 163, 74)' : 'rgb(220, 38, 38)',\n marginBottom: '1rem'\n }}\n >\n <CheckCircle2\n style={{\n width: '1.25rem',\n height: '1.25rem',\n flexShrink: 0\n }}\n />\n <div style={{ flex: 1, minWidth: 0 }}>\n <p style={{ fontSize: '0.875rem', fontWeight: 600 }}>\n {isAvailable\n ? `${fullName} is available!`\n : `${fullName} is already taken`}\n </p>\n </div>\n </div>\n )}\n\n {/* Year Selection */}\n {isAvailable && (\n <div style={{ marginBottom: '1rem' }}>\n <label\n htmlFor=\"year-select\"\n style={{\n display: 'block',\n fontSize: '0.875rem',\n fontWeight: 500,\n marginBottom: '0.5rem'\n }}\n >\n Registration Period\n </label>\n <div\n style={{\n display: 'flex',\n gap: '0.5rem',\n flexWrap: 'wrap'\n }}\n >\n {[1, 2, 3, 4, 5].map(year => (\n <button\n key={year}\n type=\"button\"\n onClick={() => setSelectedYears(year)}\n disabled={isRegistering || isSwapping}\n style={{\n padding: '0.5rem 1rem',\n borderRadius: '0.375rem',\n border: `1px solid ${\n selectedYears === year\n ? 'rgba(59, 130, 246, 0.5)'\n : 'rgba(229, 231, 235, 1)'\n }`,\n backgroundColor:\n selectedYears === year\n ? 'rgba(59, 130, 246, 0.1)'\n : 'transparent',\n color:\n selectedYears === year\n ? 'rgb(37, 99, 235)'\n : 'inherit',\n fontWeight: selectedYears === year ? 600 : 400,\n cursor:\n isRegistering || isSwapping\n ? 'not-allowed'\n : 'pointer',\n fontSize: '0.875rem',\n transition: 'all 0.2s',\n opacity: isRegistering || isSwapping ? 0.5 : 1\n }}\n >\n {year} {year === 1 ? 'Year' : 'Years'}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {/* Price Breakdown */}\n {isAvailable && (pricePerYearFormatted || estimatedPrice) && (\n <div\n style={{\n padding: '1rem',\n borderRadius: '0.5rem',\n backgroundColor: 'rgba(249, 250, 251, 1)',\n border: '1px solid rgba(229, 231, 235, 1)',\n marginBottom: '1rem'\n }}\n >\n <h3\n style={{\n fontSize: '0.875rem',\n fontWeight: 600,\n marginBottom: '0.75rem',\n color: 'rgb(17, 24, 39)'\n }}\n >\n Price Breakdown\n </h3>\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '0.5rem'\n }}\n >\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center'\n }}\n >\n <span\n style={{\n fontSize: '0.875rem',\n color: 'rgb(107, 114, 128)'\n }}\n >\n Price per year:\n </span>\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-end',\n gap: '0.125rem'\n }}\n >\n <span\n style={{\n fontSize: '0.875rem',\n fontWeight: 600,\n color: 'rgb(17, 24, 39)'\n }}\n >\n {pricePerYearFormatted || estimatedPrice}\n </span>\n {isTestnet && pricePerYearUsdc && (\n <span\n style={{\n fontSize: '0.75rem',\n color: 'rgb(107, 114, 128)',\n opacity: 0.8\n }}\n >\n ({pricePerYearUsdc})\n </span>\n )}\n </div>\n </div>\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center'\n }}\n >\n <span\n style={{\n fontSize: '0.875rem',\n color: 'rgb(107, 114, 128)'\n }}\n >\n Number of years:\n </span>\n <span\n style={{\n fontSize: '0.875rem',\n fontWeight: 600,\n color: 'rgb(17, 24, 39)'\n }}\n >\n {selectedYears}\n </span>\n </div>\n <div\n style={{\n height: '1px',\n backgroundColor: 'rgba(229, 231, 235, 1)',\n margin: '0.5rem 0'\n }}\n />\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center'\n }}\n >\n <span\n style={{\n fontSize: '0.875rem',\n fontWeight: 600,\n color: 'rgb(17, 24, 39)'\n }}\n >\n Total:\n </span>\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-end',\n gap: '0.125rem'\n }}\n >\n <span\n style={{\n fontSize: '1rem',\n fontWeight: 700,\n color: 'rgb(17, 24, 39)'\n }}\n >\n {totalPriceFormatted || estimatedPrice}\n </span>\n {isTestnet && totalPriceUsdc && (\n <span\n style={{\n fontSize: '0.75rem',\n color: 'rgb(107, 114, 128)',\n opacity: 0.8\n }}\n >\n ({totalPriceUsdc})\n </span>\n )}\n </div>\n </div>\n {expirationDate && (\n <div\n style={{\n marginTop: '0.5rem',\n paddingTop: '0.5rem',\n borderTop: '1px solid rgba(229, 231, 235, 1)'\n }}\n >\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center'\n }}\n >\n <span\n style={{\n fontSize: '0.75rem',\n color: 'rgb(107, 114, 128)'\n }}\n >\n Expires on:\n </span>\n <span\n style={{\n fontSize: '0.75rem',\n fontWeight: 500,\n color: 'rgb(17, 24, 39)'\n }}\n >\n {expirationDate.toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric'\n })}\n </span>\n </div>\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Error */}\n {error && (\n <div\n style={{\n padding: '0.75rem',\n borderRadius: '0.5rem',\n backgroundColor: 'rgba(239, 68, 68, 0.1)',\n color: 'rgb(220, 38, 38)',\n fontSize: '0.875rem',\n marginBottom: '1rem'\n }}\n >\n {error}\n </div>\n )}\n\n {/* Register Button */}\n {isAvailable && (\n <Button\n onClick={handleRegister}\n disabled={isRegistering || isSwapping || !normalizedName}\n variant=\"gradient\"\n size=\"default\"\n style={{ width: '100%' }}\n >\n {isSwapping ? (\n <>\n <Loader2\n style={{\n width: '1rem',\n height: '1rem',\n animation: 'spin 1s linear infinite',\n marginRight: '0.5rem'\n }}\n />\n Swapping WAL to USDC...\n </>\n ) : isRegistering ? (\n <>\n <Loader2\n style={{\n width: '1rem',\n height: '1rem',\n animation: 'spin 1s linear infinite',\n marginRight: '0.5rem'\n }}\n />\n Registering...\n </>\n ) : (\n `Register ${fullName} for ${selectedYears} ${selectedYears === 1 ? 'year' : 'years'}`\n )}\n </Button>\n )}\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n )\n}\n","import {\n type ISignAndExecuteTransaction,\n type ISponsorConfig,\n suinsDomainToWalrusSiteUrl\n} from '@cmdoss/walrus-site-builder'\nimport type { SuiClient } from '@mysten/sui/client'\nimport type { SuinsClient } from '@mysten/suins'\nimport type { WalletAccount } from '@mysten/wallet-standard'\nimport { useStore } from '@nanostores/react'\nimport * as Dialog from '@radix-ui/react-dialog'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { ExternalLink, Loader2, X } from 'lucide-react'\nimport type { FC } from 'react'\nimport { useSuiNsDomainsQuery } from '~/queries'\nimport {\n isAssigningDomain,\n isDomainDialogOpen,\n isRegisterSuiNSDomainDialogOpen\n} from '~/stores/site-domain.store'\nimport { siteMetadataStore } from '~/stores/site-metadata.store'\nimport { Banner } from '../ui'\nimport { Button } from '../ui/Button'\nimport DomainCardSvg from './DomainCardSvg'\nimport { RegisterSuiNsDialog } from './RegisterSuiNsDialog'\nimport * as styles from './SuiNsModal.css'\n\nexport interface SuiNsDomain {\n nftId: string\n name: string\n expirationTimestampMs?: number\n walrusSiteId?: string\n walrusSiteUrl?: string\n}\n\ninterface SuiNsModalProps {\n siteId: string | undefined\n onAssociateDomain?: (nftId: string, siteId: string, suiNSName: string) => void\n currentAccount: WalletAccount | null\n /** Optional domain for the portal to view published site. */\n portalDomain?: string\n /** Whether to use HTTPS for the portal URL. */\n portalHttps?: boolean\n /**\n * Sui and Query clients needed for on-chain operations.\n */\n clients: {\n suiClient: SuiClient\n queryClient: QueryClient\n suinsClient: SuinsClient\n }\n /**\n * Callback for signing and executing transactions.\n * Required for registering new SuiNS domains.\n */\n signAndExecuteTransaction?: ISignAndExecuteTransaction\n /**\n * Optional sponsor configuration for transaction sponsorship.\n */\n sponsorConfig?: ISponsorConfig\n}\n\nconst SuiNsModal: FC<SuiNsModalProps> = ({\n siteId,\n onAssociateDomain,\n currentAccount,\n portalDomain,\n portalHttps,\n clients: { suiClient, queryClient, suinsClient },\n signAndExecuteTransaction,\n sponsorConfig\n}) => {\n const isOpen = useStore(isDomainDialogOpen)\n const isAssigning = useStore(isAssigningDomain)\n const isRegisterSuiNSDomainDialog = useStore(isRegisterSuiNSDomainDialogOpen)\n const suiNSUrlArray = useStore(siteMetadataStore.suiNSUrl)\n const { network } = suiClient\n const {\n data: nsDomains,\n isLoading: isLoadingDomains,\n isError: isErrorDomains\n } = useSuiNsDomainsQuery(currentAccount, { suiClient, queryClient })\n\n // Find all domains that are linked in store (suiNSUrlArray)\n const connectedDomains = nsDomains.filter(domain => {\n console.log('[1]domain', domain)\n console.log('[1]suiNSUrlArray', suiNSUrlArray)\n return suiNSUrlArray.some(entry => entry.nftId === domain.nftId)\n })\n\n // Explorer URL\n const explorerUrl = siteId\n ? network === 'testnet'\n ? `https://testnet.suivision.xyz/object/${siteId}`\n : `https://suivision.xyz/object/${siteId}`\n : undefined\n\n const handleAssociate = (nftId: string, suiNSName: string) => {\n if (siteId && onAssociateDomain) {\n onAssociateDomain(nftId, siteId, suiNSName)\n }\n }\n\n const handleRemoveAssociation = (nftId: string) => {\n if (onAssociateDomain) {\n onAssociateDomain(nftId, '', '')\n }\n }\n\n const formatExpiryDate = (timestamp?: number) => {\n if (!timestamp) return null\n return new Date(timestamp).toLocaleDateString('en-US', {\n month: 'short',\n day: '2-digit',\n year: 'numeric'\n })\n }\n\n return (\n <Dialog.Root open={isOpen} onOpenChange={isDomainDialogOpen.set}>\n <Dialog.Portal>\n <Dialog.Overlay className={styles.overlay} />\n <Dialog.Content className={styles.content}>\n {/* Loading Overlay */}\n {isAssigning && (\n <div\n style={{\n position: 'absolute',\n inset: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n backdropFilter: 'blur(4px)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 100,\n borderRadius: '0.75rem'\n }}\n >\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '0.75rem'\n }}\n >\n <Loader2\n style={{\n width: '2rem',\n height: '2rem',\n animation: 'spin 1s linear infinite',\n color: 'white'\n }}\n />\n <p style={{ fontSize: '0.875rem', color: 'white' }}>\n Updating domain association...\n </p>\n </div>\n </div>\n )}\n\n <div className={styles.header}>\n <Dialog.Title className={styles.title}>\n Customize Domain\n </Dialog.Title>\n <Dialog.Description className={styles.description}>\n Associate your website with a SuiNS domain for easy access\n </Dialog.Description>\n </div>\n\n <div className={styles.body}>\n {/* Currently Associated Domains */}\n <div className={styles.section}>\n <div className={styles.sectionTitle}>\n Currently Associated Domains\n </div>\n <div className={styles.domainList}>\n {/* Explorer - Always shown if siteId exists */}\n {explorerUrl && (\n <div className={styles.domainItem}>\n <div style={{ flex: 1, width: '100%' }}>\n <a\n href={explorerUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className={styles.link}\n style={{ fontSize: '0.875rem', fontWeight: 500 }}\n >\n Explorer\n <ExternalLink\n style={{\n display: 'inline',\n width: '0.75rem',\n height: '0.75rem',\n marginLeft: '0.25rem'\n }}\n />\n </a>\n <p\n style={{\n marginTop: '0.1rem',\n fontSize: '0.75rem',\n color: 'var(--muted-foreground)'\n }}\n >\n Sui Explorer\n </p>\n </div>\n </div>\n )}\n\n {/* SuiNS Domains - Show all linked domains from store */}\n {connectedDomains.length > 0 &&\n connectedDomains.map(domain => {\n const linkedEntry = suiNSUrlArray.find(\n entry => entry.nftId === domain.nftId\n )\n return (\n <div key={domain.nftId} className={styles.domainItem}>\n <div style={{ flex: 1, minWidth: 0 }}>\n <a\n href={\n suinsDomainToWalrusSiteUrl(\n linkedEntry?.suins || '',\n portalDomain,\n portalHttps\n ) || domain.walrusSiteUrl\n }\n target=\"_blank\"\n rel=\"noreferrer\"\n className={styles.link}\n style={{ fontSize: '0.875rem', fontWeight: 500 }}\n >\n @{domain.name}\n </a>\n <p\n style={{\n fontSize: '0.75rem',\n color: 'var(--muted-foreground)'\n }}\n >\n SuiNS Linked Domain\n </p>\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleRemoveAssociation(domain.nftId)}\n disabled={isAssigning}\n title=\"Remove domain association\"\n >\n <X style={{ width: '1rem', height: '1rem' }} />\n </Button>\n </div>\n )\n })}\n </div>\n </div>\n {/* Available Domains */}\n <div className={styles.section} style={{ marginTop: '0.5rem' }}>\n <div className={styles.sectionTitle}>\n <span>Select a domain to associate with your website</span>\n\n <Button\n size=\"sm\"\n type=\"button\"\n onClick={() => isRegisterSuiNSDomainDialogOpen.set(true)}\n >\n Buy a domain\n </Button>\n </div>\n\n {/* Loading state */}\n {isLoadingDomains && (\n <div className={styles.loadingSpinner}>\n <Loader2\n style={{\n width: '1.5rem',\n height: '1.5rem',\n animation: 'spin 1s linear infinite'\n }}\n />\n </div>\n )}\n\n {/* Error state */}\n {isErrorDomains && (\n <p\n style={{\n fontSize: '0.75rem',\n color: 'var(--destructive)',\n padding: '1rem 0'\n }}\n >\n Failed to load your domains. Please try again.\n </p>\n )}\n\n {/* Empty state */}\n {!isLoadingDomains && !isErrorDomains && !nsDomains.length && (\n <Banner\n title=\"You don't own any SuiNS domains yet.\"\n description=\"Buy a domain to continue.\"\n variant=\"warning\"\n />\n )}\n {/* Domain cards */}\n {!isLoadingDomains && !isErrorDomains && nsDomains.length > 0 && (\n <div className={styles.domainCardGrid}>\n {nsDomains.map(domain => {\n const isConnectedToThisSite = suiNSUrlArray.some(\n entry => entry.nftId === domain.nftId\n )\n\n return (\n <button\n key={domain.nftId}\n type=\"button\"\n className={styles.domainCard}\n onClick={() =>\n handleAssociate(domain.nftId, domain.name)\n }\n disabled={isConnectedToThisSite}\n title={\n isConnectedToThisSite\n ? 'Already connected to this site'\n : 'Click to connect'\n }\n >\n <div className={styles.domainCardBg}>\n <DomainCardSvg />\n </div>\n <div className={styles.domainName}>\n @{domain.name || 'Unknown'}\n </div>\n <div className={styles.domainExpiry}>\n {formatExpiryDate(domain.expirationTimestampMs)}\n </div>\n </button>\n )\n })}\n </div>\n )}\n </div>\n {/* Info Panel */}\n {network === 'testnet' && (\n <Banner\n title=\"You are publishing to the testnet\"\n description=\"You must run a local Walrus Site Portal to view published site.\"\n variant=\"info\"\n url=\"https://docs.wal.app/walrus-sites/portal.html\"\n urlName=\"Portal Documentation\"\n />\n )}\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n\n {/* Register SuiNS Dialog */}\n {signAndExecuteTransaction && (\n <RegisterSuiNsDialog\n isOpen={isRegisterSuiNSDomainDialog}\n onClose={() => isRegisterSuiNSDomainDialogOpen.set(false)}\n onRegistered={() => {\n // Invalidate domains query to refresh the list\n if (currentAccount?.address) {\n queryClient.invalidateQueries({\n queryKey: ['suins-domains', currentAccount.address, network]\n })\n }\n }}\n currentAccount={currentAccount}\n clients={{ suiClient, queryClient, suinsClient }}\n signAndExecuteTransaction={signAndExecuteTransaction}\n sponsorConfig={sponsorConfig}\n />\n )}\n </Dialog.Root>\n )\n}\n\nexport default SuiNsModal\n","import type { FC, ReactNode } from 'react'\nimport type { ThemeOverride } from '~/themes/themeContract'\n\ninterface ThemeProviderProps {\n children: ReactNode\n /**\n * Override default theme values for light and/or dark mode\n * @example\n * ```tsx\n * <ThemeProvider\n * themeOverrides={{\n * light: {\n * colors: { primary: '#ff0000' }\n * },\n * dark: {\n * colors: { primary: '#00ff00' }\n * }\n * }}\n * >\n * {children}\n * </ThemeProvider>\n * ```\n */\n themeOverrides?: ThemeOverride\n}\n\nexport const ThemeProvider: FC<ThemeProviderProps> = ({\n children,\n themeOverrides: _ // Currently unused\n}) => {\n return (\n <>\n {/* {themeOverrides && (\n <style\n // biome-ignore lint/security/noDangerouslySetInnerHtml: Required for dynamic theme overrides\n dangerouslySetInnerHTML={{\n __html: `\n :root, .light {\n ${getStaticThemeStyles(lightTheme)}\n }\n .dark {\n ${getStaticThemeStyles(darkTheme)}\n }\n `,\n }}\n />\n )} */}\n {children}\n </>\n )\n}\n\n// function getStaticThemeStyles(theme: ThemeVars) {\n// \treturn `${styleDataAttributeSelector} {${cssStringFromTheme(theme)}}`;\n// }\n\n// function cssStringFromTheme(theme: ThemeVars) {\n// \treturn Object.entries(assignInlineVars(themeVars, theme))\n// \t\t.map(([key, value]) => `${key}:${value};`)\n// \t\t.join('');\n// }\n","import { keyframes, style } from '@vanilla-extract/css'\nimport { themeVars } from '~/theme.css'\n\nconst spin = keyframes({\n '0%': { transform: 'rotate(0deg)' },\n '100%': { transform: 'rotate(360deg)' }\n})\n\nexport const overlay = style({\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n position: 'fixed',\n inset: 0,\n zIndex: 50,\n animation: 'fadeIn 150ms ease-in-out'\n})\n\nexport const content = style({\n backgroundColor: themeVars.colors.background,\n borderRadius: themeVars.radius.lg,\n boxShadow:\n '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n width: '90vw',\n maxWidth: '32rem',\n maxHeight: '90vh',\n overflow: 'auto',\n zIndex: 51,\n animation: 'slideIn 200ms ease-in-out',\n border: `1px solid ${themeVars.colors.border}`,\n padding: 0,\n display: 'flex',\n flexDirection: 'column'\n})\n\nexport const header = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.xs,\n padding: themeVars.spacing.md,\n borderBottom: `1px solid ${themeVars.colors.border}`,\n position: 'relative'\n})\n\nexport const title = style({\n fontSize: '1.125rem',\n fontWeight: 600,\n color: themeVars.colors.foreground,\n margin: 0\n})\n\nexport const description = style({\n fontSize: '0.875rem',\n color: themeVars.colors.mutedForeground,\n margin: 0\n})\n\nexport const closeButton = style({\n position: 'absolute',\n top: themeVars.spacing.md,\n right: themeVars.spacing.md,\n padding: '0.25rem',\n cursor: 'pointer',\n border: 'none',\n background: 'transparent',\n color: themeVars.colors.foreground,\n borderRadius: '0.5rem',\n transition: 'background-color 0.2s',\n ':hover': {\n backgroundColor: themeVars.colors.muted\n }\n})\n\nexport const body = style({\n padding: themeVars.spacing.md,\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.md,\n flex: 1,\n overflowY: 'auto'\n})\n\nexport const loadingContainer = style({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: themeVars.spacing.md,\n padding: themeVars.spacing.xl,\n color: themeVars.colors.mutedForeground\n})\n\nexport const footer = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n gap: themeVars.spacing.sm,\n padding: themeVars.spacing.md,\n borderTop: `1px solid ${themeVars.colors.border}`,\n backgroundColor: 'rgba(var(--muted-rgb), 0.3)'\n})\n\nexport const fieldLabel = style({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: themeVars.spacing.xs\n})\n\nexport const charCount = style({\n fontSize: '0.75rem',\n color: themeVars.colors.mutedForeground\n})\n\nexport const optionalLabel = style({\n fontSize: '0.75rem',\n color: themeVars.colors.mutedForeground,\n fontWeight: 'normal'\n})\n\nexport const uploadModeToggle = style({\n display: 'flex',\n gap: '0.5rem',\n marginBottom: themeVars.spacing.md,\n padding: '0.25rem',\n backgroundColor: themeVars.colors.muted,\n borderRadius: '0.5rem'\n})\n\nexport const uploadModeButton = style({\n flex: 1,\n padding: '0.5rem 1rem',\n fontSize: '0.875rem',\n fontWeight: 500,\n border: 'none',\n borderRadius: '0.375rem',\n cursor: 'pointer',\n transition: 'all 0.2s',\n backgroundColor: 'transparent',\n color: themeVars.colors.mutedForeground\n})\n\nexport const uploadModeButtonActive = style({\n flex: 1,\n padding: '0.5rem 1rem',\n fontSize: '0.875rem',\n fontWeight: 500,\n border: 'none',\n borderRadius: '0.375rem',\n cursor: 'pointer',\n transition: 'all 0.2s',\n backgroundColor: themeVars.colors.background,\n color: themeVars.colors.foreground,\n boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)'\n})\n\nexport const uploadArea = style({\n border: `2px dashed ${themeVars.colors.border}`,\n borderRadius: themeVars.radius.lg,\n aspectRatio: '1 / 1',\n width: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n transition: 'background-color 0.2s',\n overflow: 'hidden',\n position: 'relative',\n ':hover': {\n backgroundColor: 'rgba(var(--muted-rgb), 0.5)'\n }\n})\n\nexport const uploadPlaceholder = style({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: themeVars.spacing.sm,\n padding: themeVars.spacing.lg,\n color: themeVars.colors.mutedForeground\n})\n\nexport const uploadHint = style({\n fontSize: '0.875rem',\n marginTop: '0.25rem'\n})\n\nexport const previewImage = style({\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n borderRadius: themeVars.radius.lg\n})\n\nexport const urlInputContainer = style({\n display: 'flex',\n flexDirection: 'column',\n gap: themeVars.spacing.md\n})\n\nexport const imagePreview = style({\n width: '100%',\n aspectRatio: '1',\n borderRadius: themeVars.radius.lg,\n overflow: 'hidden',\n border: `1px solid ${themeVars.colors.border}`\n})\n\nexport const urlInputWrapper = style({\n display: 'flex',\n gap: '0.5rem'\n})\n\nexport const errorText = style({\n fontSize: '0.75rem',\n color: themeVars.colors.destructive,\n marginTop: '0.5rem',\n display: 'flex',\n alignItems: 'center',\n gap: '0.25rem'\n})\n\nexport const errorBanner = style({\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem',\n padding: themeVars.spacing.sm,\n backgroundColor: 'rgba(var(--destructive-rgb), 0.1)',\n border: `1px solid ${themeVars.colors.destructive}`,\n borderRadius: themeVars.radius.md,\n color: themeVars.colors.destructive,\n fontSize: '0.875rem'\n})\n\nexport const warningBanner = style({\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem',\n padding: themeVars.spacing.sm,\n backgroundColor: 'rgba(251, 191, 36, 0.1)',\n border: '1px solid rgb(251, 191, 36)',\n borderRadius: themeVars.radius.md,\n color: 'rgb(251, 191, 36)',\n fontSize: '0.875rem'\n})\n\nexport const spinner = style({\n animation: `${spin} 1s linear infinite`\n})\n","import type { SuiClient } from '@mysten/sui/client'\nimport type { WalrusClient } from '@mysten/walrus'\nimport * as Dialog from '@radix-ui/react-dialog'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { Info, Loader2, Upload, X } from 'lucide-react'\nimport type { FC } from 'react'\nimport { useEffect, useRef, useState } from 'react'\nimport {\n type UseUpdateSiteMetadataParams,\n useUpdateSiteMetadata\n} from '~/hooks/useUpdateSiteMetadata'\nimport { useWalrusSiteQuery } from '~/queries'\nimport { Button } from '../ui/Button'\nimport { Input, Label, Textarea } from '../ui/Input'\nimport * as styles from './UpdateMetadataModal.css'\n\n/**\n * Props for the UpdateMetadataModal component.\n *\n * @example\n * ```tsx\n * <UpdateMetadataModal\n * siteId=\"0x123...\"\n * isOpen={isOpen}\n * onOpenChange={setIsOpen}\n * clients={{ suiClient, queryClient, walrusClient }}\n * currentAccount={currentAccount}\n * signAndExecuteTransaction={signAndExecuteTransaction}\n * />\n * ```\n */\ninterface UpdateMetadataModalProps {\n /** The object ID of the published Walrus site to update */\n siteId: string\n /** Controls the visibility of the modal */\n isOpen: boolean\n /** Callback when modal open state changes */\n onOpenChange: (open: boolean) => void\n /** Optional callback when metadata update succeeds. Receives the transaction digest. */\n onSuccess?: (digest: string) => void\n /** Optional callback when metadata update fails. Receives the error object. */\n onError?: (error: Error) => void\n /** Object containing Sui, Query, and Walrus clients */\n clients: {\n /** Sui blockchain client for on-chain operations */\n suiClient: SuiClient\n /** React Query client for data fetching and caching */\n queryClient: QueryClient\n /** Walrus storage client for blob operations */\n walrusClient: WalrusClient\n }\n /** Current connected wallet account. Must be non-null to submit updates. */\n currentAccount: UseUpdateSiteMetadataParams['currentAccount']\n /** Function to sign and execute transactions on the Sui blockchain */\n signAndExecuteTransaction: UseUpdateSiteMetadataParams['signAndExecuteTransaction']\n /** Optional transaction sponsorship configuration */\n sponsorConfig?: UseUpdateSiteMetadataParams['sponsorConfig']\n}\n\n/**\n * UpdateMetadataModal Component\n *\n * A modal dialog component for updating metadata (name, description, project URL, preview image)\n * of an existing Walrus site on the Sui blockchain.\n *\n * ## Features\n * - Updates site name (max 120 chars), description (max 150 chars), project URL, and preview image\n * - Supports image upload (max 5MB) or URL input\n * - Validates wallet connection before allowing submission\n * - Automatically loads current site metadata when opened\n * - Shows loading states and error messages\n *\n * ## Usage\n *\n * ```tsx\n * import { UpdateMetadataModal, isUpdateMetadataModalOpen } from '@cmdoss/walrus-site-builder-react'\n * import { useStore } from '@nanostores/react'\n *\n * function MyComponent() {\n * const isOpen = useStore(isUpdateMetadataModalOpen)\n *\n * return (\n * <UpdateMetadataModal\n * siteId=\"0x123...\"\n * isOpen={isOpen}\n * onOpenChange={isUpdateMetadataModalOpen.set}\n * onSuccess={(digest) => console.log('Updated:', digest)}\n * clients={{ suiClient, queryClient, walrusClient }}\n * currentAccount={currentAccount}\n * signAndExecuteTransaction={signAndExecuteTransaction}\n * />\n * )\n * }\n * ```\n *\n * ## State Management\n *\n * The modal visibility is typically controlled via the `isUpdateMetadataModalOpen` atom:\n *\n * ```tsx\n * import { isUpdateMetadataModalOpen } from '@cmdoss/walrus-site-builder-react'\n *\n * // Open modal\n * isUpdateMetadataModalOpen.set(true)\n *\n * // Close modal\n * isUpdateMetadataModalOpen.set(false)\n * ```\n *\n * @see {@link useUpdateSiteMetadata} - The hook used internally for metadata updates\n * @see {@link useWalrusSiteQuery} - Used to fetch current site data\n */\n\nconst UpdateMetadataModal: FC<UpdateMetadataModalProps> = ({\n siteId,\n isOpen,\n onOpenChange,\n onSuccess,\n onError,\n clients: { suiClient, queryClient, walrusClient },\n currentAccount,\n signAndExecuteTransaction,\n sponsorConfig\n}) => {\n const [siteName, setSiteName] = useState('')\n const [description, setDescription] = useState('')\n const [projectUrl, setProjectUrl] = useState('')\n const [imageUrl, setImageUrl] = useState('')\n const [uploadMode, setUploadMode] = useState<'file' | 'url'>('url')\n const [urlInput, setUrlInput] = useState('')\n const [urlError, setUrlError] = useState('')\n const [fileSizeError, setFileSizeError] = useState('')\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n const MAX_FILE_SIZE = 5 * 1024 * 1024 // 5MB\n\n // Get current site data\n const { data: siteData, isLoading: isLoadingSite } = useWalrusSiteQuery(\n siteId,\n {\n suiClient,\n queryClient\n }\n )\n\n // Update metadata hook\n const { updateSiteMetadata, isUpdating, error } = useUpdateSiteMetadata({\n siteId,\n clients: {\n suiClient,\n queryClient,\n walrusClient\n },\n currentAccount,\n signAndExecuteTransaction,\n sponsorConfig\n })\n\n // Check if SDK is ready\n const isSdkReady = !!currentAccount && !!suiClient && !!walrusClient\n\n // Populate form with current site data\n useEffect(() => {\n if (siteData && isOpen) {\n setSiteName(siteData.name || '')\n setDescription(siteData.description || '')\n setProjectUrl(siteData.project_url || '')\n setImageUrl(siteData.image_url || '')\n setUrlInput(siteData.image_url || '')\n }\n }, [siteData, isOpen])\n\n // Reset form when modal closes\n useEffect(() => {\n if (!isOpen) {\n setUrlError('')\n setFileSizeError('')\n setUploadMode('url')\n }\n }, [isOpen])\n\n // Handle image file upload\n const handleImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file) return\n\n if (file.size > MAX_FILE_SIZE) {\n setFileSizeError(\n `File size exceeds 5MB limit (${(file.size / 1024 / 1024).toFixed(2)}MB)`\n )\n e.target.value = ''\n return\n }\n\n setFileSizeError('')\n const reader = new FileReader()\n reader.onload = e => {\n const result = e.target?.result\n if (typeof result === 'string') {\n setImageUrl(result)\n }\n }\n reader.readAsDataURL(file)\n }\n\n // Handle URL submit\n const handleUrlSubmit = () => {\n if (!urlInput.trim()) {\n setUrlError('Please enter a valid URL')\n return\n }\n\n try {\n new URL(urlInput)\n setImageUrl(urlInput)\n setUrlError('')\n } catch {\n setUrlError('Please enter a valid URL')\n }\n }\n\n // Handle form submission\n const handleSubmit = async () => {\n if (!isSdkReady) {\n const error = new Error(\n 'Wallet not connected. Please connect your wallet first.'\n )\n onError?.(error)\n return\n }\n\n try {\n const digest = await updateSiteMetadata({\n siteName,\n metadata: {\n description: description || undefined,\n project_url: projectUrl || undefined,\n image_url: imageUrl || undefined\n }\n })\n onSuccess?.(digest)\n onOpenChange(false)\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Unknown error')\n onError?.(error)\n }\n }\n\n // Check if form has changes\n const hasChanges =\n siteName !== (siteData?.name || '') ||\n description !== (siteData?.description || '') ||\n projectUrl !== (siteData?.project_url || '') ||\n imageUrl !== (siteData?.image_url || '')\n\n const isLoading = isLoadingSite || isUpdating\n\n return (\n <Dialog.Root open={isOpen} onOpenChange={onOpenChange}>\n <Dialog.Portal>\n <Dialog.Overlay className={styles.overlay} />\n <Dialog.Content className={styles.content}>\n <div className={styles.header}>\n <Dialog.Title className={styles.title}>\n Update Site Metadata\n </Dialog.Title>\n <Dialog.Description className={styles.description}>\n Update the metadata for your site\n </Dialog.Description>\n <Dialog.Close asChild>\n <button type=\"button\" className={styles.closeButton}>\n <X size={20} />\n </button>\n </Dialog.Close>\n </div>\n\n {isLoadingSite ? (\n <div className={styles.loadingContainer}>\n <Loader2 size={24} className={styles.spinner} />\n <p>Loading site data...</p>\n </div>\n ) : (\n <div className={styles.body}>\n {/* Image URL */}\n <fieldset>\n <div className={styles.fieldLabel}>\n <Label>Preview Image</Label>\n <span className={styles.optionalLabel}>Max 5MB</span>\n </div>\n\n {/* Upload Mode Toggle */}\n <div className={styles.uploadModeToggle}>\n <button\n type=\"button\"\n onClick={() => {\n setUploadMode('file')\n setUrlError('')\n }}\n className={\n uploadMode === 'file'\n ? styles.uploadModeButtonActive\n : styles.uploadModeButton\n }\n >\n Upload File\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setUploadMode('url')\n setFileSizeError('')\n }}\n className={\n uploadMode === 'url'\n ? styles.uploadModeButtonActive\n : styles.uploadModeButton\n }\n >\n From URL\n </button>\n </div>\n\n {uploadMode === 'file' ? (\n <>\n <div\n className={styles.uploadArea}\n onClick={() =>\n !isUpdating && fileInputRef.current?.click()\n }\n style={{\n cursor: isUpdating ? 'wait' : 'pointer',\n opacity: isUpdating ? 0.6 : 1\n }}\n >\n {imageUrl ? (\n <img\n src={imageUrl}\n alt=\"Preview\"\n className={styles.previewImage}\n />\n ) : (\n <div className={styles.uploadPlaceholder}>\n <Upload size={32} />\n <p>Click to upload</p>\n <p className={styles.uploadHint}>\n Square image recommended\n </p>\n </div>\n )}\n </div>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleImageChange}\n style={{ display: 'none' }}\n />\n {fileSizeError && (\n <p className={styles.errorText}>\n <Info size={14} />\n {fileSizeError}\n </p>\n )}\n </>\n ) : (\n <div className={styles.urlInputContainer}>\n {imageUrl && (\n <div className={styles.imagePreview}>\n <img\n src={imageUrl}\n alt=\"Preview\"\n className={styles.previewImage}\n />\n </div>\n )}\n <div className={styles.urlInputWrapper}>\n <Input\n value={urlInput}\n onChange={e => {\n setUrlInput(e.target.value)\n setUrlError('')\n }}\n onKeyDown={e => {\n if (e.key === 'Enter') {\n handleUrlSubmit()\n }\n }}\n placeholder=\"https://example.com/image.png\"\n disabled={isUpdating}\n />\n <Button\n onClick={handleUrlSubmit}\n disabled={isUpdating}\n style={{ flexShrink: 0 }}\n >\n Apply\n </Button>\n </div>\n {urlError && (\n <p className={styles.errorText}>\n <Info size={14} />\n {urlError}\n </p>\n )}\n </div>\n )}\n </fieldset>\n {/* Site Name */}\n <fieldset>\n <div className={styles.fieldLabel}>\n <Label>Site Name</Label>\n <span className={styles.charCount}>\n {siteName.length}/120\n </span>\n </div>\n <Input\n value={siteName}\n onChange={e => setSiteName(e.target.value.slice(0, 120))}\n placeholder=\"Enter site name...\"\n disabled={isUpdating}\n />\n </fieldset>\n\n {/* Description */}\n <fieldset>\n <div className={styles.fieldLabel}>\n <Label>Description</Label>\n <span className={styles.charCount}>\n {description.length}/150\n </span>\n </div>\n <Textarea\n value={description}\n onChange={e => setDescription(e.target.value.slice(0, 150))}\n placeholder=\"Enter description...\"\n rows={4}\n disabled={isUpdating}\n />\n </fieldset>\n\n {/* Project URL */}\n <fieldset>\n <Label>\n Project URL\n <span className={styles.optionalLabel}> (Optional)</span>\n </Label>\n <Input\n value={projectUrl}\n onChange={e => setProjectUrl(e.target.value)}\n placeholder=\"https://github.com/username/project\"\n disabled={isUpdating}\n />\n </fieldset>\n\n {!isSdkReady && (\n <div className={styles.warningBanner}>\n <Info size={16} />\n <span>Please connect your wallet to update metadata</span>\n </div>\n )}\n {error && (\n <div className={styles.errorBanner}>\n <Info size={16} />\n <span>Failed to update metadata: {error.message}</span>\n </div>\n )}\n </div>\n )}\n\n <div className={styles.footer}>\n <Button\n variant=\"outline\"\n onClick={() => onOpenChange(false)}\n disabled={isUpdating}\n >\n Cancel\n </Button>\n <Button\n onClick={handleSubmit}\n disabled={!hasChanges || isLoading || !isSdkReady}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem'\n }}\n >\n {isUpdating && <Loader2 size={16} className={styles.spinner} />}\n {isUpdating\n ? 'Updating...'\n : !isSdkReady\n ? 'Connect Wallet'\n : 'Update Metadata'}\n </Button>\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n )\n}\n\nexport default UpdateMetadataModal\n","import { useStore } from '@nanostores/react'\nimport type { FC, ReactNode } from 'react'\nimport {\n type UseSitePublishingParams,\n useSitePublishing\n} from '~/hooks/useSitePublishing'\nimport { isUpdateMetadataModalOpen } from '~/stores/site-domain.store'\nimport ExtendTimeDialog from './extend-time-dialog/ExtendTimeDialog'\nimport PublishMenu from './publish-menu/PublishMenu'\nimport PublishModal from './publish-modal/PublishModal'\nimport SuiNsModal from './suins-modal/SuiNsModal'\nimport { ThemeProvider } from './ThemeProvider'\nimport { Button } from './ui/Button'\nimport UpdateMetadataModal from './update-metadata-modal/UpdateMetadataModal'\n\ninterface Props extends UseSitePublishingParams {\n children?: ReactNode\n}\n\nconst PublishButton: FC<Props> = ({\n children,\n siteId,\n assets,\n onUpdateSiteMetadata,\n onAssociatedDomain,\n onError,\n onExtendedBlobs,\n currentAccount,\n signAndExecuteTransaction,\n sponsorConfig,\n portalDomain,\n portalHttps,\n clients\n}) => {\n const {\n actions: {\n handleOpenPublishingDialog,\n handleOpenDomainDialog,\n handleRunDeploymentStep,\n handleSaveSiteMetadata,\n handleAssociateDomain,\n handleExtendBlobs\n }\n } = useSitePublishing({\n siteId,\n assets,\n onUpdateSiteMetadata,\n onAssociatedDomain,\n onError,\n onExtendedBlobs,\n currentAccount,\n signAndExecuteTransaction,\n sponsorConfig,\n clients,\n portalDomain,\n portalHttps\n })\n const network = clients.suiClient.network\n const updateMetadataModalOpen = useStore(isUpdateMetadataModalOpen)\n\n return (\n <ThemeProvider>\n <PublishMenu\n siteId={siteId}\n onPublishClick={handleOpenPublishingDialog}\n onDomainClick={handleOpenDomainDialog}\n network={network === 'mainnet' ? 'mainnet' : 'testnet'}\n portalDomain={portalDomain}\n portalHttps={portalHttps}\n clients={clients}\n currentAccount={currentAccount}\n >\n {children || <Button>Publish</Button>}\n </PublishMenu>\n <PublishModal\n siteId={siteId}\n assets={assets}\n onDeploy={handleRunDeploymentStep}\n onSaveMetadata={handleSaveSiteMetadata}\n onExtendBlobs={handleExtendBlobs}\n clients={clients}\n />\n <SuiNsModal\n siteId={siteId}\n onAssociateDomain={handleAssociateDomain}\n currentAccount={currentAccount}\n portalDomain={portalDomain}\n portalHttps={portalHttps}\n clients={clients}\n signAndExecuteTransaction={signAndExecuteTransaction}\n sponsorConfig={sponsorConfig}\n />\n <ExtendTimeDialog\n siteId={siteId}\n currentAccount={currentAccount}\n clients={clients}\n signAndExecuteTransaction={signAndExecuteTransaction}\n sponsorConfig={sponsorConfig}\n onSuccess={(message, digest) => {\n onExtendedBlobs?.(message, digest)\n }}\n />\n {siteId && (\n <UpdateMetadataModal\n siteId={siteId}\n isOpen={updateMetadataModalOpen}\n onOpenChange={isUpdateMetadataModalOpen.set}\n onSuccess={digest => {\n console.log('✅ Site metadata updated:', digest)\n // Success is handled silently - modal closes automatically and queries are invalidated\n }}\n onError={error => {\n onError?.(error.message)\n console.error('❌ Failed to update metadata:', error)\n }}\n clients={{\n suiClient: clients.suiClient,\n queryClient: clients.queryClient,\n walrusClient: clients.walrusClient\n }}\n currentAccount={currentAccount}\n signAndExecuteTransaction={signAndExecuteTransaction}\n sponsorConfig={sponsorConfig}\n />\n )}\n </ThemeProvider>\n )\n}\n\nexport default PublishButton\n"],"x_google_ignoreList":[16,17,18,19,20],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAgB,QAAW,OAAyC;AAClE,QAAO,UAAU,QAAQ,UAAU;;;;;ACDrC,MAAa,YAAY;CACvB,eAAe,SAA6B,YAC1C;EAAC;EAAiB;EAAS;EAAQ;CACrC,oBAAoB,MAAc,YAChC;EAAC;EAAuB;EAAM;EAAQ;CACxC,aAAa,WAA+B,CAAC,eAAe,OAAO;CACnE,cAAc,SAA6B,YACzC;EAAC;EAAgB;EAAS;EAAQ;CACpC,cAAc,UAAyB,WACrC;EAAC;EAAgB;EAAU;EAAO;CACrC;;;;ACoBD,SAAgB,qBACd,gBACA,SAImB;CACnB,MAAM,EAAE,WAAW,gBAAgB;CACnC,MAAM,EAAE,YAAY;CACpB,MAAM,cAAc,cAEhB,IAAI,YAAY;EACd,SAAS,UAAU,YAAY,YAAY,YAAY;EACvD,QAAQ;EACT,CAAC,EACJ,CAAC,UAAU,CACZ;CAED,MAAM,mBAAmB,SACvB;EACE,UAAU,UAAU,aAAa,gBAAgB,SAAS,QAAQ;EAClE,SAAS,YAAY;AACnB,OAAI,CAAC,gBAAgB,QAAS,QAAO,EAAE;AAEvC,OAAI;IACF,IAAIA,aAA4B,EAAE;IAClC,IAAI,cAAc;IAClB,IAAIC;IAGJ,MAAM,iBACJC,cAAY,UAAsC;AAEpD,QAAI,CAAC,gBAAgB;AACnB,aAAQ,KAAK,mCAAmC,UAAU;AAC1D,YAAO,EAAE;;AAGX,YAAQ,IAAI,kBAAkB,eAAe;AAG7C,YAAQ,IACN,kBACA,GAAG,eAAe,yCACnB;AACD,WAAO,aAAa;KAClB,MAAM,WAAW,MAAM,UAAU,gBAAgB;MAC/C,OAAO,eAAe;MACtB,QAAQ,EACN,YAAY,GAAG,eAAe,0CAC/B;MACD,SAAS;OAAE,aAAa;OAAM,UAAU;OAAM,aAAa;OAAM;MACjE;MACD,CAAC;AAEF,aAAQ,IAAI,YAAY,SAAS;KAGjC,MAAMC,YAAU,SAAS,KACtB,QAAO,QAAO,IAAI,MAAM,SAAS,aAAa,aAAa,CAC3D,KAAI,QAAO;MACV,MAAMC,YAAU,IAAI,MAAM;MAC1B,MAAM,SACJA,aAAW,YAAYA,YAClBA,UAAQ,SACT,EAAE;AAER,aAAO;OACL,MAAO,QAAQ,eAA0B;OACzC,UAAU,IAAI,MAAM,YAAY;OAChC,WAAW,QAAQ,0BACf,OAAO,OAAO,wBAAwB,GACtC;OACL;OACD,CACD,QAAO,WAAU,OAAO,KAAK;AAEhC,kBAAa,CAAC,GAAG,YAAY,GAAGD,UAAQ;AACxC,mBAAc,SAAS;AACvB,cAAS,SAAS;;AAGpB,WAAO;YACA,OAAO;AACd,YAAQ,MAAM,iCAAiC,MAAM;AACrD,WAAO,EAAE;;;EAGb,SAAS,CAAC,CAAC,gBAAgB;EAC3B,WAAW,MAAO,KAAK;EACvB,OAAO;EACP,aAAY,iBAAgB,KAAK,IAAI,MAAO,KAAK,cAAc,IAAM;EACtE,EACD,YACD;CAGD,MAAM,UAAU,WACd,EACE,SACE,iBAAiB,MAAM,KAAI,YAAW;EACpC,UAAU,UAAU,kBAAkB,OAAO,MAAM,QAAQ;EAC3D,SAAS,YAAY,MAAM,aAAa,cAAc,OAAO,KAAK;EAClE,SAAS,CAAC,CAAC,eAAe,CAAC,CAAC,OAAO;EACpC,EAAE,IAAI,EAAE,EACZ,EACD,YACD;AAiCD,QAAO;EAAE,WA/BS,cACV,iBAAiB,aAAa,QAAQ,MAAK,MAAK,EAAE,UAAU,EAClE,CAAC,iBAAiB,WAAW,QAAQ,CACtC;EA4BmB,SA3BJ,cACR,iBAAiB,WAAW,QAAQ,MAAK,MAAK,EAAE,QAAQ,EAC9D,CAAC,iBAAiB,SAAS,QAAQ,CACpC;EAwB4B,MAvBhB,cAET,QACG,KAAI,MAAK,EAAE,KAAK,CAChB,OAAO,QAAQ,CACf,KACC,OACqB;GACjB,MAAM,EAAE,KAAK,MAAM,GAAG,GAAG;GACzB,QAAQ,EAAE;GACV,uBAAuB,OAAO,EAAE,sBAAsB;GACtD,OAAO,EAAE;GACT,cAAc,EAAE;GAChB,YAAY,EAAE;GACd,eACE,YAAY,YACR,WAAW,EAAE,KAAK,MAAM,GAAG,GAAG,CAAC,YAC/B,UAAU,EAAE,KAAK,MAAM,GAAG,GAAG,CAAC;GACrC,EACJ,EACL,CAAC,SAAS,QAAQ,CACnB;EAEkC;;;;;ACpHrC,SAAS,YAAY,OAAmC;AACtD,SAAQ,MAAM,MAAd;EACE,KAAK,UACH,OAAM,IAAI,MAAM,+BAA+B;EACjD,KAAK,YACH,OAAM,IAAI,MAAM,6BAA6B;EAC/C,KAAK,eACH,OAAM,IAAI,MAAM,2CAA2C;EAC7D,KAAK,uBACH,OAAM,IAAI,MAAM,sCAAsC;EACxD,QACE,OAAM,IAAI,MAAM,2CAA2C;;;AAIjE,eAAe,uBACb,WACA,QAC6B;CAC7B,MAAME,gBAAoC,EAAE;CAC5C,IAAIC,SAAwB;AAC5B,QAAO,MAAM;EACX,MAAM,OAAO,MAAM,UAAU,iBAAiB;GAAE,UAAU;GAAQ;GAAQ,CAAC;AAC3E,WAAS,KAAK;AACd,gBAAc,KAAK,GAAG,KAAK,KAAK;AAChC,MAAI,CAAC,KAAK,YAAa;;AAEzB,QAAO;;AAGT,eAAe,mBACb,WACA,QACA,WACA;CAKA,MAAM,iBAJgB,MAAM,uBAAuB,WAAW,OAAO,EAKlE,QAAO,MAAK,EAAE,eAAe,GAAG,UAAU,kBAAkB,CAC5D,QAAO,MAAK,EAAE,KAAK,SAAS,GAAG,UAAU,sBAAsB;CAKlE,MAAMC,YAA4B,EAAE;AACpC,MAAK,MAAM,MAAM,eAAe;EAC9B,MAAM,SAAS,MAAM,UAAU,UAAU;GACvC,IAAI,GAAG;GACP,SAAS,EAAE,aAAa,MAAM;GAC/B,CAAC;AAEF,MAAI,OAAO,MAAM,SAAS,aAAa,aACrC,OAAM,IAAI,MAAM,oCAAoC;EAEtD,MAAM,SAAS,OAAO,MAAM,SAAS;AACrC,MAAI,MAAM,QAAQ,OAAO,CAAE,OAAM,IAAI,MAAM,iCAAiC;AAC5E,MAAI,EAAE,WAAW,QACf,OAAM,IAAI,MAAM,uCAAuC;EAIzD,MAAM,gBAAgB,OAAO;EAC7B,MAAMC,SAAuB;GAC3B,WAAW,cAAc,OAAO;GAChC,SAAS,cAAc,OAAO;GAC9B,SAAS,cAAc,OAAO,QAAQ,OAAO,SAAS,KAAI,MAAK,EAAE,OAAO;GACxE,MAAM,cAAc,OAAO;GAC5B;AACD,YAAU,KAAK,OAAO;;AAExB,QAAO;;AAGT,eAAe,oBACb,WACA,IACA,WACyB;CAGzB,MAAM,SAAS,MAAM,UAAU,UAAU;EACvC;EACA,SAAS,EAAE,aAAa,MAAM;EAC/B,CAAC;CAEF,MAAM,QAAQ,OAAO,MAAM,SAAS,SAAS,OAAO;AACpD,KAAI,MAAO,aAAY,MAAM;CAE7B,MAAM,OAAO,OAAO,MAAM,SAAS;AACnC,KAAI,CAAC,KAAM,OAAM,IAAI,MAAM,mCAAmC;CAC9D,MAAM,WAAW;CAEjB,MAAM,YAAY,MAAM,mBAAmB,WAAW,IAAI,UAAU;AAIpE,QAFsB;EAAE;EAAI,GAAG;EAAU;EAAW;;AAKtD,SAAgB,mBACd,IACA,SAIA;CACA,MAAM,EAAE,YAAY,QAAQ;CAC5B,MAAM,YAAY,cACV,YAAY,SAAqC,WACvD,CAAC,QAAQ,CACV;AAED,QAAO,SACL;EACE,UAAU,UAAU,WAAW,GAAG;EAClC,SAAS,YAAY;AACnB,OAAI,CAAC,GAAI,OAAM,IAAI,MAAM,sBAAsB;AAC/C,UAAO,oBAAoB,QAAQ,WAAW,IAAI,UAAU;;EAE9D,SAAS,CAAC,CAAC;EACZ,EACD,QAAQ,YACT;;AAGH,eAAe,8BACb,WACA,SACA,WACA,OACA,aAKC;AACD,KAAI;EACF,MAAM,WAAW,MAAM,UAAU,gBAAgB;GAC/C,OAAO;GACP,QAAQ,EACN,YAAY,GAAG,UAAU,eAC1B;GACD,SAAS;IAAE,aAAa;IAAM,UAAU;IAAM;GAC9C,QAAQ;GACR,OAAO,SAAS;GACjB,CAAC;AAIF,MAAI,CAAC,SAAS,QAAQ,SAAS,KAAK,WAAW,EAC7C,QAAO;GACL,OAAO,EAAE;GACT,YAAY,SAAS,cAAc;GACnC,aAAa,SAAS;GACvB;AAmEH,SAAO;GACL,OAjEkB,SAAS,KAC1B,QAAO,QAAO;AAEb,QAAI,CAAC,IAAI,MAAM;AACb,aAAQ,KAAK,wBAAwB,IAAI;AACzC,YAAO;;AAIT,QAAI,IAAI,KAAK,SAAS,OAAO;AAC3B,aAAQ,KACN,2BACA,IAAI,KAAK,UACT,IAAI,KAAK,QAAQ,MAClB;AACD,YAAO;;IAIT,MAAM,OAAO,IAAI,KAAK;AACtB,QAAI,CAAC,QAAQ,SAAS,GAAG,UAAU,cACjC,QAAO;AAIT,QAAI,CAAC,IAAI,KAAK,UAAU;AACtB,aAAQ,KAAK,4BAA4B,IAAI;AAC7C,YAAO;;AAGT,WAAO;KACP,CACD,KAAI,QAAO;AAEV,QAAI,CAAC,IAAI,KAAM,QAAO;IAGtB,MAAM,UAAU,IAAI,KAAK,SAAS;AAClC,QAAI,CAAC,SAAS;AACZ,aAAQ,KAAK,6BAA6B,IAAI,KAAK,SAAS;AAC5D,YAAO;;IAGT,MAAM,cAAc;AAGpB,QAAI,CAAC,YAAY,MAAM;AACrB,aAAQ,KAAK,sBAAsB,IAAI,KAAK,SAAS;AACrD,YAAO;;AAGT,WAAO;KACL,IAAI,IAAI,KAAK;KACb,MAAM,YAAY;KAClB,aAAa,YAAY,eAAe;KACxC,WAAW,YAAY,aAAa;KACpC,MAAM,YAAY,QAAQ;KAC1B,aAAa,YAAY,eAAe;KACxC,SAAS,YAAY,WAAW;KAChC,WAAW,EAAE;KACd;KACD,CACD,QAAQ,SAAiC,SAAS,KAAK;GAIxD,YAAY,SAAS,cAAc;GACnC,aAAa,SAAS;GACvB;UACM,OAAO;AACd,UAAQ,MAAM,qCAAqC,MAAM;AACzD,QAAM;;;AAIV,SAAgB,oBACd,SACA,SAIA,SAIA;CACA,MAAM,EAAE,WAAW,gBAAgB;CACnC,MAAM,EAAE,YAAY;CACpB,MAAM,YAAY,cACV,YAAY,SAAqC,WACvD,CAAC,QAAQ,CACV;AAED,SAAQ,IAAI,8CAA8C,SAAS,UAAU;CAE7E,MAAM,iBAAiB,SACrB;EACE,UAAU;GACR,GAAG,UAAU,YAAY,SAAS,QAAQ;GAC1C,SAAS;GACT,SAAS;GACV;EACD,SAAS,YAAY;AACnB,OAAI,CAAC,QAAS,QAAO;IAAE,OAAO,EAAE;IAAE,YAAY;IAAM,aAAa;IAAO;AACxE,UAAO,8BACL,WACA,SACA,WACA,SAAS,OACT,SAAS,OACV;;EAEH,SAAS,CAAC,CAAC;EACX,WAAW,MAAO,KAAK;EACvB,OAAO;EACP,aAAY,iBAAgB,KAAK,IAAI,MAAO,KAAK,cAAc,IAAM;EACtE,EACD,YACD;AAGD,QAAO;EACL,MAAM,eAAe,MAAM,SAAS,EAAE;EACtC,YAAY,eAAe,MAAM,cAAc;EAC/C,aAAa,eAAe,MAAM,eAAe;EACjD,WAAW,eAAe;EAC1B,SAAS,eAAe;EACxB,OAAO,eAAe;EACvB;;;;;AC7UH,SAAgB,mBACd,IACA,SAGA;CACA,MAAM,EAAE,gBAAgB;AACxB,QAAO,SACL;EACE,UAAU,CAAC,eAAe,IAAI,aAAa;EAC3C,SAAS,YAAY;AACnB,OAAI,CAAC,GAAI,QAAO,EAAE;GAClB,MAAM,QAAQ,MAAM,GAAG,WAAW;GAClC,MAAMC,SAAmB,EAAE;AAC3B,QAAK,MAAM,QAAQ,OAAO;IACxB,MAAMC,YAAU,MAAM,IAAI,SAAS,KAAK;AACxC,QAAI,CAACA,UAAS;IAEd,MAAM,WAAW,aADJ,MAAM,cAAcA,UAAQ,CACN;AACnC,WAAO,KAAK;KAAE;KAAM;KAAS;KAAU,CAAC;;AAE1C,UAAO;;EAET,SAAS,CAAC,CAAC;EACX,WAAW,MAAS;EACrB,EACD,YACD;;;;;ACjCH,MAAa,qBAAqB,KAAK,MAAM;AAC7C,MAAa,oBAAoB,KAAK,MAAM;AAC5C,MAAa,kCAAkC,KAAK,MAAM;AAC1D,MAAa,yBAAyB,KAAK,MAAM;AACjD,MAAa,4BAA4B,KAAK,MAAM;;;;ACJpD,MAAM,gBAAgB;AACtB,MAAM,sBAAsB;AAE5B,IAAM,eAAN,MAAmB;CACjB,QAAQ,KAAK,cAAc;CAC3B,cAAc,KAAK,oBAAoB;CACvC,WAAW,KAA2B,qCAAqC;CAC3E,OAAO,KAAa,GAAG;CACvB,aAAa,KAAa,GAAG;CAC7B,SAAS,KAAK,EAAE;CAChB,YAAY,KAAK,MAAM;CACvB,UAAU,KAAK,MAAM;CACrB,WAAW,KAA8C,EAAE,CAAC;CAG5D,gBAAgB,KAAK,cAAc;CACnC,sBAAsB,KAAK,oBAAoB;CAC/C,mBAAmB,KACjB,qCACD;CACD,eAAe,KAAa,GAAG;CAC/B,qBAAqB,KAAa,GAAG;CACrC,iBAAiB,KAAK,EAAE;CACxB,mBAAmB,KAA8C,EAAE,CAAC;CAGpE,UAAU,SACR;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACN,GAEC,SACA,eACA,SACA,QACA,YACA,QACA,UACA,eACA,qBACA,cACA,cACA,oBACA,gBACA,qBAEAC,YAAU,iBACVC,kBAAgB,wBACf,WAAW,WAAW,gBAAgB,SACvCC,WAAS,gBACT,eAAe,sBACf,WAAW,kBACX,KAAK,UACH,SAAS,MAAM,GAAG,MAAM,EAAE,MAAM,cAAc,EAAE,MAAM,CAAC,CACxD,KACC,KAAK,UACH,iBAAiB,MAAM,GAAG,MAAM,EAAE,MAAM,cAAc,EAAE,MAAM,CAAC,CAChE,CACN;;;;CAID,kBAAkB,SAAS,CAAC,KAAK,SAAS,GAAE,aAAY;AACtD,MAAI,CAAC,SAAU,QAAO;AACtB,MAAI,OAAO,aAAa,SAAU,QAAO;AACzC,SAAO,IAAI,gBAAgB,SAAS;GACpC;CAEF,gBAAgB;AACd,OAAK,cAAc,IAAI,KAAK,MAAM,KAAK,CAAC;AACxC,OAAK,oBAAoB,IAAI,KAAK,YAAY,KAAK,CAAC;AACpD,OAAK,iBAAiB,IAAI,KAAK,SAAS,KAAK,CAAC;AAC9C,OAAK,aAAa,IAAI,KAAK,KAAK,KAAK,CAAC;AACtC,OAAK,mBAAmB,IAAI,KAAK,WAAW,KAAK,CAAC;AAClD,OAAK,eAAe,IAAI,KAAK,OAAO,KAAK,CAAC;AAC1C,OAAK,iBAAiB,IAAI,KAAK,SAAS,KAAK,CAAC,KAAI,YAAS,EAAE,GAAGC,QAAM,EAAE,CAAC;;CAG3E,QAAQ;AACN,OAAK,MAAM,IAAI,KAAK,cAAc,KAAK,CAAC;AACxC,OAAK,YAAY,IAAI,KAAK,oBAAoB,KAAK,CAAC;AACpD,OAAK,SAAS,IAAI,KAAK,iBAAiB,KAAK,CAAC;AAC9C,OAAK,KAAK,IAAI,KAAK,aAAa,KAAK,CAAC;AACtC,OAAK,WAAW,IAAI,KAAK,mBAAmB,KAAK,CAAC;AAClD,OAAK,OAAO,IAAI,KAAK,eAAe,KAAK,CAAC;AAC1C,OAAK,SAAS,IAAI,KAAK,iBAAiB,KAAK,CAAC,KAAI,YAAS,EAAE,GAAGA,QAAM,EAAE,CAAC;AACzE,OAAK,QAAQ,IAAI,MAAM;;CAGzB,mBAAmB,KAAK,OAAO;;AAGjC,MAAa,oBAAoB,IAAI,cAAc;;;;AC7FnD,SAAgB,GAAM,MAAkB;AACtC,QAAO;EAAE,IAAI;EAAY;EAAW;;AAEtC,SAAgB,OAAU,OAAsB;AAC9C,QAAO;EAAE,IAAI;EAAO;EAAO;;;;;ACP7B,IAAY,sDAAL;AACL;AACA;AACA;AACA;AACA;;;AAGF,IAAY,gEAAL;AACL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAuBF,IAAM,sBAAN,MAA0B;CAExB,eAAe,KAAK,iBAAiB,KAAK;CAC1C,sBAAsB,SAAS,CAAC,KAAK,aAAa,GAAE,MAAK;AACvD,UAAQ,GAAR;GACE,KAAK,iBAAiB;GACtB,KAAK,iBAAiB,UACpB,QAAO;GACT,KAAK,iBAAiB;GACtB,KAAK,iBAAiB,UACpB,QAAO;GACT,KAAK,iBAAiB;GACtB,KAAK,iBAAiB,WACpB,QAAO;GACT,KAAK,iBAAiB;GACtB,KAAK,iBAAiB,UACpB,QAAO;GACT,KAAK,iBAAiB,SACpB,QAAO;GACT,QACE,QAAO;;GAEX;CAGF,sBAAsB,KAAK,MAAM;CACjC,iBAAiB,KAAuB,EAAE,CAAC;CAC3C,YAAY,SACV,CAAC,KAAK,aAAa,GACnB,iBACE,iBAAiB,iBAAiB,QAClC,iBAAiB,iBAAiB,YAClC,iBAAiB,iBAAiB,YAClC,iBAAiB,iBAAiB,aAClC,iBAAiB,iBAAiB,SACrC;CAED,mBAAmB,SAAS,CAAC,KAAK,aAAa,GAAE,MAAK;AACpD,UAAQ,GAAR;GACE,KAAK,iBAAiB,KACpB,QAAO;GACT,KAAK,iBAAiB,UACpB,QAAO;GACT,KAAK,iBAAiB,SACpB,QAAO;GACT,KAAK,iBAAiB,UACpB,QAAO;GACT,KAAK,iBAAiB,SACpB,QAAO;GACT,KAAK,iBAAiB,WACpB,QAAO;GACT,KAAK,iBAAiB,UACpB,QAAO;GACT,KAAK,iBAAiB,UACpB,QAAO;GACT,KAAK,iBAAiB,SACpB,QAAO;GACT,QACE,QAAO;;GAEX;CAEF,AAAQ;CACR,AAAQ;CAER,MAAM,kBACJ,KACA,QACA,MAC0B;AAC1B,MAAI,KAAK,UAAU,KAAK,CAAE,QAAO,OAAO,mCAAmC;AAI3E,UAFe,KAAK,aAAa,KAAK,EAEtC;GACE,KAAK,iBAAiB;AACpB,SAAK,aAAa,IAAI,iBAAiB,UAAU;AACjD,QAAI;AACF,UAAK,cAAc,IAAI,sBAAsB,QAAQ;MACnD,WAAW,KAAK;MAChB,WAAW,KAAK;MAChB,UAAU;OACR,MAAM,KAAK;OACX,aAAa,KAAK;OAClB,aAAa,KAAK;OAClB,WAAW,KAAK;OAChB,SAAS,KAAK,WAAW;OAC1B;MACF,CAAC;KACF,MAAM,OAAO,MAAM,KAAK,YAAY,kBAAkB;AACtD,SAAI,KAAK,UAAU,OAAM,MAAK,EAAE,OAAO,YAAY,CACjD,KAAI,KAAK,UAAU,OAAO,UAAU,KAAK,SAAS,OAAO,QAAQ;AAC/D,WAAK,aAAa,IAAI,iBAAiB,KAAK;AAC5C,aAAO,OAAO,sBAAsB;WAGpC,MAAK,aAAa,IAAI,iBAAiB,UAAU;SAE9C,MAAK,aAAa,IAAI,iBAAiB,SAAS;AACvD,YAAO,KAAK,kBAAkB,KAAK,QAAQ,KAAK;aACzC,GAAG;AACV,aAAQ,MAAM,6BAA6B,EAAE;KAC7C,MAAM,MACJ,aAAa,QAAQ,EAAE,UAAU;AACnC,UAAK,aAAa,IAAI,iBAAiB,KAAK;AAC5C,YAAO,OAAO,IAAI;;GAItB,KAAK,iBAAiB,UAAU;AAC9B,QAAI,CAAC,KAAK,YAAa,QAAO,OAAO,0BAA0B;AAE/D,SAAK,aAAa,IAAI,iBAAiB,UAAU;IACjD,MAAM,SAAS,kBAAkB,OAAO,KAAK;IAC7C,MAAM,YAAY,kBAAkB,UAAU,KAAK;AAEnD,QAAI;AACF,WAAM,KAAK,YAAY,eAAe,QAAQ,UAAU;aACjD,GAAG;AACV,aAAQ,MAAM,4BAA4B,EAAE;AAC5C,UAAK,aAAa,IAAI,iBAAiB,SAAS;AAChD,YAAO,OAAO,0BAA0B;;AAG1C,SAAK,aAAa,IAAI,iBAAiB,SAAS;AAChD,WAAO,KAAK,kBAAkB,KAAK,QAAQ,KAAK;;GAGlD,KAAK,iBAAiB;AACpB,QAAI,CAAC,KAAK,YAAa,QAAO,OAAO,0BAA0B;AAC/D,SAAK,aAAa,IAAI,iBAAiB,WAAW;AAClD,QAAI;AACF,WAAM,KAAK,YAAY,kBAAkB;AACzC,UAAK,aAAa,IAAI,iBAAiB,UAAU;AACjD,YAAO,KAAK,kBAAkB,KAAK,QAAQ,KAAK;aACzC,GAAG;AACV,aAAQ,MAAM,6BAA6B,EAAE;AAC7C,UAAK,aAAa,IAAI,iBAAiB,SAAS;AAGhD,YAAO,OADL,aAAa,QAAQ,EAAE,UAAU,2BACjB;;GAItB,KAAK,iBAAiB;AACpB,QAAI,CAAC,KAAK,YAAa,QAAO,OAAO,0BAA0B;AAC/D,SAAK,aAAa,IAAI,iBAAiB,UAAU;AACjD,QAAI;KACF,MAAM,EAAE,WAAW,MAAM,KAAK,YAAY,WAAW;AACrD,SAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,sBAAsB;AACnD,UAAK,aAAa,IAAI,iBAAiB,SAAS;AAChD,UAAK,SAAS;AACd,YAAO,GAAG,OAAO;aACV,GAAG;AACV,aAAQ,MAAM,0BAA0B,EAAE;AAC1C,UAAK,aAAa,IAAI,iBAAiB,UAAU;AAEjD,YAAO,OADK,aAAa,QAAQ,EAAE,UAAU,wBAC3B;;GAGtB,KAAK,iBAAiB;AACpB,QAAI,CAAC,KAAK,OAAQ,QAAO,OAAO,gBAAgB;AAEhD,SAAK,OAAO;AACZ,SAAK,oBAAoB;AACzB,SAAK,wBAAwB;AAC7B,WAAO,GAAG,KAAK,OAAO;GAExB,QACE,QAAO,OAAO,0BAA0B;;;CAI9C,QAAQ;AACN,OAAK,aAAa,IAAI,iBAAiB,KAAK;AAC5C,OAAK,eAAe,IAAI,EAAE,CAAC;AAC3B,OAAK,cAAc;;CAGrB,2BAA2B,KAAK,oBAAoB,IAAI,MAAM;CAC9D,+BAA+B,mBAAmB,IAAI,KAAK;;AAG7D,MAAa,sBAAsB,IAAI,qBAAqB;;;;;;;;AC/N5D,SAAgB,uBAAuB,EACrC,WACA,eACA,2BACA,iBAC+B;AAC/B,QAAO,cAAc;AACnB,MAAI,CAAC,cAAe,QAAO;AAE3B,SAAO,IAAI,2BAA2B;GACpC;GACA;GACA;GACA;GACD,CAAC;IACD;EAAC;EAAW;EAAe;EAA2B;EAAc,CAAC;;;;;ACoD1E,SAAgB,kBAAkB,EAChC,QACA,QACA,sBACA,oBACA,SACA,iBACA,gBACA,2BACA,eACA,cACA,aACA,SAAS,EAAE,WAAW,aAAa,aAAa,kBACtB;CAC1B,MAAM,CAAC,aAAa,kBAAkB,SAAS,MAAM;CAErD,MAAM,aAAa,uBAAuB;EACxC;EACA,eAAe,gBAAgB;EAC/B;EACA;EACD,CAAC;CAEF,MAAMC,MAAyC,cAAc;AAC3D,MAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,eAAgB;AACpD,SAAO,IAAI,qBACT,cACA,WACA,eAAe,SACf,2BACA,cACD;IACA;EACD;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAM,EACJ,MAAM,WACN,WAAW,oBACX,SAAS,qBACP,qBAAqB,gBAAgB;EAAE;EAAW;EAAa,CAAC;CAEpE,MAAM,EAAE,MAAM,mBAAmB,mBAAmB,QAAQ;EAC1D;EACA;EACD,CAAC;CAGF,MAAM,sBAAsB,SAAS,oBAAoB,oBAAoB;CAC7E,MAAM,YAAY,SAAS,oBAAoB,UAAU;CACzD,MAAM,iBAAiB,SAAS,oBAAoB,eAAe;CACnE,MAAM,eAAe,SAAS,oBAAoB,aAAa;CAC/D,MAAM,mBAAmB,SAAS,oBAAoB,iBAAiB;CACvE,MAAM,kBAAkB,SAAS,oBAAoB,oBAAoB;CAEzE,MAAM,SAAS,SAAS,kBAAkB,OAAO;CACjD,MAAMC,UAAQ,SAAS,kBAAkB,MAAM;CAC/C,MAAM,WAAW,SAAS,kBAAkB,SAAS;CACrD,MAAMC,SAAO,SAAS,kBAAkB,KAAK;CAC7C,MAAMC,gBAAc,SAAS,kBAAkB,YAAY;CAC3D,MAAM,wBAAwB,SAAS,kBAAkB,QAAQ;CACjE,MAAM,uBAAuB,SAAS,kBAAkB,QAAQ;CAChE,MAAM,cAAc,SAAS,kBAAkB;CAG/C,MAAM,aAAa,CAAC,CAAC;CACrB,MAAM,gBAAgB,cAAc;AAClC,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,wBAAwB,QAAQ,cAAc,YAAY;IAChE;EAAC;EAAQ;EAAc;EAAY,CAAC;CAEvC,MAAM,oBAAoB,UAAU,QAAO,MAAK,EAAE,iBAAiB,OAAO;AAG1E,iBAAgB;AACd,MAAI,CAAC,eAAgB;AACrB,UAAQ,IAAI,wCAAwC,eAAe;AACnE,oBAAkB,cAAc,IAAI,eAAe,QAAQ,GAAG;AAC9D,oBAAkB,oBAAoB,IAAI,eAAe,eAAe,GAAG;AAC3E,oBAAkB,iBAAiB,IAAI,eAAe,aAAa,KAAK;AACxE,oBAAkB,mBAAmB,IAAI,eAAe,eAAe,KAAK;AAC5E,oBAAkB,aAAa,IAAI,eAAe,QAAQ,GAAG;AAC7D,oBAAkB,OAAO;IACxB,CAAC,eAAe,CAAC;CAGpB,MAAM,0BAA0B,YAAY;AAC1C,MAAI,CAAC,IAAK,QAAO,UAAU,sBAAsB;AACjD,MAAI,oBAAoB,KAAM,QAAO,UAAU,6BAA6B;EAC5E,MAAMC,eAA6B;GACjC,IAAI;GACJ;GACA;GACA,UAAU,YAAY;GACtB,MAAM,kBAAkB,KAAK,KAAK,IAAI;GACtC,YAAY,kBAAkB,WAAW,KAAK,IAAI;GACnD;EACD,MAAM,SAAS,MAAM,oBAAoB,kBACvC,KACA,QACA,aACD;AACD,MAAI,CAAC,OAAO,GAAI,QAAO,UAAU,OAAO,SAAS,oBAAoB;AACrE,eAAa,KAAK,OAAO;AACzB,QAAM,uBAAuB,aAAa;AAC1C,oBAAkB,eAAe;;CAGnC,MAAM,yBAAyB,YAAY;AACzC,MAAI,CAAC,sBAAsB;AACzB,qBAAkB,eAAe;AACjC;;AAGF,oBAAkB,QAAQ,IAAI,KAAK;AACnC,MAAI;GACF,MAAM,SAAS,MAAM,qBAAqB;IACxC,IAAI;IACJ,OAAO,kBAAkB,MAAM,KAAK;IACpC,aAAa,kBAAkB,YAAY,KAAK;IAChD,UAAU,kBAAkB,SAAS,KAAK,IAAI;IAC9C,MAAM,kBAAkB,KAAK,KAAK,IAAI;IACtC,YAAY,kBAAkB,WAAW,KAAK,IAAI;IACnD,CAAC;AACF,OAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,+BAA+B;AAE5D,OAAI,OAAO,MAAO,mBAAkB,MAAM,IAAI,OAAO,MAAM;AAC3D,OAAI,OAAO,YACT,mBAAkB,YAAY,IAAI,OAAO,YAAY;AACvD,OAAI,OAAO,SAAU,mBAAkB,SAAS,IAAI,OAAO,SAAS;AACpE,qBAAkB,KAAK,IAAI,OAAO,QAAQ,GAAG;AAC7C,qBAAkB,WAAW,IAAI,OAAO,cAAc,GAAG;AAEzD,qBAAkB,eAAe;YACzB;AACR,qBAAkB,QAAQ,IAAI,MAAM;;;CAIxC,MAAM,wBAAwB,OAC5B,OACA,UACA,cACG;AACH,MAAI,CAAC,YAAa,QAAO,UAAU,6BAA6B;AAChE,MAAI,CAAC,MAAO,QAAO,UAAU,qBAAqB;AAClD,MAAI,CAAC,WAAY,QAAO,UAAU,qCAAqC;AAEvE,oBAAkB,IAAI,KAAK;AAC3B,MAAI;AACF,OAAI;IACF,MAAM,cAAc,IAAI,aAAa;AAErC,IADyB,IAAI,iBAAiB,aAAa,YAAY,CACtD,YAAY;KAC3B,KAAK;KACL,KAAK,iBAAiB;KACtB,OAAOC;KACR,CAAC;IAEF,MAAM,SAAS,MAAM,WAAW,QAAQ;KACtC;KACA,aAAa;KACd,CAAC;AAEF,UAAM,UAAU,mBAAmB,EAAE,QAAQ,CAAC;AAG9C,UAAM,YAAY,kBAAkB,EAClC,YAAW,UAAS;KAClB,MAAM,MAAM,MAAM,SAAS;AAC3B,YAAO,QAAQ,mBAAmB,QAAQ;OAE7C,CAAC;IAGF,MAAM,iBAAiB,kBAAkB,SAAS,KAAK;IACvD,MAAM,cAAc;KAAE,OAAO;KAAW;KAAO;AAE/C,QAAI,CAAC,eAAe,MAAK,MAAK,EAAE,UAAU,MAAM,CAC9C,mBAAkB,SAAS,IAAI,CAAC,GAAG,gBAAgB,YAAY,CAAC;AAGlE,UAAM,qBAAqB,OAAOA,UAAQ,UAAU;YAC7C,GAAG;AACV,YAAQ,MAAM,uCAAuC,EAAE;AACvD,cAAU,kCAAkC;;YAEtC;AACR,qBAAkB,IAAI,MAAM;;;CAIhC,SAAS,yBAAyB;AAChC,qBAAmB,IAAI,KAAK;;CAE9B,SAAS,6BAA6B;AACpC,sBAAoB,oBAAoB,IAAI,KAAK;;CAGnD,MAAM,oBAAoB,OAAO,iBAAyB;AACxD,MACE,CAAC,gBACD,CAAC,kBACD,CAAC,gBAAgB,aACjB,eAAe,UAAU,WAAW,GACpC;AACA,aAAU,6CAA6C;AACvD;;AAGF,MAAI,CAAC,gBAAgB,gBAAgB,KAAK,eAAe,KAAK;AAC5D,aAAU,iDAAiD;AAC3D;;AAGF,MAAI,CAAC,YAAY;AACf,aAAU,qCAAqC;AAC/C;;AAGF,iBAAe,KAAK;AACpB,MAAI;GACF,MAAM,WAAW,MAAM,aAAa,aAAa;GAGjD,MAAM,cACJ,YAAY,UAAU,SACnB;GACL,MAAM,kBACJ,YAAY,UAAU,SACnB;GACL,MAAM,iBACJ,UAAU,YAAY,YAClB,8BAA8B,iBAC9B,8BAA8B;GAGpC,MAAM,sCAAsB,IAAI,KAAqB;GACrD,IAAIC,SAAoC;GACxC,IAAI,cAAc;AAElB,UAAO,aAAa;IAClB,MAAM,eAAe,MAAM,UAAU,gBAAgB;KACnD,OAAO,eAAe;KACtB,QAAQ,EAAE,YAAY,UAAU;KAChC,SAAS,EAAE,aAAa,MAAM;KAC9B;KACD,CAAC;AAGF,YAAQ,IAAI,4BAA4B,eAAe,UAAU;AAEjE,SAAK,MAAM,YAAY,eAAe,WAAW;KAC/C,MAAM,SAAS,SAAS;AAExB,UAAK,MAAM,OAAO,aAAa,KAC7B,KAAI,IAAI,MAAM,WAAW,YAAY,IAAI,KAAK,SAAS;MACrD,MAAM,SAAS,IAAI,KAAK,QAAQ;AAChC,UAAI,aAAa,QAEf;WADkB,OAAO,OAAO,QAAQ,KACtB,UAAU,CAAC,oBAAoB,IAAI,OAAO,EAAE;AAC5D,4BAAoB,IAAI,QAAQ,IAAI,KAAK,SAAS;AAClD;;;;;AAOV,kBAAc,aAAa;AAC3B,aAAS,aAAa;;AAGxB,OAAI,oBAAoB,SAAS,EAC/B,OAAM,IAAI,MACR,2EACD;GAGH,MAAM,KAAK,IAAI,aAAa;AAC5B,MAAG,UAAU,eAAe,QAAQ;GAEpC,MAAM,UAAU,MAAM,UAAU,SAAS;IACvC,OAAO,eAAe;IACtB,UAAU;IACX,CAAC;AAEF,OAAI,QAAQ,KAAK,WAAW,EAC1B,OAAM,IAAI,MACR,iEACD;AAIH,OAAI,QAAQ,KAAK,SAAS,EACxB,IAAG,WACD,GAAG,OAAO,QAAQ,KAAK,GAAG,aAAa,EACvC,QAAQ,KAAK,MAAM,EAAE,CAAC,KAAI,SAAQ,GAAG,OAAO,KAAK,aAAa,CAAC,CAChE;AAIH,QAAK,MAAM,CAAC,SAAS,aAAa,oBAAoB,SAAS,CAC7D,IAAG,SAAS;IACV,SAAS;IACT,QAAQ;IACR,UAAU;IACV,WAAW;KACT,GAAG,OAAO,eAAe;KACzB,GAAG,OAAO,SAAS;KACnB,GAAG,KAAK,IAAI,aAAa;KACzB,GAAG,OAAO,QAAQ,KAAK,GAAG,aAAa;KACxC;IACF,CAAC;GAGJ,MAAM,SAAS,MAAM,WAAW,QAAQ;IACtC,aAAa;IACb,aAAa,aAAa,oBAAoB,KAAK,cAAc,aAAa;IAC/E,CAAC;AAGF,SAAM,UAAU,mBAAmB,EAAE,QAAQ,CAAC;AAG9C,SAAM,YAAY,kBAAkB,EAClC,YAAW,UAAS;IAClB,MAAM,MAAM,MAAM;AAClB,WACG,MAAM,QAAQ,IAAI,KAChB,IAAI,OAAO,iBAAiB,IAAI,OAAO,mBAC1C;MAGL,CAAC;AAEF,qBACE,yBAAyB,oBAAoB,KAAK,cAAc,aAAa,YAC7E,OACD;WACM,OAAO;AACd,WAAQ,MAAM,0BAA0B,MAAM;AAC9C,aACE,2BAA2B,iBAAiB,QAAQ,MAAM,UAAU,kBACrE;YACO;AACR,kBAAe,MAAM;;;AAIzB,QAAO;EACL,OAAO;GACL;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA,SAAS;GACT;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD;EACD,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA,iCAAiC,kBAAkB;GACpD;EACF;;;;;ACtdH,SAAgB,iBAAiB,cAAmC;CAClE,MAAM,CAAC,iBAAiB,sBAAsB,SAAwB,KAAK;AAG3E,iBAAgB;EACd,MAAM,qBAAqB,YAAY;AACrC,OAAI,CAAC,aAAc;AAEnB,OAAI;IACF,MAAM,eAAe,MAAM,aAAa,cAAc;AAEtD,uBADiB,OAAO,aAAa,eAAe,CACxB;YACrB,OAAO;AACd,YAAQ,MAAM,kCAAkC,MAAM;AAEtD,uBAAmB,OAAU,KAAK,IAAK;;;AAI3C,sBAAoB;IACnB,CAAC,aAAa,CAAC;CAGlB,MAAM,oBAAoB,cAAc;AACtC,UAAQ,WAAmB;AACzB,OAAI,CAAC,mBAAmB,CAAC,UAAU,UAAU,EAAG,QAAO;GACvD,MAAM,MAAM,KAAK,KAAK;AACtB,UAAO,IAAI,KAAK,MAAM,SAAS,gBAAgB;;IAEhD,CAAC,gBAAgB,CAAC;CAErB,MAAM,cAAc,SAAe;AACjC,SAAO,IAAI,KAAK,eAAe,SAAS;GACtC,MAAM;GACN,OAAO;GACP,KAAK;GACL,MAAM;GACN,QAAQ;GACT,CAAC,CAAC,OAAO,KAAK;;AAGjB,QAAO;EACL;EACA;EACA;EACD;;;;;ACtBH,SAAgB,qBAAqB,EACnC,gBACA,SAAS,EAAE,WAAW,aAAa,eACnC,2BACA,iBAC6B;CAC7B,MAAM,aAAa,uBAAuB;EACxC;EACA,eAAe,gBAAgB;EAC/B;EACA;EACD,CAAC;CAEF,MAAM,CAAC,YAAY,iBAAiB,SAAS,GAAG;CAChD,MAAM,CAAC,aAAa,kBAAkB,SAAS,MAAM;CACrD,MAAM,CAAC,aAAa,kBAAkB,SAAyB,KAAK;CACpE,MAAM,CAAC,eAAe,oBAAoB,SAAS,MAAM;CACzD,MAAM,CAAC,YAAY,iBAAiB,SAAS,MAAM;CACnD,MAAM,CAAC,gBAAgB,qBAAqB,SAAwB,KAAK;CACzE,MAAM,CAAC,OAAO,YAAY,SAAwB,KAAK;CACvD,MAAM,CAAC,eAAe,oBAAoB,SAAS,EAAE;CACrD,MAAM,CAAC,cAAc,mBAAmB,SAAwB,KAAK;CACrE,MAAM,CAAC,uBAAuB,4BAA4B,SAExD,KAAK;CACP,MAAM,CAAC,kBAAkB,uBAAuB,SAAwB,KAAK;CAC7E,MAAM,CAAC,gBAAgB,qBAAqB,SAAwB,KAAK;CACzE,MAAM,0BAA0B,OAA8B,KAAK;CAEnE,MAAM,iBAAiB,WAAW,aAAa,CAAC,MAAM;CACtD,MAAM,WAAW,iBAAiB,GAAG,eAAe,QAAQ;CAC5D,MAAM,UAAU,UAAU;CAC1B,MAAM,YAAY,YAAY;CAC9B,MAAM,YAAY,YAAY;CAG9B,MAAM,iBAAiB,cAAc;AACnC,MAAI,CAAC,cAAe,QAAO;EAC3B,MAAM,uBAAO,IAAI,MAAM;AACvB,OAAK,YAAY,KAAK,aAAa,GAAG,cAAc;AACpD,SAAO;IACN,CAAC,cAAc,CAAC;CAGnB,MAAM,aAAa,cAAc;AAC/B,MAAI,CAAC,gBAAgB,CAAC,cAAe,QAAO;AAC5C,SAAO,eAAe;IACrB,CAAC,cAAc,cAAc,CAAC;CAGjC,MAAM,sBAAsB,cAAc;AACxC,MAAI,CAAC,cAAc,CAAC,sBAAuB,QAAO;EAClD,MAAM,eAAe,WACnB,sBAAsB,QAAQ,WAAW,GAAG,CAC7C;AACD,MAAI,OAAO,MAAM,aAAa,CAAE,QAAO;EACvC,MAAM,aAAa,eAAe;AAClC,SAAO,sBAAsB,QAAQ,UAAU,WAAW,QAAQ,EAAE,CAAC;IACpE;EAAC;EAAY;EAAuB;EAAc,CAAC;CAGtD,MAAM,gBACJ,YAAY,UAAsC;CAGpD,MAAM,mBAAmB,cAAc;AACrC,MAAI,CAAC,aAAa,CAAC,kBAAkB,CAAC,UAAW,QAAO;AAExD,SAAO,IAAI,iBAAiB;GAC1B,QAAQ,eAAe;GACvB,QAAQ;GACR,KAAK,IAAI;GACV,CAAC;IACD;EAAC;EAAW;EAAgB;EAAU,CAAC;CAG1C,MAAM,sBAAsB,YAAY,YAAY;AAClD,MACE,CAAC,eACD,CAAC,kBACD,CAAC,aACD,CAAC,iBACD,CAAC,oBACD,CAAC,eAED;EAIF,MAAM,YAAY,MAAM,YAAY,cAAc;EAClD,MAAM,aAAa,eAAe;EAGlC,IAAI,oBAAoB;AACxB,OAAK,MAAM,CAAC,CAAC,MAAM,KAAK,UAAU,UAAU,SAAS,CACnD,KAAI,cAAc,QAAQ,cAAc,IAAI;AAC1C,uBAAoB;AACpB;;AAIJ,MAAI,oBAAoB,GAAG;AACzB,mBAAgB,kBAAkB;GAGlC,MAAM,kBAAkB,oBAAoB;GAC5C,MAAM,iBAAiB,OAAO,KAAK,MAAM,kBAAkB,KAAK,CAAC;GAQjE,MAAM,eALY,MAAM,UAAU,SAAS;IACzC,OAAO,eAAe;IACtB,UAAU,YAAY,OAAO,MAAM,KAAK;IACzC,CAAC,EAGU,MAAM,QAAQ,KAAK,SAAS,MAAM,OAAO,KAAK,QAAQ,EAAE,GAAG,IACrE;GAGF,MAAM,cACJ,cAAc,iBACV,iBAAiB,cACjB;GAGN,MAAM,gBAAgB;GACtB,MAAM,aAAa,MAAM,iBAAiB,YAAY;IACpD,MAAM;IACN,QAAQ,YAAY,OAAO,MAAM,KAAK;IACtC,QAAQ,IAAI,GAAG,cAAc,UAAU,CAAC;IACxC,YAAY;IACZ,WAAW,CAAC,QAAQ;IACrB,CAAC;AAEF,OAAI,cAAc,CAAC,WAAW,SAAS,WAAW,WAAW;IAC3D,MAAM,eAAe,WAAW;IAChC,MAAM,mBAAmB,OACvB,wBAAwB,KACpB,aAAa,UAAU,GACvB,IAAI,GAAG,OAAO,aAAa,CAAC,CAAC,UAAU,CAC5C;AAED,QAAI,mBAAmB,IAAI;KACzB,MAAM,eAAe,OAAO,cAAc,GAAG,OAAO,iBAAiB;KACrE,MAAM,qBACJ,cAAc,OAAO,KAAK,KAAK,aAAa,CAAC;KAC/C,MAAM,sBACJ,OAAO,mBAAmB,GAAG,KAC7B,QAAQ,EAAE;AAMZ,8BAAyB,IAJvB,OAAO,mBAAmB,GAC1B,gBACA,KACA,QAAQ,EAAE,CACoC,MAAM;AACtD,uBAAkB,IAAI,mBAAmB,MAAM;WAC1C;KAEL,MAAM,aAAa,OAAO,eAAe,GAAG,KAAW,QAAQ,EAAE;AAEjE,8BAAyB,IADJ,oBAAoB,KAAW,QAAQ,EAAE,CACtB,OAAO;AAC/C,uBAAkB,IAAI,UAAU,OAAO;;UAEpC;IAEL,MAAM,aAAa,OAAO,eAAe,GAAG,KAAW,QAAQ,EAAE;AAEjE,6BAAyB,IADJ,oBAAoB,KAAW,QAAQ,EAAE,CACtB,OAAO;AAC/C,sBAAkB,IAAI,UAAU,OAAO;;;IAG1C;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CAIF,MAAM,6BAA6B,YAAY,YAAY;AACzD,MAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC,aAAa,CAAC,eACpD;EAIF,MAAM,YAAY,MAAM,YAAY,cAAc;EAClD,MAAM,aAAa,eAAe;EAGlC,IAAI,oBAAoB;AACxB,OAAK,MAAM,CAAC,CAAC,MAAM,KAAK,UAAU,UAAU,SAAS,CACnD,KAAI,cAAc,QAAQ,cAAc,IAAI;AAC1C,uBAAoB;AACpB;;AAIJ,MAAI,oBAAoB,GAAG;AACzB,mBAAgB,kBAAkB;GAGlC,MAAM,kBAAkB,oBAAoB;GAC5C,MAAM,mBAAmB,OAAO,KAAK,MAAM,gBAAgB,CAAC;GAM5D,MAAM,kBACH,mBAAmB,KAAK,eAAmB,KAAK;GACnD,MAAM,mBACH,OAAO,KAAK,MAAM,kBAAkB,CAAC,GAAG,KAAK,eAC7C,KAAK;GAGR,MAAM,sBACJ,OAAO,gBAAgB,GAAG,KAC1B,QAAQ,EAAE;GACZ,MAAM,uBACJ,OAAO,iBAAiB,GAAG,KAC3B,QAAQ,EAAE;GAGZ,MAAM,aAAa,OAAO,iBAAiB,GAAG,KAAW,QAAQ,EAAE;GACnE,MAAM,eAAe,oBAAoB,KAAW,QAAQ,EAAE;AAE9D,4BAAyB,GAAG,oBAAoB,MAAM;AACtD,qBAAkB,GAAG,mBAAmB,MAAM;AAC9C,uBAAoB,GAAG,YAAY,OAAO;AAC1C,qBAAkB,GAAG,UAAU,OAAO;;IAEvC;EAAC;EAAa;EAAgB;EAAW;EAAgB;EAAc,CAAC;AAG3E,iBAAgB;AACd,MACE,aACA,eACA,kBACA,CAAC,iBACD,kBACA;AAEA,OAAI,wBAAwB,QAC1B,eAAc,wBAAwB,QAAQ;AAIhD,2BAAwB,UAAU,kBAAkB;AAClD,yBAAqB,CAAC,OAAM,QAAO;AACjC,aAAQ,MAAM,2BAA2B,IAAI;MAC7C;MACD,IAAM;AAET,gBAAa;AACX,QAAI,wBAAwB,QAC1B,eAAc,wBAAwB,QAAQ;;;IAInD;EACD;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AAGF,iBAAgB;AACd,MAAI,eAAe,iBAAiB,MAClC;OAAI,aAAa,iBACf,sBAAqB,CAAC,OAAM,QAAO;AACjC,YAAQ,MAAM,yBAAyB,IAAI;KAC3C;YACO,UACT,6BAA4B,CAAC,OAAM,QAAO;AACxC,YAAQ,MAAM,yBAAyB,IAAI;KAC3C;;IAGL;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AAyaF,QAAO;EAEL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA,cA7bmB,YAAY,YAAY;AAC3C,OAAI,CAAC,kBAAkB,CAAC,YAAa;AAErC,OAAI,eAAe,SAAS,GAAG;AAC7B,aAAS,4CAA4C;AACrD,mBAAe,KAAK;AACpB,sBAAkB,KAAK;AACvB;;AAGF,kBAAe,KAAK;AACpB,YAAS,KAAK;AACd,kBAAe,KAAK;AACpB,qBAAkB,KAAK;AAEvB,OAAI;IAEF,MAAM,YAAY,EADC,MAAM,YAAY,cAAc,SAAS,GAC7B;AAC/B,mBAAe,UAAU;AAGzB,QAAI,aAAa,kBAAkB,iBACjC,KAAI;AACF,SAAI,aAAa,cACf,OAAM,qBAAqB;cAClB,UACT,OAAM,4BAA4B;aAE7B,YAAY;AACnB,aAAQ,MAAM,2BAA2B,WAAW;;YAIjDC,SAAO;AAEd,YAAQ,MAAM,wBAAwBA,QAAM;AAC5C,mBAAe,KAAK;aACZ;AACR,mBAAe,MAAM;;KAEtB;GACD;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;EA2YA,gBAzYqB,YAAY,YAAY;AAC7C,OAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC,eAAe,CAAC,eACtD;AAGF,OAAI,CAAC,YAAY;AACf,aAAS,qCAAqC;AAC9C;;AAGF,oBAAiB,KAAK;AACtB,YAAS,KAAK;AAEd,OAAI;IAEF,MAAM,YAAY,MAAM,YAAY,cAAc;IAClD,MAAM,aAAa,eAAe;IAGlC,IAAIC,iBAAe;AACnB,SAAK,MAAM,CAAC,CAAC,MAAM,KAAK,UAAU,UAAU,SAAS,CACnD,KAAI,cAAc,QAAQ,cAAc,IAAI;AAC1C,sBAAe;AACf;;AAIJ,QAAIA,mBAAiB,EACnB,OAAM,IAAI,MAAM,4CAA4C;IAI9D,MAAM,QAAQ;IACd,MAAMC,eAAaD,iBAAe;IAGlC,MAAM,WAAW,YAAY,QAAQ;IACrC,MAAM,aAAa,YAAY,OAAO,MAAM;IAG5C,MAAM,CAAC,WAAW,YAAY,MAAM,QAAQ,IAAI,CAC9C,YACI,UAAU,SAAS;KACjB,OAAO,eAAe;KACtB,UAAU,YAAY,OAAO,MAAM,KAAK;KACzC,CAAC,GACF,QAAQ,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,EACjC,aAAa,gBACT,UAAU,SAAS;KACjB,OAAO,eAAe;KACtB,UAAU;KACX,CAAC,GACF,QAAQ,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,CAClC,CAAC;IAEF,MAAM,cACJ,UAAU,MAAM,QAAQ,KAAK,SAAS,MAAM,OAAO,KAAK,QAAQ,EAAE,GAAG,IACrE;IACF,MAAM,aACJ,SAAS,MAAM,QAAQ,KAAK,SAAS,MAAM,OAAO,KAAK,QAAQ,EAAE,GAAG,IACpE;IAGF,MAAM,iBAAiB,OAAO,KAAK,MAAMC,eAAa,KAAK,CAAC;AAG5D,QAAI,aAAa,aAAa,QAC5B;SAAI,cAAc,gBAAgB;AAChC,UAAI,CAAC,oBAAoB,CAAC,cACxB,OAAM,IAAI,MACR,4DACD;AAGH,UAAI,eAAe,GACjB,OAAM,IAAI,MACR,kDAAkD,OAAO,eAAe,GAAG,KAAW,QAAQ,EAAE,CAAC,mBAAmB,OAAO,YAAY,GAAG,KAAW,QAAQ,EAAE,CAAC,kCACjK;MAGH,MAAM,cAAc,iBAAiB;MAGrC,MAAM,gBAAgB;MACtB,MAAM,aAAa,MAAM,iBAAiB,YAAY;OACpD,MAAM;OACN,QAAQ,YAAY,OAAO,MAAM,KAAK;OACtC,QAAQ,IAAI,GAAG,cAAc,UAAU,CAAC;OACxC,YAAY;OACZ,WAAW,CAAC,QAAQ;OACrB,CAAC;AAEF,UAAI,CAAC,cAAc,WAAW,SAAS,CAAC,WAAW,WAAW;OAC5D,MAAM,MACJ,YAAY,OAAO,OACnB;AACF,aAAM,IAAI,MAAM,IAAI;;MAGtB,MAAM,eAAe,WAAW;AAChC,UAAI,CAAC,aACH,OAAM,IAAI,MAAM,4CAA4C;MAE9D,MAAM,mBAAmB,OACvB,wBAAwB,KACpB,aAAa,UAAU,GACvB,IAAI,GAAG,OAAO,aAAa,CAAC,CAAC,UAAU,CAC5C;AAED,UAAI,qBAAqB,GACvB,OAAM,IAAI,MAAM,2CAA2C;MAG7D,MAAM,eAAe,OAAO,cAAc,GAAG,OAAO,iBAAiB;MACrE,MAAM,qBACJ,cAAc,OAAO,KAAK,KAAK,aAAa,CAAC;AAE/C,UAAI,aAAa,mBACf,OAAM,IAAI,MACR,iDAAiD,OAAO,mBAAmB,GAAG,KAAe,QAAQ,EAAE,CAAC,wBACzG;AAIH,oBAAc,KAAK;AACnB,UAAI;OACF,MAAM,cAAc,IAAI,GAAG,mBAAmB,UAAU,CAAC;OAEzD,MAAM,eAAe,MAAM,iBAAiB,YAAY;QACtD,MAAM;QACN,QAAQ,YAAY,OAAO,MAAM,KAAK;QACtC,QAAQ;QACR,YAAY;QACZ,WAAW,CAAC,QAAQ;QACrB,CAAC;AAEF,WAAI,CAAC,gBAAiB,aAAqC,OAAO;QAChE,MAAM,MACH,cAA+C,OAAO,OACvD;AACF,cAAM,IAAI,MAAM,IAAI;;AAGtB,WACG,aACE,sBAEH,OAAM,IAAI,MACR,2EACD;OAGH,MAAM,SAAS,IAAI,aAAa;AAChC,cAAO,kBAAkB,eAAe,QAAQ;AAEhD,aAAM,iBAAiB,eAAe;QACpC,QAAQ;QACR,KAAK;QACL,UAAU;QACX,CAAC;AAEF,cAAO,aAAa,IAAW;OAE/B,MAAM,aAAa,MAAM,WAAW,QAAQ;QAC1C,aAAa;QACb,aAAa;QACd,CAAC;AAGF,aAAM,UAAU,mBAAmB,EAAE,QAAQ,YAAY,CAAC;AAc1D,aAXuB,MAAM,UAAU,SAAS;QAC9C,OAAO,eAAe;QACtB,UAAU,YAAY,OAAO,MAAM,KAAK;QACzC,CAAC,EAGe,MAAM,QAClB,KAAK,SAAS,MAAM,OAAO,KAAK,QAAQ,EACzC,GACD,IAAI,MAEgB,eACrB,OAAM,IAAI,MACR,wEACD;gBAEK;AACR,qBAAc,MAAM;;;;IAM1B,MAAM,QAAQ,MAAM,UAAU,SAAS;KACrC,OAAO,eAAe;KACtB,UAAU,WAAW;KACtB,CAAC;AAEF,QAAI,MAAM,KAAK,WAAW,EACxB,OAAM,IAAI,MAAM,MAAM,SAAS,6BAA6B;IAI9D,MAAM,mBAAmB,KAAK,MAAMA,eAAa,KAAK;IACtD,MAAM,eAAe,MAAM,KAAK,QAC7B,KAAK,SAAS,MAAM,OAAO,KAAK,QAAQ,EACzC,GACD;IAGD,MAAM,kBAAkB,OAAO,iBAAiB,GAD7B;AAGnB,QAAI,eAAe,gBACjB,OAAM,IAAI,MACR,6CAA6C,OAAO,gBAAgB,GAAG,KAAe,QAAQ,EAAE,CAAC,GAAG,WACrG;IAIH,MAAM,cAAc,IAAI,aAAa;AACrC,gBAAY,kBAAkB,eAAe,QAAQ;IAErD,MAAM,mBAAmB,IAAI,iBAAiB,aAAa,YAAY;IAGvE,IAAIC;AAIJ,QAAI,aAAa,MAEf,eAAc,YAAY;SACrB;KAEL,MAAM,WAAW,MAAM,UAAU,SAAS;MACxC,OAAO,eAAe;MACtB,UAAU;MACX,CAAC;AAEF,SAAI,SAAS,KAAK,WAAW,EAC3B,OAAM,IAAI,MAAM,kCAAkC;KAIpD,MAAM,cAAc,MAAM,KAAK,GAAG;AAClC,SAAI,MAAM,KAAK,SAAS,EACtB,aAAY,WACV,YAAY,OAAO,YAAY,EAC/B,MAAM,KACH,MAAM,EAAE,CACR,KAAI,SAAQ,YAAY,OAAO,KAAK,aAAa,CAAC,CACtD;AAGH,mBAAc,YAAY,OAAO,YAAY;AAG7C,SAAI,SAAS,KAAK,SAAS,EACzB,aAAY,WACV,YAAY,OAAO,SAAS,KAAK,GAAG,aAAa,EACjD,SAAS,KACN,MAAM,EAAE,CACR,KAAI,SAAQ,YAAY,OAAO,KAAK,aAAa,CAAC,CACtD;;IAKL,MAAMC,iBAMF;KACF,QAAQ;KACR;KACA;KACA,MAAM;KACP;AAGD,QAAI,WAAW,KAIb,gBAAe,qBAFb,MAAM,YAAY,mBAAmB,aAAa,WAAW,KAAK,EAClE;IAKJ,MAAM,MAAM,iBAAiB,SAAS,eAAe;AAGrD,qBAAiB,iBAAiB;KAChC;KACA,SAAS,eAAe;KACzB,CAAC;AAGF,gBAAY,gBAAgB,CAAC,IAAI,EAAE,eAAe,QAAQ;AAG1D,gBAAY,aAAa,IAAW;AAGpC,QAAI,CAAC,WACH,OAAM,IAAI,MAAM,qCAAqC;IAGvD,MAAM,SAAS,MAAM,WAAW,QAAQ;KACtC;KACA,aAAa;KACd,CAAC;AAGF,UAAM,UAAU,mBAAmB,EAAE,QAAQ,CAAC;AAG9C,QAAI,gBAAgB,QAClB,aAAY,kBAAkB,EAC5B,UAAU;KAAC;KAAiB,eAAe;KAAS;KAAQ,EAC7D,CAAC;AAGJ,WAAO;YACA,KAAK;AACZ,YAAQ,MAAM,6BAA6B,IAAI;AAC/C,aAAS,eAAe,QAAQ,IAAI,UAAU,4BAA4B;AAC1E,WAAO;aACC;AACR,qBAAiB,MAAM;;KAExB;GACD;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;EA6CA,OA3CY,kBAAkB;AAC9B,iBAAc,GAAG;AACjB,kBAAe,KAAK;AACpB,qBAAkB,KAAK;AACvB,YAAS,KAAK;AACd,kBAAe,MAAM;AACrB,oBAAiB,MAAM;AACvB,iBAAc,MAAM;AACpB,oBAAiB,EAAE;AACnB,mBAAgB,KAAK;AACrB,4BAAyB,KAAK;AAC9B,uBAAoB,KAAK;AACzB,qBAAkB,KAAK;AACvB,OAAI,wBAAwB,SAAS;AACnC,kBAAc,wBAAwB,QAAQ;AAC9C,4BAAwB,UAAU;;KAEnC,EAAE,CAAC;EA2BL;;;;;ACpuBH,SAAgB,sBAAsB,EACpC,QACA,SAAS,EAAE,WAAW,aAAa,gBACnC,gBACA,2BACA,iBAC8B;CAC9B,MAAM,UAAU,UAAU;CAG1B,MAAM,MAAM,cAAc;AACxB,MAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,aAAc,QAAO;AAE3D,SAAO,IAAI,qBACT,cACA,WACA,eAAe,SACf,2BACA,cACD;IACA;EACD;EACA;EACA;EACA;EACA;EACD,CAAC;CAGF,MAAM,WAAW,YACf;EACE,YAAY,OAAO,EACjB,UACA,eAC8C;AAC9C,OAAI,CAAC,IACH,OAAM,IAAI,MAAM,sBAAsB;AAIxC,UADe,MAAM,IAAI,mBAAmB,QAAQ,UAAU,SAAS;;EAGzE,YAAW,WAAU;AAEnB,eAAY,kBAAkB,EAC5B,UAAU,UAAU,WAAW,OAAO,EACvC,CAAC;AAGF,OAAI,gBAAgB,QAClB,aAAY,kBAAkB,EAC5B,UAAU,UAAU,YAAY,eAAe,SAAS,QAAQ,EACjE,CAAC;AAGJ,WAAQ,IAAI,yCAAyC,OAAO;;EAE9D,UAAS,UAAS;AAChB,WAAQ,MAAM,qCAAqC,MAAM;;EAE5D,EACD,YACD;AAED,QAAO;EACL,oBAAoB,SAAS;EAC7B,YAAY,SAAS;EACrB,OAAO,SAAS;EAChB,WAAW,SAAS;EACpB,MAAM,SAAS;EAChB;;;;;ACjGH,SAAgB,kBACd,eAAe,cACf,WAAW,cACX,aACA;CACA,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAC5C,MAAM,CAAC,aAAa,kBAAkB,SAAkC,KAAK;AAG7E,iBAAgB;AACd,aAAW,KAAK;AAChB,UAAQ,IAAI,qCAAqC,aAAa;EAC9D,MAAM,KAAK,IAAI,iBAAiB,cAAc,SAAS;AACvD,iBAAe,GAAG;AAElB,KAAG,YAAY,CACZ,YAAY,GAEX,CACD,KAAK,YAAY;AAEhB,SAAM,YAAY,kBAAkB,EAClC,UAAU,CAAC,SAAS,aAAa,EAClC,CAAC;IACF,CACD,cAAc,WAAW,MAAM,CAAC;IAElC;EAAC;EAAc;EAAU;EAAY,CAAC;AAEzC,QAAO;EACL;EACA;EACD;;;;;AChCH,SAAgB,oBACd,UACA,QACA,SAIA;CACA,MAAM,EAAE,cAAc,gBAAgB;AACtC,QAAO,SACL;EACE,UAAU,UAAU,YAAY,UAAU,OAAO;EACjD,SAAS,YAAY;AACnB,OAAI,CAAC,aAAc,OAAM,IAAI,MAAM,8BAA8B;AACjE,OAAI,aAAa,KAAM,OAAM,IAAI,MAAM,oBAAoB;GAC3D,MAAM,cAAc,MAAM,aAAa,YAAY,UAAU,OAAO;AACpE,UAAO;IACL,aAAa,YAAY,YAAY,UAAU;IAC/C,WAAW,YAAY,UAAU,UAAU;IAC3C,WAAW,YAAY,UAAU,UAAU;IAC5C;;EAEH,SACE,CAAC,CAAC,gBAAgB,aAAa,QAAQ,WAAW,KAAK,SAAS;EAClE,WAAW,MAAS;EACrB,EACD,YACD;;;;;;CC7BH,SAAS,YAAY,GAAG,GAAG;AACzB,MAAI,YAAY,OAAO,KAAK,CAAC,EAAG,QAAO;EACvC,IAAI,IAAI,EAAE,OAAO;AACjB,MAAI,KAAK,MAAM,GAAG;GAChB,IAAI,IAAI,EAAE,KAAK,GAAG,KAAK,UAAU;AACjC,OAAI,YAAY,OAAO,EAAG,QAAO;AACjC,SAAM,IAAI,UAAU,+CAA+C;;AAErE,UAAQ,aAAa,IAAI,SAAS,QAAQ,EAAE;;CAG9C,SAAS,cAAc,GAAG;EACxB,IAAI,IAAI,YAAY,GAAG,SAAS;AAChC,SAAO,YAAY,OAAO,IAAI,IAAI,OAAO,EAAE;;CAG7C,SAAS,gBAAgB,KAAK,KAAK,OAAO;AACxC,QAAM,cAAc,IAAI;AACxB,MAAI,OAAO,IACT,QAAO,eAAe,KAAK,KAAK;GACvB;GACP,YAAY;GACZ,cAAc;GACd,UAAU;GACX,CAAC;MAEF,KAAI,OAAO;AAEb,SAAO;;CAGT,SAAS,QAAQ,GAAG,GAAG;EACrB,IAAI,IAAI,OAAO,KAAK,EAAE;AACtB,MAAI,OAAO,uBAAuB;GAChC,IAAI,IAAI,OAAO,sBAAsB,EAAE;AACvC,SAAM,IAAI,EAAE,OAAO,SAAU,KAAG;AAC9B,WAAO,OAAO,yBAAyB,GAAGC,IAAE,CAAC;KAC7C,GAAG,EAAE,KAAK,MAAM,GAAG,EAAE;;AAEzB,SAAO;;CAET,SAAS,eAAe,GAAG;AACzB,OAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;GACzC,IAAI,IAAI,QAAQ,UAAU,KAAK,UAAU,KAAK,EAAE;AAChD,OAAI,IAAI,QAAQ,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,SAAU,KAAG;AAClD,oBAAgB,GAAGA,KAAG,EAAEA,KAAG;KAC3B,GAAG,OAAO,4BAA4B,OAAO,iBAAiB,GAAG,OAAO,0BAA0B,EAAE,CAAC,GAAG,QAAQ,OAAO,EAAE,CAAC,CAAC,QAAQ,SAAU,KAAG;AAChJ,WAAO,eAAe,GAAGA,KAAG,OAAO,yBAAyB,GAAGA,IAAE,CAAC;KAClE;;AAEJ,SAAO;;CAGT,SAAS,UAAU,SAAO,IAAI;EAC5B,IAAI,SAAS,EAAE;AACf,OAAK,IAAI,QAAQC,QACf,QAAO,QAAQ,GAAGA,QAAM,OAAO,KAAK;AAEtC,SAAO;;CAGT,IAAI,uBAAuB,eAAe,YAAY,oBAAoB;AACxE,OAAK,IAAI,OAAO,OAAO,KAAK,cAAc,EAAE;GAC1C,IAAI;AACJ,OAAI,cAAc,WAAW,kBAAkB,WAAW,UAAU,QAAQ,oBAAoB,KAAK,IAAI,kBAAkB,gBAAgB,MACzI,QAAO;;AAGX,SAAO;;CAET,IAAI,mBAAkB,WAAU;EAC9B,IAAI,aAAY,YAAW;GACzB,IAAI,YAAY,OAAO;GACvB,IAAI,aAAa,eAAe,eAAe,EAAE,EAAE,OAAO,gBAAgB,EAAE,QAAQ;AACpF,QAAK,IAAI,eAAe,YAAY;IAClC,IAAI;IACJ,IAAI,oBAAoB,wBAAwB,WAAW,kBAAkB,QAAQ,0BAA0B,KAAK,IAAI,wBAAwB,OAAO,gBAAgB;AACvK,QAAI,oBAAoB,MAAM;KAC5B,IAAI,YAAY;AAChB,SAAI,OAAO,cAAc,UAEvB,aAAY,cAAc,OAAO,SAAS;KAE5C,IAAI,qBAEJ,OAAO,kBAAkB,aAAa;AACtC,SAAI,mBACF,cAAa,MAAM;;;AAIzB,QAAK,IAAI,CAAC,eAAe,sBAAsB,OAAO,iBACpD,KAAI,oBAAoB,eAAe,YAAY,OAAO,gBAAgB,CACxE,cAAa,MAAM;AAGvB,UAAO;;AAET,YAAU,iBAAiB,OAAO,KAAK,OAAO,kBAAkB;AAChE,YAAU,aAAa;GACrB,IAAI,OAAO;AACT,WAAO,OAAO,iBAAiB,MAAM,IAAI,CAAC;;GAE5C,IAAI,WAAW;AACb,WAAO,UAAU,OAAO,oBAAmB,eAAc,UAAU,aAAY,cAAa,UAAU,MAAM,IAAI,CAAC,GAAG,CAAC;;GAExH;AACD,SAAO;;AAGT,SAAQ,kBAAkB;AAC1B,SAAQ,YAAY;;;;;;AC/GpB,QAAO,eAAe,SAAS,cAAc,EAAE,OAAO,MAAM,CAAC;CAE7D,IAAI;AAIJ,SAAQ,kBAAkB,0DAA0D;;;;;;CCNpF,SAAS,YAAY,GAAG,GAAG;AACzB,MAAI,YAAY,OAAO,KAAK,CAAC,EAAG,QAAO;EACvC,IAAI,IAAI,EAAE,OAAO;AACjB,MAAI,KAAK,MAAM,GAAG;GAChB,IAAI,IAAI,EAAE,KAAK,GAAG,KAAK,UAAU;AACjC,OAAI,YAAY,OAAO,EAAG,QAAO;AACjC,SAAM,IAAI,UAAU,+CAA+C;;AAErE,UAAQ,aAAa,IAAI,SAAS,QAAQ,EAAE;;CAG9C,SAAS,cAAc,GAAG;EACxB,IAAI,IAAI,YAAY,GAAG,SAAS;AAChC,SAAO,YAAY,OAAO,IAAI,IAAI,OAAO,EAAE;;CAG7C,SAAS,gBAAgB,KAAK,KAAK,OAAO;AACxC,QAAM,cAAc,IAAI;AACxB,MAAI,OAAO,IACT,QAAO,eAAe,KAAK,KAAK;GACvB;GACP,YAAY;GACZ,cAAc;GACd,UAAU;GACX,CAAC;MAEF,KAAI,OAAO;AAEb,SAAO;;CAGT,SAAS,QAAQ,GAAG,GAAG;EACrB,IAAI,IAAI,OAAO,KAAK,EAAE;AACtB,MAAI,OAAO,uBAAuB;GAChC,IAAI,IAAI,OAAO,sBAAsB,EAAE;AACvC,SAAM,IAAI,EAAE,OAAO,SAAU,KAAG;AAC9B,WAAO,OAAO,yBAAyB,GAAGC,IAAE,CAAC;KAC7C,GAAG,EAAE,KAAK,MAAM,GAAG,EAAE;;AAEzB,SAAO;;CAET,SAAS,eAAe,GAAG;AACzB,OAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;GACzC,IAAI,IAAI,QAAQ,UAAU,KAAK,UAAU,KAAK,EAAE;AAChD,OAAI,IAAI,QAAQ,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,SAAU,KAAG;AAClD,oBAAgB,GAAGA,KAAG,EAAEA,KAAG;KAC3B,GAAG,OAAO,4BAA4B,OAAO,iBAAiB,GAAG,OAAO,0BAA0B,EAAE,CAAC,GAAG,QAAQ,OAAO,EAAE,CAAC,CAAC,QAAQ,SAAU,KAAG;AAChJ,WAAO,eAAe,GAAGA,KAAG,OAAO,yBAAyB,GAAGA,IAAE,CAAC;KAClE;;AAEJ,SAAO;;CAGT,SAAS,UAAU,SAAO,IAAI;EAC5B,IAAI,SAAS,EAAE;AACf,OAAK,IAAI,QAAQC,QACf,QAAO,QAAQ,GAAGA,QAAM,OAAO,KAAK;AAEtC,SAAO;;CAGT,IAAI,uBAAuB,eAAe,YAAY,oBAAoB;AACxE,OAAK,IAAI,OAAO,OAAO,KAAK,cAAc,EAAE;GAC1C,IAAI;AACJ,OAAI,cAAc,WAAW,kBAAkB,WAAW,UAAU,QAAQ,oBAAoB,KAAK,IAAI,kBAAkB,gBAAgB,MACzI,QAAO;;AAGX,SAAO;;CAET,IAAI,mBAAkB,WAAU;EAC9B,IAAI,aAAY,YAAW;GACzB,IAAI,YAAY,OAAO;GACvB,IAAI,aAAa,eAAe,eAAe,EAAE,EAAE,OAAO,gBAAgB,EAAE,QAAQ;AACpF,QAAK,IAAI,eAAe,YAAY;IAClC,IAAI;IACJ,IAAI,oBAAoB,wBAAwB,WAAW,kBAAkB,QAAQ,0BAA0B,KAAK,IAAI,wBAAwB,OAAO,gBAAgB;AACvK,QAAI,oBAAoB,MAAM;KAC5B,IAAI,YAAY;AAChB,SAAI,OAAO,cAAc,UAEvB,aAAY,cAAc,OAAO,SAAS;KAE5C,IAAI,qBAEJ,OAAO,kBAAkB,aAAa;AACtC,SAAI,mBACF,cAAa,MAAM;;;AAIzB,QAAK,IAAI,CAAC,eAAe,sBAAsB,OAAO,iBACpD,KAAI,oBAAoB,eAAe,YAAY,OAAO,gBAAgB,CACxE,cAAa,MAAM;AAGvB,UAAO;;AAET,YAAU,iBAAiB,OAAO,KAAK,OAAO,kBAAkB;AAChE,YAAU,aAAa;GACrB,IAAI,OAAO;AACT,WAAO,OAAO,iBAAiB,MAAM,IAAI,CAAC;;GAE5C,IAAI,WAAW;AACb,WAAO,UAAU,OAAO,oBAAmB,eAAc,UAAU,aAAY,cAAa,UAAU,MAAM,IAAI,CAAC,GAAG,CAAC;;GAExH;AACD,SAAO;;AAGT,SAAQ,kBAAkB;AAC1B,SAAQ,YAAY;;;;;;AC/GpB,QAAO,eAAe,SAAS,cAAc,EAAE,OAAO,MAAM,CAAC;CAE7D,IAAI;AAIJ,SAAQ,kBAAkB,0DAA0D;;;;;;ACNpF,KAAI,QAAQ,IAAI,aAAa,aAC3B,QAAO;KAEP,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AE+BT,MAAMC,eAAiD;CACrD,MAAM,oBAAC;EAAM,OAAO;GAAE,OAAO;GAAQ,QAAQ;GAAQ;EAAE,aAAa;GAAO;CAC3E,SACE,oBAAC;EAAY,OAAO;GAAE,OAAO;GAAQ,QAAQ;GAAQ;EAAE,aAAa;GAAO;CAE7E,SACE,oBAAC;EACC,OAAO;GAAE,OAAO;GAAQ,QAAQ;GAAQ;EACxC,aAAa;GACb;CAEJ,OACE,oBAAC;EAAY,OAAO;GAAE,OAAO;GAAQ,QAAQ;GAAQ;EAAE,aAAa;GAAO;CAE7E,OAAO,oBAAC;EAAQ,OAAO;GAAE,OAAO;GAAQ,QAAQ;GAAQ;EAAE,aAAa;GAAO;CAC/E;AAED,MAAaC,UAA2B,EACtC,OAAO,WACP,aAAa,iBACb,MAAM,YACN,WAAW,MACX,YAAY,IACZ,UAAU,QACV,SACA,KACA,cACI;AACJ,QACE,qBAAC;EAAI,WAAW,GAAG,OAAO,EAAE,SAAS,CAAC,CAAC,GAAG;;GAExC,qBAAC;IACC,WAAW;IACX,OAAM;IACN,QAAO;IACP,eAAY;eAEZ,oBAAC,oBACC,oBAAC;KACC,IAAI,gBAAgB;KACpB,GAAE;KACF,GAAE;KACF,OAAM;KACN,QAAO;KACP,cAAa;eAEb,oBAAC;MACC,GAAE;MACF,MAAK;MACL,QAAO;MACP,aAAY;gBAEZ,oBAAC,qBAAM,iBAAoB;OACtB;MACC,GACL,EACP,oBAAC;KACC,MAAM,qBAAqB,QAAQ;KACnC,OAAM;KACN,QAAO;MACP;KACE;GAGN,qBAAC;IAAI,WAAWC;eACb,YACC,oBAAC;KAAI,WAAW,cAAc,EAAE,SAAS,CAAC;eACxC,oBAAC;MAAI,WAAW,KAAK,EAAE,SAAS,CAAC;gBAC9B,cAAc,aAAa;OACxB;MACF,EAER,qBAAC;KAAI,WAAW;gBACd,oBAAC;MAAG,WAAWC,QAAM,EAAE,SAAS,CAAC;gBAAG;OAAe,EAClD,mBACC,qBAAC;MAAE,WAAWC,cAAY,EAAE,SAAS,CAAC;iBACnC,iBACA,OAAO,WACN,4CACG,KACD,oBAAC;OACC,MAAM;OACN,QAAO;OACP,KAAI;OACJ,WAAWC,OAAK,EAAE,SAAS,CAAC;iBAE3B;QACC,IACH;OAEH;MAEF;KACF;GAGL,WACC,oBAAC;IACC,MAAK;IACL,SAAS;IACT,WAAWC,cAAY,EAAE,SAAS,CAAC;IACnC,cAAW;cAEX,oBAAC;KACC,WAAW;KACX,MAAK;KACL,QAAO;KACP,SAAQ;KACR,eAAY;eAEZ,oBAAC;MACC,eAAc;MACd,gBAAe;MACf,aAAa;MACb,GAAE;gBAEF,oBAAC,qBAAM,eAAkB;OACpB;MACH;KACC;;GAEP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AEpJV,MAAaC,UAA2B,EACtC,UAAU,WACV,OAAO,WACP,YAAY,IACZ,UACA,GAAG,YACC;AACJ,QACE,oBAAC;EAAO,WAAW,GAAG,OAAO;GAAE;GAAS;GAAM,CAAC,CAAC,GAAG;EAAa,GAAI;EACjE;GACM;;;;;;;;;;AELb,MAAaC,kBAA2C,EACtD,aAAa,GACb,UAAU,GACV,gBAAgB,IAChB,QAAQ,gBACR,OACA,QACA,YAAY,IACZ,aAAa,IACb,GAAG,YACC;CACJ,MAAM,YAAY,OAA0B,KAAK;CACjD,MAAM,eAAe,OAAuB,KAAK;CACjD,MAAM,CAAC,UAAU,eAAe,SAAS,MAAM;CAC/C,MAAM,CAAC,YAAY,iBAAiB,SAAS;EAAE,OAAO;EAAG,QAAQ;EAAG,CAAC;CAErE,MAAM,gBAAgB,cAAc;EAClC,MAAM,UAAU,YAAkB;AAChC,OAAI,OAAO,WAAW,YACpB,QAAO;GAET,MAAM,WAAW,SAAS,cAAc,SAAS;AACjD,YAAS,QAAQ,SAAS,SAAS;GACnC,MAAM,MAAM,SAAS,WAAW,KAAK;AACrC,OAAI,CAAC,IAAK,QAAO;AACjB,OAAI,YAAYC;AAChB,OAAI,SAAS,GAAG,GAAG,GAAG,EAAE;GACxB,MAAM,CAAC,GAAG,GAAG,KAAK,MAAM,KAAK,IAAI,aAAa,GAAG,GAAG,GAAG,EAAE,CAAC,KAAK;AAC/D,UAAO,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE;;AAE/B,SAAO,OAAO,MAAM;IACnB,CAAC,MAAM,CAAC;CAEX,MAAM,cAAc,aACjB,UAA6B,SAAe,aAAmB;EAC9D,MAAM,MAAM,OAAO,oBAAoB;AACvC,WAAS,QAAQC,UAAQ;AACzB,WAAS,SAASC,WAAS;AAC3B,WAAS,MAAM,QAAQ,GAAGD,QAAM;AAChC,WAAS,MAAM,SAAS,GAAGC,SAAO;EAClC,MAAM,OAAO,KAAK,MAAMD,WAAS,aAAa,SAAS;EACvD,MAAM,OAAO,KAAK,MAAMC,YAAU,aAAa,SAAS;EAExD,MAAM,UAAU,IAAI,aAAa,OAAO,KAAK;AAC7C,OAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAClC,SAAQ,KAAK,KAAK,QAAQ,GAAG;AAG/B,SAAO;GAAE;GAAM;GAAM;GAAS;GAAK;IAErC;EAAC;EAAY;EAAS;EAAW,CAClC;CAED,MAAM,gBAAgB,aACnB,SAAuB,cAAsB;AAC5C,OAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAClC,KAAI,KAAK,QAAQ,GAAG,gBAAgB,UAClC,SAAQ,KAAK,KAAK,QAAQ,GAAG;IAInC,CAAC,eAAe,WAAW,CAC5B;CAED,MAAM,WAAW,aAEb,KACA,SACA,UACA,MACA,MACA,SACA,QACG;AACH,MAAI,UAAU,GAAG,GAAGD,SAAOC,SAAO;AAClC,MAAI,YAAY;AAChB,MAAI,SAAS,GAAG,GAAGD,SAAOC,SAAO;AAEjC,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,IACxB,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,KAAK;AAE7B,OAAI,YAAY,GAAG,gBADH,QAAQ,IAAI,OAAO,GACQ;AAC3C,OAAI,SACF,KAAK,aAAa,WAAW,KAC7B,KAAK,aAAa,WAAW,KAC7B,aAAa,KACb,aAAa,IACd;;IAIP;EAAC;EAAe;EAAY;EAAQ,CACrC;AAED,iBAAgB;EACd,MAAM,WAAW,UAAU;EAC3B,MAAMC,cAAY,aAAa;AAC/B,MAAI,CAAC,YAAY,CAACA,YAAW;EAE7B,MAAM,MAAM,SAAS,WAAW,KAAK;AACrC,MAAI,CAAC,IAAK;EAEV,IAAIC;EACJ,IAAIC;EAEJ,MAAM,yBAAyB;GAC7B,MAAM,WAAW,SAASF,YAAU;GACpC,MAAM,YAAY,UAAUA,YAAU;AACtC,iBAAc;IAAE,OAAO;IAAU,QAAQ;IAAW,CAAC;AACrD,gBAAa,YAAY,UAAU,UAAU,UAAU;;AAGzD,oBAAkB;EAElB,IAAI,WAAW;EACf,MAAM,WAAW,SAAiB;AAChC,OAAI,CAAC,SAAU;GAEf,MAAM,aAAa,OAAO,YAAY;AACtC,cAAW;AAEX,iBAAc,WAAW,SAAS,UAAU;AAC5C,YACE,KACA,SAAS,OACT,SAAS,QACT,WAAW,MACX,WAAW,MACX,WAAW,SACX,WAAW,IACZ;AACD,sBAAmB,sBAAsB,QAAQ;;EAGnD,MAAM,iBAAiB,IAAI,qBAAqB;AAC9C,qBAAkB;IAClB;AAEF,iBAAe,QAAQA,YAAU;EAEjC,MAAM,uBAAuB,IAAI,sBAC9B,CAAC,WAAW;AACX,eAAY,MAAM,eAAe;KAEnC,EAAE,WAAW,GAAG,CACjB;AAED,uBAAqB,QAAQ,SAAS;AAEtC,MAAI,SACF,oBAAmB,sBAAsB,QAAQ;AAGnD,eAAa;AACX,wBAAqB,iBAAiB;AACtC,kBAAe,YAAY;AAC3B,wBAAqB,YAAY;;IAElC;EAAC;EAAa;EAAe;EAAU;EAAO;EAAQ;EAAS,CAAC;AAEnE,QACE,oBAAC;EAAI,KAAK;EAAc,WAAW,GAAG,UAAU,GAAG;EAAa,GAAI;YAClE,oBAAC;GACC,KAAK;GACL,WAAW;GACX,OAAO;IACL,OAAO,WAAW;IAClB,QAAQ,WAAW;IACpB;IACD;GACE;;;;;;;;;;;AE1KV,MAAa,QAAQ,YAClB,EAAE,YAAY,IAAI,GAAG,SAAS,QAAQ;AACrC,QAAO,oBAAC;EAAW;EAAK,WAAW,GAAG,MAAM,GAAG;EAAa,GAAI;GAAS;EAE5E;AAED,MAAM,cAAc;AAMpB,MAAaG,SAAyB,EACpC,YAAY,IACZ,UACA,GAAG,YACC;AACJ,QAEE,oBAAC;EAAM,WAAW,GAAGC,MAAW,GAAG;EAAa,GAAI;EACjD;GACK;;AAOZ,MAAaC,YAA+B,EAAE,YAAY,IAAI,GAAG,YAAY;AAC3E,QAAO,oBAAC;EAAS,WAAW,GAAGC,SAAc,GAAG;EAAa,GAAI;GAAS;;;;;;;;;;;;;;;;;;;;;;;AE/B5E,MAAMC,QAAuB,EAC3B,gBACA,WACA,aACA,UACA,aACI;AACJ,QACE,qBAAC;EAAI,WAAWC;;GAEd,oBAAC;IACC,WAAW,GAAGC,cAAqB,GACjC,cACIC,yBACA,WACEC,sBACAC;cAGP,cACC,qBAAC;KACC,OAAM;KACN,QAAO;KACP,MAAK;KACL,QAAO;KACP,SAAQ;gBAER,oBAAC,qBAAM,UAAa,EACpB,oBAAC;MACC,eAAc;MACd,gBAAe;MACf,aAAa;MACb,GAAE;OACF;MACE,GACJ,YACF,oBAAC,SAAI,WAAWC,cAAsB,GAEtC,oBAAC,SAAI,WAAWC,UAAkB;KAEhC;GAGL,CAAC,UACA,oBAAC,SACC,WAAW,GAAGC,SAAgB,GAC5B,cAAcC,oBAA2BC,oBAE3C;GAIJ,oBAAC;IACC,WAAW,GAAGC,UAAiB,GAC7B,YAAY,cACRC,kBACAC;cAGLC;KACI;;GACH;;AAUV,MAAaC,WAA6B,EACxC,OACA,aACA,gBACI;AACJ,QACE,oBAAC;EAAI,WAAWC;YACd,oBAAC;GAAI,WAAWC;aACb,MAAM,KAAK,MAAM,UAChB,oBAAC;IAEC,OAAO,KAAK;IACZ,aAAa,KAAK;IAClB,aAAa,QAAQ;IACrB,WAAW,aAAa,UAAU;IAClC,UAAU,UAAU;IACpB,QAAQ,UAAU,MAAM,SAAS;MAN5B,KAAK,MAOV,CACF;IACE;GACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AE9DV,MAAMC,oBAA+C,EACnD,QACA,gBACA,SAAS,EAAE,WAAW,aAAa,gBACnC,2BACA,eACA,gBACI;CACJ,MAAM,SAAS,SAAS,uBAAuB;CAC/C,MAAM,CAAC,cAAc,mBAAmB,SAAiB,GAAG;CAC5D,MAAM,CAAC,QAAQ,aAAa,SAAiB,EAAE;CAC/C,MAAM,CAAC,aAAa,kBAAkB,SAAS,MAAM;CACrD,MAAM,CAAC,WAAW,gBAAgB,SAAwB,KAAK;CAC/D,MAAM,CAAC,wBAAwB,6BAA6B,SAE1D,KAAK;CACP,MAAM,CAAC,iBAAiB,sBAAsB,yBAC5C,IAAI,KAAK,CACV;CACD,MAAM,CAAC,eAAe,oBAAoB,SAAwB,KAAK;CAEvE,MAAM,EAAE,iBAAiB,eAAe,iBAAiB,aAAa;CACtE,MAAM,aAAa,uBAAuB;EACxC;EACA,eAAe,gBAAgB;EAC/B;EACA;EACD,CAAC;CAEF,MAAM,EAAE,MAAM,aAAa,mBAAmB,QAAQ;EACpD;EACA;EACD,CAAC;CAGF,MAAM,uBAAuB,YAAY,YAAY;AACnD,MAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,UAAU,UAC5D;AAGF,MAAI;GACF,MAAM,WAAW,MAAM,aAAa,aAAa;GACjD,MAAM,2BAAW,IAAI,KAAmB;GACxC,IAAI,YAAY;GAGhB,MAAM,eAAe,MAAM,aAAa,cAAc;GACtD,MAAM,eAAe,OAAO,aAAa,MAAM;GAC/C,MAAM,gBAAgB,OAAO,aAAa,eAAe;GAEzD,IAAIC,SAAoC;GACxC,IAAI,cAAc;AAElB,UAAO,aAAa;IAClB,MAAM,eAAe,MAAM,UAAU,gBAAgB;KACnD,OAAO,eAAe;KACtB,QAAQ,EAAE,YAAY,UAAU;KAChC,SAAS,EAAE,aAAa,MAAM;KAC9B;KACD,CAAC;AAEF,SAAK,MAAM,YAAY,SAAS,WAAW;KACzC,MAAM,SAAS,SAAS;AACxB,SAAI,SAAS,IAAI,OAAO,CAAE;AAE1B,UAAK,MAAM,OAAO,aAAa,KAC7B,KAAI,IAAI,MAAM,WAAW,YAAY,IAAI,KAAK,SAAS;MACrD,MAAM,SAAS,IAAI,KAAK,QAAQ;AAChC,UAAI,aAAa,QAEf;WADkB,OAAO,OAAO,QAAQ,KACtB,QAAQ;QACxB,MAAM,UAAU,OAAO;AAMvB,YAAI,SAAS,QAAQ,cAAc,QAAW;SAE5C,MAAM,kBADW,OAAO,QAAQ,OAAO,UAAU,GACd;SACnC,MAAM,iBACJ,KAAK,KAAK,GAAG,kBAAkB;AACjC,kBAAS,IAAI,QAAQ,IAAI,KAAK,eAAe,CAAC;SAG9C,MAAM,YAAY,OAAO;AACzB,aAAI,cAAc,QAAW;UAE3B,MAAM,OACJ,OAAO,cAAc,WACjB,OAAO,UAAU,GACjB,OAAO,UAAU;AACvB,cAAI,CAAC,OAAO,MAAM,KAAK,IAAI,OAAO,EAChC,cAAa;;AAGjB;;;;;;AAQZ,kBAAc,aAAa;AAC3B,aAAS,aAAa;;AAGxB,sBAAmB,SAAS;AAC5B,oBAAiB,YAAY,IAAI,YAAY,KAAK;WAC3C,OAAO;AACd,WAAQ,MAAM,oCAAoC,MAAM;;IAEzD;EAAC;EAAQ;EAAc;EAAgB;EAAW;EAAS,CAAC;CAG/D,MAAM,EACJ,MAAM,iBACN,WAAW,sBACX,OAAO,qBACL,oBAAoB,eAAe,QAAQ;EAC7C;EACA;EACD,CAAC;CAGF,MAAM,oBAAoB,cAAc;AACtC,MAAI,kBAAkB,KAAM,QAAO;AACnC,MAAI,CAAC,UAAU,UAAW,QAAO;AAEjC,SAAO,SAAS,UAAU,SAAS,KAAK;IACvC,CAAC,eAAe,UAAU,UAAU,CAAC;CAGxC,MAAM,EAAE,MAAM,mBAAmB,WAAW,2BAC1C,oBAAoB,mBAAmB,QAAQ;EAC7C;EACA;EACD,CAAC;CAGJ,MAAM,iBAAiB,aAAa,UAAiC;AACnE,MAAI,UAAU,QAAQ,UAAU,EAAG,QAAO;EAC1C,MAAM,QAAQ;GAAC;GAAK;GAAM;GAAM;GAAK;EACrC,IAAI,OAAO;EACX,IAAI,YAAY;AAChB,SAAO,QAAQ,QAAQ,YAAY,MAAM,SAAS,GAAG;AACnD,WAAQ;AACR;;AAEF,SAAO,GAAG,KAAK,QAAQ,EAAE,CAAC,GAAG,MAAM;IAClC,EAAE,CAAC;CAGN,MAAM,kBAAkB,aAAa,WAAuC;AAC1E,MAAI,CAAC,OAAQ,QAAO;EACpB,MAAM,MAAM,OAAO,OAAO;AAG1B,UADkB,OAAO,IAAI,GAAG,KACf,QAAQ,EAAE;IAC1B,EAAE,CAAC;AAGN,iBAAgB;AACd,MAAI,UAAU,OACZ,uBAAsB;IAEvB;EAAC;EAAQ;EAAQ;EAAqB,CAAC;CAG1C,MAAM,yBAAyB,cAAc;AAC3C,MAAI,CAAC,UAAU,aAAa,SAAS,UAAU,WAAW,EACxD,QAAO;EAGT,MAAM,aAAa,SAAS,UACzB,KAAI,aAAY,gBAAgB,IAAI,SAAS,QAAQ,EAAE,SAAS,CAAC,CACjE,QAAQ,cAAmC,OAAO,cAAc,SAAS;AAE5E,MAAI,WAAW,WAAW,EACxB,QAAO;AAGT,SAAO,IAAI,KAAK,KAAK,IAAI,GAAG,WAAW,CAAC;IACvC,CAAC,UAAU,WAAW,gBAAgB,CAAC;AAG1C,iBAAgB;AACd,MAAI,CAAC,0BAA0B,CAAC,iBAAiB;AAC/C,6BAA0B,KAAK;AAC/B;;EAGF,MAAM,MAAM,KAAK,KAAK;AACtB,MAAI,uBAAuB,SAAS,IAAI,KAAK;AAC3C,6BAA0B,EAAE;AAC5B;;AAMF,4BAHkB,KAAK,MACpB,uBAAuB,SAAS,GAAG,OAAO,gBAC5C,CACmC;IACnC,CAAC,wBAAwB,gBAAgB,CAAC;CAG7C,MAAM,UAAU,cAAc;AAC5B,MAAI,CAAC,mBAAmB,CAAC,uBAAwB,QAAO;EACxD,MAAM,MAAM,KAAK,KAAK;EACtB,MAAM,oBAAoB,uBAAuB,SAAS;EAI1D,MAAM,aAAa,MADD,IACmB;EACrC,MAAM,eAAe,KAAK,IAAI,mBAAmB,WAAW;AAE5D,SAAO,IAAI,KAAK,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,GAAG;IACvD,CAAC,iBAAiB,uBAAuB,CAAC;CAE7C,MAAM,UAAU,cAAc;AAC5B,MAAI,CAAC,mBAAmB,CAAC,uBAAwB,QAAO;EAGxD,MAAM,eAFoB,uBAAuB,SAAS,GACxC,MACmC;AACrD,SAAO,IAAI,KAAK,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,GAAG;IACvD,CAAC,iBAAiB,uBAAuB,CAAC;CAG7C,MAAM,2BAA2B,eAAuB;AACtD,MAAI,CAAC,mBAAmB,CAAC,cAAc,CAAC,uBAAwB,QAAO;EAIvE,MAAM,SAFa,IAAI,KAAK,WAAW,CAAC,SAAS,GACvB,uBAAuB,SAAS;AAG1D,MAAI,UAAU,EAAG,QAAO;EAGxB,MAAM,cAAc,SAAS;EAC7B,MAAM,gBAAgB,KAAK,KAAK,YAAY;AAG5C,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,cAAc,CAAC;;CAIlD,MAAM,oBAAoB,MAA2C;EACnE,MAAM,UAAU,EAAE,OAAO;AACzB,kBAAgB,QAAQ;AACxB,eAAa,KAAK;AAElB,MAAI,CAAC,SAAS;AACZ,aAAU,EAAE;AACZ;;AAIF,YADyB,wBAAwB,QAAQ,CAC9B;;CAI7B,MAAM,gBAAgB,cAAc;AAClC,MAAI,CAAC,mBAAmB,CAAC,uBAAwB,QAAO;EAExD,MAAM,qBADoB,uBAAuB,SAAS,GACX,SAAS;AACxD,SAAO,IAAI,KAAK,mBAAmB;IAClC;EAAC;EAAQ;EAAwB;EAAgB,CAAC;AAGrD,iBAAgB;AACd,MAAI,UAAU,mBAAmB,wBAAwB;GAEvD,MAAM,mBACJ,uBAAuB,SAAS,GAAG;AAErC,mBADoB,IAAI,KAAK,iBAAiB,CAAC,aAAa,CAAC,MAAM,GAAG,GAAG,CAC7C;AAC5B,aAAU,EAAE;AACZ,gBAAa,KAAK;;IAEnB;EAAC;EAAQ;EAAiB;EAAuB,CAAC;CAErD,MAAM,eAAe,YAAY,YAAY;AAC3C,MACE,CAAC,gBACD,CAAC,kBACD,CAAC,UAAU,aACX,SAAS,UAAU,WAAW,KAC9B,CAAC,QACD;AACA,gBAAa,6CAA6C;AAC1D;;AAGF,MAAI,CAAC,UAAU,UAAU,KAAK,SAAS,KAAK;AAC1C,gBAAa,iDAAiD;AAC9D;;AAGF,MAAI,CAAC,cAAc;AACjB,gBAAa,mCAAmC;AAChD;;AAGF,MAAI,CAAC,YAAY;AACf,gBAAa,qCAAqC;AAClD;;AAGF,iBAAe,KAAK;AACpB,eAAa,KAAK;AAElB,MAAI;GACF,MAAM,WAAW,MAAM,aAAa,aAAa;GACjD,MAAM,UAAU,UAAU;GAG1B,MAAM,cACJ,YAAY,UAAsC;GACpD,MAAM,kBACJ,YAAY,UAAsC;GACpD,MAAM,iBACJ,YAAY,YACR,8BAA8B,iBAC9B,8BAA8B;AAEpC,OAAI,CAAC,eAAe,CAAC,gBACnB,OAAM,IAAI,MAAM,kCAAkC;GAIpD,MAAM,sCAAsB,IAAI,KAAqB;GACrD,IAAIA,SAAoC;GACxC,IAAI,cAAc;AAElB,UAAO,aAAa;IAClB,MAAM,eAAe,MAAM,UAAU,gBAAgB;KACnD,OAAO,eAAe;KACtB,QAAQ,EAAE,YAAY,UAAU;KAChC,SAAS,EAAE,aAAa,MAAM;KAC9B;KACD,CAAC;AAEF,SAAK,MAAM,YAAY,SAAS,WAAW;KACzC,MAAM,SAAS,SAAS;AACxB,SAAI,oBAAoB,IAAI,OAAO,CAAE;AAErC,UAAK,MAAM,OAAO,aAAa,KAC7B,KAAI,IAAI,MAAM,WAAW,YAAY,IAAI,KAAK,SAAS;MACrD,MAAM,SAAS,IAAI,KAAK,QAAQ;AAChC,UAAI,aAAa,QAEf;WADkB,OAAO,OAAO,QAAQ,KACtB,QAAQ;AACxB,4BAAoB,IAAI,QAAQ,IAAI,KAAK,SAAS;AAClD;;;;;AAOV,kBAAc,aAAa;AAC3B,aAAS,aAAa;;AAGxB,OAAI,oBAAoB,SAAS,EAC/B,OAAM,IAAI,MACR,2EACD;GAGH,MAAM,KAAK,IAAI,aAAa;AAC5B,MAAG,UAAU,eAAe,QAAQ;GAEpC,MAAM,UAAU,MAAM,UAAU,SAAS;IACvC,OAAO,eAAe;IACtB,UAAU;IACX,CAAC;AAEF,OAAI,QAAQ,KAAK,WAAW,EAC1B,OAAM,IAAI,MACR,iEACD;AAIH,OAAI,QAAQ,KAAK,SAAS,EACxB,IAAG,WACD,GAAG,OAAO,QAAQ,KAAK,GAAG,aAAa,EACvC,QAAQ,KAAK,MAAM,EAAE,CAAC,KAAI,SAAQ,GAAG,OAAO,KAAK,aAAa,CAAC,CAChE;AAIH,QAAK,MAAM,CAAC,SAAS,aAAa,oBAAoB,SAAS,CAC7D,IAAG,SAAS;IACV,SAAS;IACT,QAAQ;IACR,UAAU;IACV,WAAW;KACT,GAAG,OAAO,eAAe;KACzB,GAAG,OAAO,SAAS;KACnB,GAAG,KAAK,IAAI,OAAO;KACnB,GAAG,OAAO,QAAQ,KAAK,GAAG,aAAa;KACxC;IACF,CAAC;GAGJ,MAAM,SAAS,MAAM,WAAW,QAAQ;IACtC,aAAa;IACb,aAAa,aAAa,oBAAoB,KAAK,cAAc,OAAO;IACzE,CAAC;AAGF,SAAM,UAAU,mBAAmB,EAAE,QAAQ,CAAC;AAG9C,SAAM,YAAY,kBAAkB,EAClC,YAAW,UAAS;IAClB,MAAM,MAAM,MAAM;AAClB,WACG,MAAM,QAAQ,IAAI,KAChB,IAAI,OAAO,iBAAiB,IAAI,OAAO,mBAC1C;MAGL,CAAC;AAGF,SAAM,sBAAsB;GAG5B,MAAM,iBAAiB,yBAAyB,oBAAoB,KAAK,cAAc,OAAO;AAC9F,eAAY,gBAAgB,OAAO;AAGnC,0BAAuB,IAAI,MAAM;AACjC,mBAAgB,GAAG;AACnB,aAAU,EAAE;AACZ,gBAAa,KAAK;WACX,OAAO;AACd,WAAQ,MAAM,0BAA0B,MAAM;AAC9C,gBACE,qBAAqB,iBAAiB,QAAQ,MAAM,UAAU,kBAC/D;YACO;AACR,kBAAe,MAAM;;IAEtB;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAM,oBAAoB;AACxB,yBAAuB,IAAI,MAAM;AACjC,kBAAgB,GAAG;AACnB,YAAU,EAAE;AACZ,eAAa,KAAK;;AAGpB,KAAI,CAAC,UAAU,CAAC,SACd,QAAO;AAGT,QACE,oBAAC,OAAO;EAAK,MAAM;EAAQ,eAAc,SAAQ,CAAC,QAAQ,aAAa;YACrE,qBAAC,OAAO,qBACN,oBAAC,OAAO,WAAQ,WAAWC,YAAkB,EAC7C,qBAAC,OAAO;GAAQ,WAAWC;;IAExB,eACC,oBAAC;KAAI,WAAWC;eACd,qBAAC;MAAI,WAAWC;iBACd,oBAAC,WAAQ,WAAWC,YAAkB,EACtC,oBAAC,iBAAE,8BAA6B;OAC5B;MACF;IAIR,qBAAC;KAAI,WAAWC;;MACd,qBAAC,OAAO;OAAM,WAAWC;kBAAc,oBACpB,SAAS;QACb;MACf,oBAAC,OAAO;OAAY,WAAWC;iBAAoB;QAG9B;MACrB,oBAAC,OAAO;OAAM;iBACZ,oBAAC;QAAO,MAAK;QAAS,WAAWC;kBAC/B,oBAAC,KAAE,MAAM,KAAM;SACR;QACI;;MACX;IAGN,qBAAC;KAAI,WAAWC;;MAEb,2BAA2B,KAC1B,oBAAC;OACC,OAAM;OACN,aAAY;OACZ,SAAQ;QACR;MAIH,2BAA2B,KAC1B,oBAAC;OACC,OAAM;OACN,aAAY;OACZ,SAAQ;QACR;MAGJ,qBAAC;OAAI,WAAWC;;QACd,qBAAC;SAAI,WAAWC;;UACd,oBAAC;WAAM,SAAQ;qBAAkB;YAA8B;UAC/D,oBAAC;WAAI,WAAWC;qBACd,oBAAC;YACC,IAAG;YACH,MAAK;YACL,OAAO;YACP,KAAK;YACL,KAAK;YACL,UAAU;YACV,UAAU,2BAA2B,KAAK;YAC1C,WAAW,YAAYC,aAAoB;aAC3C;YACE;UAGL,mBACC,qBAAC;WAAI,WAAWC;sBACd,oBAAC,QAAK,MAAM,KAAM,EAClB,qBAAC;YAAK;YACM;aACR,mBAAmB,MAAO,KAAK,KAAK,KAAK,QAAQ,EAAE;YAAE;YAAI;eAEtD;YACH;UAEP,aAAa,oBAAC;WAAE,WAAWC;qBAAmB;YAAc;;UACzD;QAGN,qBAAC;SAAI,WAAWC;oBAEd,qBAAC;UAAI,WAAWC;qBACd,qBAAC;WAAI,WAAWC;sBACd,oBAAC,YAAS,MAAM,KAAM,EACtB,oBAAC,oBAAK,uBAAyB;YAC3B,EACL,yBACC,qBAAC;WAAI,WAAWC;;YACd,oBAAC;aAAI,WAAWC;uBACb,WAAW,uBAAuB;cAC/B;YACL,2BAA2B,QAC1B,yBAAyB,KACvB,qBAAC;aAAI,WAAWC;;cACb;cAAuB;cACvB,2BAA2B,IAAI,MAAM;cAAG;;cACrC;YAET,2BAA2B,KAC1B,oBAAC;aAAI,WAAWC;uBAAqB;cAAa;;YAEhD,GAEN,oBAAC;WAAI,WAAWF;qBAAqB;YAAiB;WAEpD,EAGN,qBAAC;UAAI,WAAWH;qBACd,qBAAC;WAAI,WAAWC;sBACd,oBAAC,SAAM,MAAM,KAAM,EACnB,oBAAC,oBAAK,wBAA0B;YAC5B,EACL,gBACC,qBAAC;WAAI,WAAWC;sBACd,oBAAC;YAAI,WAAWC;sBACb,WAAW,cAAc;aACtB,EACL,2BAA2B,QAC1B,qBAAC;YAAI,WAAWC;;aACb;aAAuB;aAAG;aAC1B,yBAAyB;aAAO;aAAW;aAAQ;aAAI;aAClD,WAAW,IAAI,MAAM;aAAG;;aAC1B;YAEJ,GAEN,oBAAC;WAAI,WAAWD;qBAAqB;YAAmB;WAEtD;UACF;QAGN,qBAAC;SAAI,WAAWG;oBACd,qBAAC;UAAI,WAAWC;;WACd,oBAAC,cAAW,MAAM,KAAM;WACxB,oBAAC,oBAAK,iBAAmB;WACxB,kBAAkB,QAAQ,sBAAsB,QAC/C,oBAAC;YAAK,WAAWC;sBAAuB;aAAgB;;WAEtD,EACN,qBAAC;UAAI,WAAWC;;WACd,qBAAC;YAAI,WAAWC;uBACd,oBAAC;aAAK,WAAWC;uBAAkB;cAAY,EAC/C,oBAAC;aAAK,WAAWC;uBACd,kBAAkB,OACf,eAAe,cAAc,GAC7B,sBAAsB,OACpB,eAAe,kBAAkB,GACjC;cACD;aACH;WACN,qBAAC;YAAI,WAAWF;uBACd,oBAAC;aAAK,WAAWC;uBAAkB;cAAiB,EACpD,qBAAC;aAAK,WAAWC;;cACd,UAAU,WAAW,UAAU;cAAE;cAAc;cAAQ;cAAI;cAE3D,WAAW,IAAI,MAAM;;cACjB;aACH;WACL,wBAAwB,yBACvB,qBAAC;YAAI,WAAWC;uBACd,oBAAC;aAAQ,MAAM;aAAI,WAAW1B;cAAkB,EAChD,oBAAC,oBAAK,wBAA0B;aAC5B,GACJ,mBAAmB,oBACrB;YACG,kBAAkB,QAAQ,sBAAsB,QAC/C,qBAAC;aAAI,WAAW2B;wBACd,oBAAC,QAAK,MAAM,KAAM,EAClB,qBAAC;cAAK;cACoB;cACvB,UAAU,WAAW,UAAU;cAAE;cACjC,UAAU,WAAW,WAAW,IAAI,MAAM;iBACtC;cACH;YAER,oBAAC,SAAI,WAAWC,cAAsB;YACtC,qBAAC;aAAI,WAAWL;wBACd,oBAAC;cAAK,WAAWC;wBAAkB;eAAoB,EACvD,qBAAC;cAAK,WAAWC;;eACd,gBACC,iBAAiB,eACf,mBAAmB,YACtB;eAAE;eAAI;;eAEF;cACH;eACL,GACD,mBACF,qBAAC;YAAI,WAAWI;uBACd,oBAAC,QAAK,MAAM,KAAM,EAClB,oBAAC,oBAAK,6EAGC;aACH,GAEN,qBAAC;YAAI,WAAWA;uBACd,oBAAC,QAAK,MAAM,KAAM,EAClB,oBAAC,oBAAK,6BAA+B;aACjC;;WAEJ;UACF;;QACF;;MACF;IAGN,qBAAC;KAAI,WAAWC;gBACd,oBAAC;MACC,SAAQ;MACR,SAAS;MACT,UAAU;gBACX;OAEQ,EACT,oBAAC;MACC,SAAS;MACT,UACE,eACA,CAAC,UACD,CAAC,gBACD,CAAC,CAAC,aACF,2BAA2B;gBAG5B,cAAc,iBAAiB;OACzB;MACL;;IACS,IACH;GACJ;;AAIlB,+BAAe;;;;;;;;;;;;;;;;AE1sBf,MAAMC,eAAqC,EACzC,UACA,QACA,gBACA,eACA,cACA,aACA,UAAU,WACV,SACA,qBACI;CACJ,MAAM,aAAa,CAAC,CAAC;CACrB,MAAM,gBAAgB,SAClB,wBAAwB,QAAQ,cAAc,YAAY,GAC1D;CAEJ,MAAM,EAAE,MAAM,cAAc,qBAAqB,gBAAgB;EAC/D,WAAW,QAAQ;EACnB,aAAa,QAAQ;EACtB,CAAC;CAEF,MAAM,oBAAoB,UAAU,QAAO,MAAK,EAAE,iBAAiB,OAAO;CAE1E,MAAM,gBAAgB,SAAS,kBAAkB,SAAS;CAC1D,MAAM,WAAW,cAAc,SAAS,IAAI,cAAc,GAAG,QAAQ;AAErE,QACE,qBAAC,aAAa,mBACZ,oBAAC,aAAa;EAAQ;EAAS;GAAgC,EAC/D,oBAAC,aAAa,oBACZ,qBAAC,aAAa;EAAQ,WAAWC;;GAE/B,qBAAC;IAAI,WAAWC;eACd,oBAAC;KAAG,WAAWC;eACZ,aAAa,qBAAqB;MAChC,EACJ,cAAc,gBACb,kBAAkB,SAAS,KAAK,WAC9B,qBAAC;KAAE,WAAWC;;MAAoB;MACX;MACrB,oBAAC;OACC,MAAM;OACN,QAAO;OACP,KAAI;OACJ,WAAWC;iBAEV;QACC;;;MAEF,GAEJ,qBAAC;KAAE,WAAWD;;MAAoB;MACX;MACrB,qBAAC;OACC,MACE,YAAY,YACR,wCAAwC,WACxC,gCAAgC;OAEtC,QAAO;OACP,KAAI;OACJ,WAAWC;kBACZ,YAEC,oBAAC,gBACC,OAAO;QACL,SAAS;QACT,OAAO;QACP,QAAQ;QACR,YAAY;QACb,GACD;QACA;;;MAEF,GAGN,qBAAC;KAAE,WAAWD;;MAAoB;MACb;MACnB,oBAAC;OACC,MAAK;OACL,QAAO;OACP,KAAI;OACJ,WAAWC;iBACZ;QAEG;;;MAGF;KAEF;GAEN,oBAAC,aAAa,aAAU,WAAWC,YAAoB;GAGvD,qBAAC,aAAa;IACZ,WAAWC;IACX,UAAU;IACV,UAAU,CAAC;;KAEX,oBAAC,UAAO,OAAO;MAAE,OAAO;MAAQ,QAAQ;MAAQ,GAAI;KACpD,oBAAC;MAAK,OAAO,EAAE,MAAM,GAAG;gBAAE;OAAuB;KAChD,CAAC,UACA,oBAAC;MACC,OAAO;OACL,UAAU;OACV,OAAO;OACR;gBACF;OAEM;;KAES;GAEpB,qBAAC,aAAa;IACZ,WAAWA;IACX,gBAAgB;AACd,4BAAuB,IAAI,KAAK;;IAElC,UAAU,CAAC;;KAEX,oBAAC,iBAAc,OAAO;MAAE,OAAO;MAAQ,QAAQ;MAAQ,GAAI;KAC3D,oBAAC;MAAK,OAAO,EAAE,MAAM,GAAG;gBAAE;OAAkB;KAC3C,CAAC,UACA,oBAAC;MACC,OAAO;OACL,UAAU;OACV,OAAO;OACR;gBACF;OAEM;;KAES;GAEpB,oBAAC,aAAa,aAAU,WAAWD,YAAoB;GAGvD,qBAAC;IAAI,WAAWE;eACb,cAAc,gBACb,qBAAC;KAAI,WAAWC;gBACb,WACC,oBAAC,aAAa;MACZ,WAAW,OAAO;OAChB,SAAS;OACT,MAAM;OACP,CAAC;MACF,OAAO,EAAE,OAAO,QAAQ;MACxB,gBAAgB;AACd,cAAO,KACL,2BACE,UACA,cACA,YACD,EACD,UACA,sBACD;;gBAEJ;OAEmB,GAEpB,oBAAC,aAAa;MACZ,WAAW,OAAO;OAAE,SAAS;OAAW,MAAM;OAAW,CAAC;MAC1D,OAAO,EAAE,OAAO,QAAQ;MACxB,gBAAgB;AACd,0BAAmB,IAAI,KAAK;;gBAE/B;OAEmB,EAEtB,oBAAC,aAAa;MACZ,WAAW,OAAO;OAAE,SAAS;OAAY,MAAM;OAAW,CAAC;MAC3D,UAAU;gBACX;OAEmB;MAChB,GAEN,oBAAC,aAAa;KACZ,WAAW,OAAO;MAAE,SAAS;MAAY,MAAM;MAAW,CAAC;KAC3D,OAAO,EAAE,OAAO,QAAQ;KACxB,UAAU;eACX;MAEmB,EAIrB,YAAY,aACX,oBAAC;KACC,OAAM;KACN,aAAY;KACZ,SAAQ;KACR,KAAI;KACJ,SAAQ;MACR;KAEA;;GACe,GACH,IACJ;;AAIxB,0BAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AEvNf,MAAMC,gBAAuC,EAC3C,QACA,QACA,UACA,gBACA,eACA,SAAS,EAAE,aAAa,qBACpB;CACJ,MAAM,CAAC,sBAAsB,2BAA2B,SAAS,MAAM;CACvE,MAAM,CAAC,0BAA0B,+BAC/B,SAAS,MAAM;CACjB,MAAM,CAAC,aAAa,kBAAkB,SAAS,MAAM;CACrD,MAAM,CAAC,gBAAgB,qBAAqB,SAAiB,EAAE;CAC/D,MAAM,CAAC,eAAe,oBAAoB,SAAiB,EAAE;CAE7D,MAAM,SAAS,SAAS,oBAAoB,oBAAoB;CAChE,MAAM,YAAY,SAAS,oBAAoB,UAAU;CACzD,MAAM,mBAAmB,SAAS,oBAAoB,iBAAiB;CACvE,MAAM,kBAAkB,SAAS,oBAAoB,oBAAoB;CACzE,MAAM,kBAAkB,SAAS,kBAAkB,gBAAgB;CACnE,MAAM,aAAa,SAAS,kBAAkB,WAAW;CACzD,MAAM,SAAS,SAAS,kBAAkB,OAAO;CACjD,MAAM,UAAU,SAAS,kBAAkB,QAAQ;CACnD,MAAM,YAAY,SAAS,kBAAkB,QAAQ;CACrD,MAAMC,UAAQ,SAAS,kBAAkB,MAAM;CAC/C,MAAMC,gBAAc,SAAS,kBAAkB,YAAY;CAE3D,MAAM,EAAE,iBAAiB,sBAAsB,iBAAiB,aAAa;AAG7E,iBAAgB;AACd,MAAI,UAAU,UAAU,mBAAmB,EACzC,mBAAkB,OAAO;IAE1B;EAAC;EAAQ;EAAQ;EAAe,CAAC;CAGpC,MAAM,aAAa,cACX,OAAO,QAAQ,KAAK,MAAM,MAAM,EAAE,QAAQ,YAAY,EAAE,EAC9D,CAAC,OAAO,CACT;CAGD,MAAM,UAAU,cAAc;AAC5B,MAAI,CAAC,gBAAiB,QAAO;EAG7B,MAAM,cAFM,KAAK,KAAK,GACJ,IACoB;AACtC,SAAO,IAAI,KAAK,YAAY,CAAC,aAAa,CAAC,MAAM,GAAG,GAAG;IACtD,CAAC,gBAAgB,CAAC;CAErB,MAAM,UAAU,cAAc;AAC5B,MAAI,CAAC,gBAAiB,QAAO;EAG7B,MAAM,cAFM,KAAK,KAAK,GACJ,KACoB;AACtC,SAAO,IAAI,KAAK,YAAY,CAAC,aAAa,CAAC,MAAM,GAAG,GAAG;IACtD,CAAC,gBAAgB,CAAC;CAGrB,MAAM,2BAA2B,mBAAyB;AACxD,MAAI,CAAC,mBAAmB,CAACC,eAAc,QAAO;EAE9C,MAAM,MAAM,KAAK,KAAK;EAEtB,MAAM,SADa,IAAI,KAAKA,eAAa,CAAC,SAAS,GACvB;AAE5B,MAAI,UAAU,EAAG,QAAO;EAGxB,MAAM,cAAc,SAAS;EAC7B,MAAM,gBAAgB,KAAK,KAAK,YAAY;AAG5C,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,cAAc,CAAC;;CAIjD,MAAM,oBAAoB,MAA2C;EACnE,MAAMA,iBAAe,EAAE,OAAO;AAC9B,MAAI,CAACA,eAAc;EAEnB,MAAM,mBAAmB,wBAAwBA,eAAa;AAG9D,MAAI,UAAU,iBAAiB,EAC7B,kBAAiB,iBAAiB;AAGpC,oBAAkB,OAAO,IAAI,iBAAiB;;CAIhD,MAAM,+BAA+B,YAAY;AAC/C,MAAI,CAAC,eAAgB;AAGrB,QAAM,gBAAgB;AAGtB,MACE,UACA,iBACA,iBAAiB,KACjB,gBAAgB,gBAChB;GACA,MAAM,kBAAkB,gBAAgB;AAExC,OAAI,kBAAkB,GAAG;AACvB,mBAAe,KAAK;AACpB,QAAI;AACF,WAAM,cAAc,gBAAgB;AAEpC,uBAAkB,cAAc;AAChC,sBAAiB,EAAE;aACZ,OAAO;AACd,aAAQ,MAAM,2BAA2B,MAAM;cACvC;AACR,oBAAe,MAAM;;;;;CAO7B,MAAM,eAAe,cAAc;AACjC,MAAI,CAAC,mBAAmB,CAAC,OAAQ,QAAO;EAExC,MAAM,aADM,KAAK,KAAK,GACG,SAAS;AAClC,SAAO,IAAI,KAAK,WAAW,CAAC,aAAa,CAAC,MAAM,GAAG,GAAG;IACrD,CAAC,QAAQ,gBAAgB,CAAC;CAE7B,MAAM,EACJ,MAAM,cAAc;EAClB,aAAa;EACb,WAAW;EACX,WAAW;EACZ,EACD,WAAW,oBACX,SAAS,qBACP,oBAAoB,YAAY,QAAQ;EAAE;EAAc;EAAa,CAAC;CAE1E,MAAM,kBAAkB;EACtB;GACE,OAAO;GACP,aAAa;GACd;EACD;GAAE,OAAO;GAAU,aAAa;GAAmC;EACnE;GAAE,OAAO;GAAW,aAAa;GAA+B;EAChE;GAAE,OAAO;GAAU,aAAa;GAA8B;EAC/D;CAGD,MAAM,iBAAiB,kBAAkB,OAAO;AAEhD,QACE,qBAAC,OAAO;EACN,MAAM;EACN,cAAc,oBAAoB;aAElC,qBAAC,OAAO,qBACN,oBAAC,OAAO,WAAQ,WAAWC,YAAkB,EAC7C,qBAAC,OAAO;GAAQ,WAAWC;;IACzB,oBAAC,OAAO;KAAM,WAAWC;eACtB,SAAS,cAAc;MACX;IACf,oBAAC,OAAO;KAAY,WAAWC;eAAoB;MAE9B;IAErB,oBAAC;KACC,OAAO;KACP,aAAa;KACb,WAAW;MACX;IAGF,qBAAC;KAAQ,WAAWC;gBAElB,qBAAC;MAAI,WAAWC;iBACd,qBAAC;OAAI,WAAWC;kBACd,oBAAC;QAAI,WAAWC;kBACb,kBACC,qBAAC;SAAI,WAAWC;;UACd,oBAAC;WACC,KAAK;WACL,KAAI;WACJ,WAAWC;YACX;UAEF,oBAAC,SACC,OAAO;WACL,UAAU;WACV,OAAO;WACP,YACE;WACF,eAAe;WAChB,GACD;WAEAZ,WAASC,kBACT,qBAAC;WACC,OAAO;YACL,UAAU;YACV,QAAQ;YACR,MAAM;YACN,OAAO;YACP,SAAS;YACT,OAAO;YACP,eAAe;YAChB;sBAEAD,WACC,oBAAC;YACC,OAAO;aACL,UAAU;aACV,YAAY;aACZ,cAAc;aACd,YAAY;aACZ,UAAU;aACV,cAAc;aACd,SAAS;aACT,iBAAiB;aACjB,iBAAiB;aAClB;sBAEAA;aACE,EAENC,iBACC,oBAAC;YACC,OAAO;aACL,UAAU;aACV,SAAS;aACT,YAAY;aACZ,UAAU;aACV,cAAc;aACd,SAAS;aACT,iBAAiB;aACjB,iBAAiB;aAClB;sBAEAA;aACC;YAEF;;UAEJ,GAEN;SACE,oBAAC;UACC,WAAWY;UACX,YAAY;UACZ,SAAS;UACT,OAAM;UACN,YAAY;UACZ,eAAe;WACf;SACF,oBAAC,SAAI,WAAWC,YAAoB;SACpC,qBAAC;UAAI,WAAWC;;WACd,oBAAC;YAAI,WAAWC;sBACd,qBAAC;aACC,OAAM;aACN,QAAO;aACP,MAAK;aACL,QAAO;aACP,SAAQ;wBAER,oBAAC,qBAAM,2BAA8B,EACrC,oBAAC;cACC,eAAc;cACd,gBAAe;cACf,aAAa;cACb,GAAE;eACF;cACE;aACF;WACN,oBAAC;YACC,OAAO;aACL,YAAY;aACZ,OAAO;aACP,WAAW;aACZ;sBACF;aAEG;WACJ,oBAAC;YACC,OAAO;aACL,OAAO;aACP,WAAW;aACX,UAAU;aACX;sBACF;aAEG;;WACA;YACL;SAED,EACN,oBAAC;QACC,MAAK;QACL,WAAWC;QACX,eAAe,wBAAwB,KAAK;kBAE5C,oBAAC,UAAO,MAAM,KAAM;SACb;QACL,EAEN,qBAAC;OACC,WAAWC;OACX,OAAO,EAAE,WAAW,UAAU;kBAE9B,qBAAC;QAAI,WAAWC;mBACd,qBAAC;SAAI,WAAWC;oBACd,oBAAC;UAAK,OAAO,EAAE,YAAY,KAAK;oBAAE;WAAmB,EACpD,eAAe,QACd,oBAAC;UACC,MAAK;UACL,eACE,4BAA4B,CAAC,yBAAyB;UAExD,OAAO;WACL,SAAS;WACT,QAAQ;WACR,QAAQ;WACR,YAAY;WACZ,OAAO;WACP,cAAc;WACd,YAAY;WACb;UACD,eAAc,MAAK;AACjB,aAAE,cAAc,MAAM,kBAAkB;;UAE1C,eAAc,MAAK;AACjB,aAAE,cAAc,MAAM,kBAAkB;;UAE1C,cAAW;oBAEX,oBAAC,QAAK,MAAM,KAAM;WACX;UAEP,EACN,oBAAC;SAAI,WAAWC;mBACb,eAAe,OACd,qBAAC;UACC,OAAO;WACL,OAAO;WACP,SAAS;WACT,YAAY;WACZ,KAAK;WACN;qBAED,oBAAC,QAAK,MAAM,KAAM;WAEb,GACL,qBACF,oBAAC;UAAK,OAAO,EAAE,OAAO,2BAA2B;oBAAE;WAE5C,GACL,mBACF,oBAAC;UAAK,OAAO,EAAE,OAAO,sBAAsB;oBAAE;WAEvC,GAEP,4CACE,qBAAC;UACC,OAAO;WACL,UAAU;WACV,OAAO;WACR;;YAEC,aAAa,MAAM,QAAQ,EAAE;WAAC;WAAM;;WACjC,EACP,qBAAC;UACC,OAAO;WACL,YAAY;WACZ,OAAO;WACR;;aAGE,OAAO,YAAY,YAAY,GAC9B,OAAO,YAAY,UAAU,IAC/B,KACA,QAAQ,EAAE;WAAE;WAAI;;WAEb,IACN;UAED;SACF,EAGL,4BACC,oBAAC;QAAI,WAAWC;kBACd,qBAAC;SACC,OAAO;UACL,SAAS;UACT,eAAe;UACf,KAAK;UACN;;UAED,qBAAC;WAAI,OAAO,EAAE,UAAU,YAAY;;YAClC,oBAAC;aAAK,OAAO,EAAE,YAAY,KAAK;uBAAE;cAAoB;YAAC;YACvD,qBAAC;aAAK,OAAO,EAAE,OAAO,WAAW;;eAE7B,OAAO,YAAY,YAAY,GAAG,KAClC,QAAQ,EAAE;cAAE;cAAI;;cAEb;;YACH;UACN,qBAAC;WAAI,OAAO,EAAE,UAAU,YAAY;;YAClC,oBAAC;aAAK,OAAO,EAAE,YAAY,KAAK;uBAAE;cAAkB;YAAC;YACrD,qBAAC;aAAK,OAAO,EAAE,OAAO,WAAW;;eAE7B,OAAO,YAAY,UAAU,GAAG,KAChC,QAAQ,EAAE;cAAE;cAAI;;cAEb;;YACH;UACN,qBAAC;WACC,OAAO;YACL,UAAU;YACV,WAAW;YACX,YAAY;YACZ,WAAW;YACZ;;YAED,oBAAC;aAAK,OAAO,EAAE,YAAY,KAAK;uBAAE;cAAkB;YAAC;YACrD,qBAAC;aAAK,OAAO;cAAE,OAAO;cAAW,YAAY;cAAK;;gBAE7C,OAAO,YAAY,YAAY,GAC9B,OAAO,YAAY,UAAU,IAC/B,KACA,QAAQ,EAAE;cAAE;cAAI;;cAEb;;YACH;;UACF;SACF;QAEJ;OACF,EAGN,oBAAC;MAAI,WAAWC;gBACd,oBAAC;OAAI,WAAWC;iBAEd,qBAAC;QAAI,WAAWC;;SAEd,qBAAC,yBACC,qBAAC;UAAI,WAAWC;qBACd,oBAAC,mBAAM,UAAa,EACpB,qBAAC;WAAK,WAAWC;sBACd,kBAAkB,MAAM,KAAK,CAAC,QAAO;YACjC;WACH,EACN,oBAAC;UACC,OAAO,kBAAkB,MAAM,KAAK;UACpC,WAAU,MACR,kBAAkB,MAAM,IACtB,EAAE,OAAO,MAAM,MAAM,GAAG,IAAI,CAC7B;UAEH,aAAY;WACZ,IACO;SAGX,qBAAC,yBACC,qBAAC;UAAI,WAAWD;qBACd,oBAAC,mBAAM,gBAAmB,EAC1B,qBAAC;WAAK,WAAWC;sBACd,kBAAkB,YAAY,KAAK,CAAC,QAAO;YACvC;WACH,EACN,oBAAC;UACC,OAAO,kBAAkB,YAAY,KAAK;UAC1C,WAAU,MACR,kBAAkB,YAAY,IAC5B,EAAE,OAAO,MAAM,MAAM,GAAG,IAAI,CAC7B;UAEH,aAAY;UACZ,MAAM;WACN,IACO;SAGX,qBAAC,yBACC,qBAAC,oBAAM,eAEL,oBAAC;UACC,OAAO;WACL,UAAU;WACV,OAAO;WACR;oBACF;WAEM,IACD,EACR,oBAAC;UACC,OAAO;UACP,WAAU,MACR,kBAAkB,WAAW,IAAI,EAAE,OAAO,MAAM;UAElD,aAAY;WACZ,IACO;SAGV,CAAC,UACA,qBAAC;UACC,qBAAC;WAAI,WAAWD;sBACd,oBAAC,mBAAM,qBAAwB,EAC9B,SAAS,KACR,qBAAC;YACC,OAAO;aACL,UAAU;aACV,OAAO;aACP,SAAS;aACT,YAAY;aACZ,KAAK;aACN;uBAED,oBAAC;aACC,OAAO;cACL,YAAY;cACZ,OAAO;cACR;uBAEA;cACI;aAEF;YAEL;UAGN,qBAAC;WAAI,OAAO,EAAE,UAAU,YAAY;sBAClC,oBAAC;YACC,MAAK;YACL,OAAO;YACP,KAAK;YACL,KAAK;YACL,UAAU;YACV,UAAU;YACV,OAAO;aACL,aAAa;aACb,QAAQ,YAAY,SAAS;aAC9B;aACD,EACF,oBAAC;YACC,MAAM;YACN,OAAO;aACL,UAAU;aACV,MAAM;aACN,KAAK;aACL,WAAW;aACX,OAAO;aACP,eAAe;aAChB;aACD;YACE;UAGL,kBAAkB,mBACjB,qBAAC;WACC,OAAO;YACL,SAAS;YACT,YAAY;YACZ,KAAK;YACL,UAAU;YACV,OAAO;YACP,WAAW;YACZ;sBAED,oBAAC;YAAK,MAAM;YAAI,OAAO,EAAE,YAAY,GAAG;aAAI,EAC5C,qBAAC;YAAK;YACM;aACR,mBAAmB,MAAO,KAAK,KAAK,KAAK,QACzC,EACD;YAAE;YAAI;YAEN;YAAM;eAEF;YACH;aAEC;;SAET;QACF;OACF;MACE;IAET,UACC,oBAAC;KAAQ,WAAWE;eAClB,qBAAC;MAAI,WAAWC;iBACd,oBAAC;OACC,SAAQ;OACR,OAAO,EAAE,MAAM,GAAG;OAClB,SAAS,kBAAkB;OAC3B,UAAU;iBACX;QAEQ,EACT,oBAAC;OACC,OAAO;QACL,MAAM;QACN,SAAS;QACT,YAAY;QACZ,gBAAgB;QAChB,KAAK;QACN;OACD,SAAS;OACT,UAAU,aAAa;iBAEtB,aAAa,cACZ,4CACE,oBAAC;QAAQ,MAAM;QAAI,WAAWC;SAAkB,EAC/C,cAAc,yBAAyB,eACvC,GAEH;QAEK;OACL;MACE,GAEV,qBAAC;KAAQ,WAAWF;gBAClB,oBAAC;MAAI,WAAWC;gBACd,qBAAC;OACC,SAAQ;OACR,OAAO;QACL,OAAO;QACP,SAAS;QACT,YAAY;QACZ,gBAAgB;QAChB,KAAK;QACN;OACD,SAAS;OACT,UAAU;kBAET,aACC,oBAAC;QAAQ,MAAM;QAAI,WAAWC;SAAkB,EAEjD;QACM;OACL,EACN,oBAAC;MACC,OAAM;MACN,aAAY;MAEZ,SAAQ;OACR;MACM;;IAEG,IACH,EAGhB,oBAAC;GACC,QAAQ;GACR,eAAe,wBAAwB,MAAM;IAC7C;GACU;;AAUlB,SAAS,mBAAmB,EAAE,QAAQ,WAAoC;CACxE,MAAM,kBAAkB,SAAS,kBAAkB,gBAAgB;CACnE,MAAM,UAAU,SAAS,kBAAkB,QAAQ;CACnD,MAAM,YAAY,SAAS,kBAAkB,QAAQ;CAErD,MAAM,CAAC,YAAY,iBAAiB,SAAyB,OAAO;CACpE,MAAM,CAAC,UAAU,eAAe,SAAS,GAAG;CAC5C,MAAM,CAAC,UAAU,eAAe,SAAS,GAAG;CAC5C,MAAM,CAAC,eAAe,oBAAoB,SAAS,GAAG;CACtD,MAAM,eAAe,OAAyB,KAAK;CAEnD,MAAM,gBAAgB,IAAI,OAAO;CAEjC,MAAM,qBAAqB,MAA2C;EACpE,MAAM,OAAO,EAAE,OAAO,QAAQ;AAC9B,MAAI,CAAC,KAAM;AAGX,MAAI,KAAK,OAAO,eAAe;AAC7B,oBACE,iCAAiC,KAAK,OAAO,OAAO,MAAM,QAAQ,EAAE,CAAC,KACtE;AACD,KAAE,OAAO,QAAQ;AACjB;;AAGF,mBAAiB,GAAG;AACpB,oBAAkB,SAAS,IAAI,KAAK;;CAGtC,MAAM,wBAAwB;AAC5B,MAAI,CAAC,SAAS,MAAM,EAAE;AACpB,eAAY,2BAA2B;AACvC;;AAGF,MAAI;AACF,OAAI,IAAI,SAAS;AACjB,qBAAkB,SAAS,IAAI,SAAS;AACxC,eAAY,GAAG;AACf,eAAY,GAAG;AACf,iBAAc,OAAO;UACf;AACN,eAAY,2BAA2B;;;CAI3C,MAAM,qBAAqB;AACzB,oBAAkB,YAAY;AAC9B,gBAAc,OAAO;AACrB,cAAY,GAAG;AACf,cAAY,GAAG;AACf,mBAAiB,GAAG;AACpB,WAAS;;AAGX,QACE,oBAAC,OAAO;EAAK,MAAM;EAAQ,cAAc;YACvC,qBAAC,OAAO,qBACN,oBAAC,OAAO,WAAQ,WAAWC,gBAAwB,EACnD,qBAAC,OAAO;GAAQ,WAAWC;;IAEzB,qBAAC;KAAI,WAAWC;gBACd,oBAAC,OAAO;MACN,OAAO;OACL,UAAU;OACV,YAAY;OACZ,OAAO;OACR;gBACF;OAEc,EACf,oBAAC,OAAO;MAAM;gBACZ,oBAAC;OACC,MAAK;OACL,OAAO;QACL,SAAS;QACT,QAAQ;QACR,QAAQ;QACR,YAAY;QACZ,OAAO;QACP,cAAc;QACd,YAAY;QACb;OACD,eAAc,MAAK;AACjB,UAAE,cAAc,MAAM,kBAAkB;;OAE1C,eAAc,MAAK;AACjB,UAAE,cAAc,MAAM,kBAAkB;;iBAG1C,oBAAC,KAAE,MAAM,KAAM;QACR;OACI;MACX;IAGN,oBAAC;KAAI,WAAWC;eAEd,qBAAC;MACC,qBAAC;OAAI,WAAWR;kBACd,oBAAC,mBAAM,kBAAqB,EAC5B,oBAAC;QACC,OAAO;SACL,UAAU;SACV,OAAO;SACR;kBACF;SAEM;QACH;MAGN,qBAAC;OACC,OAAO;QACL,SAAS;QACT,KAAK;QACL,cAAc;QACd,SAAS;QACT,iBAAiB;QACjB,cAAc;QACf;kBAED,oBAAC;QACC,MAAK;QACL,eAAe;AACb,uBAAc,OAAO;AACrB,qBAAY,GAAG;;QAEjB,OAAO;SACL,MAAM;SACN,SAAS;SACT,UAAU;SACV,YAAY;SACZ,QAAQ;SACR,cAAc;SACd,QAAQ;SACR,YAAY;SACZ,iBACE,eAAe,SACX,sBACA;SACN,OACE,eAAe,SACX,sBACA;SACN,WACE,eAAe,SACX,iCACA;SACP;kBACF;SAEQ,EACT,oBAAC;QACC,MAAK;QACL,eAAe;AACb,uBAAc,MAAM;AACpB,0BAAiB,GAAG;;QAEtB,OAAO;SACL,MAAM;SACN,SAAS;SACT,UAAU;SACV,YAAY;SACZ,QAAQ;SACR,cAAc;SACd,QAAQ;SACR,YAAY;SACZ,iBACE,eAAe,QACX,sBACA;SACN,OACE,eAAe,QACX,sBACA;SACN,WACE,eAAe,QACX,iCACA;SACP;kBACF;SAEQ;QACL;MAEL,eAAe,SACd;OACE,oBAAC;QACC,WAAWS;QACX,eAAe,CAAC,aAAa,aAAa,SAAS,OAAO;QAC1D,OAAO;SACL,QAAQ,YAAY,SAAS;SAC7B,SAAS,YAAY,KAAM;SAC5B;kBAEA,YACC,qBAAC;SAAI,WAAWC;oBACd,oBAAC,SACC,OAAO;UACL,OAAO;UACP,QAAQ;UACR,QAAQ;UACR,WAAW;UACX,cAAc;UACd,WAAW;UACX,cAAc;UACf,GACD,EACF,oBAAC;UACC,OAAO;WACL,YAAY;WACZ,OAAO;WACP,WAAW;WACZ;oBACF;WAEG;UACA,GACJ,kBACF,oBAAC;SACC,KAAK;SACL,KAAI;SACJ,OAAO;UACL,OAAO;UACP,QAAQ;UACR,WAAW;UACX,cAAc;UACf;UACD,GAEF,qBAAC;SAAI,WAAWA;;UACd,oBAAC;WACC,MAAM;WACN,OAAO;YACL,cAAc;YACd,OAAO;YACR;YACD;UACF,oBAAC;WACC,OAAO;YACL,YAAY;YACZ,OAAO;YACP,WAAW;YACZ;qBACF;YAEG;UACJ,oBAAC;WACC,OAAO;YACL,UAAU;YACV,OAAO;YACP,WAAW;YACX,WAAW;YACZ;qBACF;YAEG;;UACA;SAEJ;OACN,oBAAC;QACC,KAAK;QACL,MAAK;QACL,QAAO;QACP,UAAU;QACV,OAAO,EAAE,SAAS,QAAQ;SAC1B;OACD,iBACC,qBAAC;QACC,OAAO;SACL,UAAU;SACV,OAAO;SACP,WAAW;SACX,SAAS;SACT,YAAY;SACZ,KAAK;SACN;mBAED,oBAAC,QAAK,MAAM,KAAM,EACjB;SACC;UAEL,GAEH,qBAAC;OACC,OAAO;QACL,SAAS;QACT,eAAe;QACf,KAAK;QACN;kBAEA,mBACC,oBAAC;QACC,OAAO;SACL,OAAO;SACP,aAAa;SACb,cAAc;SACd,UAAU;SACV,QAAQ;SACT;kBAED,oBAAC;SACC,KAAK;SACL,KAAI;SACJ,OAAO;UACL,OAAO;UACP,QAAQ;UACR,WAAW;UACZ;UACD;SACE,EAER,qBAAC;QACC,oBAAC,mBAAM,cAAiB;QACxB,qBAAC;SACC,OAAO;UACL,SAAS;UACT,KAAK;UACL,WAAW;UACZ;oBAED,oBAAC;UACC,OAAO;UACP,WAAU,MAAK;AACb,uBAAY,EAAE,OAAO,MAAM;AAC3B,uBAAY,GAAG;;UAEjB,YAAW,MAAK;AACd,eAAI,EAAE,QAAQ,QACZ,kBAAiB;;UAGrB,aAAY;UACZ,OAAO,EAAE,MAAM,GAAG;WAClB,EACF,oBAAC;UACC,SAAS;UACT,OAAO,EAAE,YAAY,GAAG;oBACzB;WAEQ;UACL;QACL,YACC,qBAAC;SACC,OAAO;UACL,UAAU;UACV,OAAO;UACP,WAAW;UACX,SAAS;UACT,YAAY;UACZ,KAAK;UACN;oBAED,oBAAC,QAAK,MAAM,KAAM,EACjB;UACC;WAEF;QACF;SAEJ;MACF;IAGN,qBAAC;KAAI,WAAWC;gBACd,oBAAC;MACC,MAAK;MACL,eAAe;AACb,yBAAkB,SAAS,IACzB,qCACD;AACD,gBAAS;;MAEX,OAAO;OACL,UAAU;OACV,YAAY;OACZ,OAAO;OACP,QAAQ;OACR,QAAQ;OACR,YAAY;OACZ,YAAY;OACb;MACD,eAAc,MAAK;AACjB,SAAE,cAAc,MAAM,QAAQ;;MAEhC,eAAc,MAAK;AACjB,SAAE,cAAc,MAAM,QAAQ;;gBAEjC;OAEQ,EACT,qBAAC;MAAI,OAAO;OAAE,SAAS;OAAQ,KAAK;OAAW;iBAC7C,oBAAC;OAAO,SAAS;OAAc,SAAQ;iBAAU;QAExC,EACT,oBAAC,OAAO;OAAM;iBACZ,oBAAC;QAAO,UAAU,CAAC,WAAW;kBAC3B,YAAY,cAAc;SACpB;QACI;OACX;MACF;;IACS,IACH;GACJ;;AAIlB,2BAAe;;;;ACnlCf,MAAMC,uBAA2B;AAC/B,QACE,4CACE,qBAAC;EAAE,UAAS;aACV,oBAAC;GAAK,OAAM;GAAM,QAAO;GAAM,IAAG;GAAU,MAAK;IAAY,EAC7D,oBAAC;GAAE,UAAS;aACV,qBAAC;IAAE,OAAO,EAAE,cAAc,gBAAgB;eACxC,oBAAC;KACC,IAAG;KACH,OAAO,EAAE,UAAU,SAAS;KAC5B,WAAU;KACV,GAAE;KACF,GAAE;KACF,OAAM;KACN,QAAO;eAEP,oBAAC;MACC,GAAE;MACF,GAAE;MACF,OAAM;MACN,QAAO;MACP,MAAK;OACL;MACG,EACP,qBAAC;KAAE,MAAK;gBACN,qBAAC;MAAE,SAAQ;;OACT,qBAAC;QAAE,UAAS;mBACV,oBAAC;SACC,GAAE;SACF,QAAO;SACP,aAAY;SACZ,kBAAiB;SACjB,eAAc;UACd,EACF,oBAAC;SACC,GAAE;SACF,QAAO;SACP,aAAY;SACZ,kBAAiB;SACjB,eAAc;UACd;SACA;OACJ,qBAAC;QAAE,UAAS;mBACV,oBAAC;SACC,GAAE;SACF,QAAO;SACP,aAAY;SACZ,kBAAiB;SACjB,eAAc;UACd,EACF,oBAAC;SACC,GAAE;SACF,QAAO;SACP,aAAY;SACZ,kBAAiB;SACjB,eAAc;UACd;SACA;OACJ,oBAAC;QAAE,UAAS;kBACV,oBAAC;SACC,GAAE;SACF,QAAO;SACP,aAAY;SACZ,kBAAiB;SACjB,eAAc;UACd;SACA;OACJ,oBAAC;QAAE,UAAS;kBACV,oBAAC;SACC,GAAE;SACF,QAAO;SACP,aAAY;SACZ,kBAAiB;SACjB,eAAc;UACd;SACA;OACJ,qBAAC;QAAE,UAAS;mBACV,oBAAC;SACC,GAAE;SACF,QAAO;SACP,aAAY;SACZ,kBAAiB;SACjB,eAAc;UACd,EACF,oBAAC;SACC,GAAE;SACF,QAAO;SACP,aAAY;SACZ,kBAAiB;SACjB,eAAc;UACd;SACA;OACJ,oBAAC;QAAE,UAAS;kBACV,oBAAC;SACC,GAAE;SACF,QAAO;SACP,aAAY;SACZ,kBAAiB;SACjB,eAAc;UACd;SACA;OACJ,qBAAC;QAAE,UAAS;mBACV,oBAAC;SACC,GAAE;SACF,QAAO;SACP,aAAY;SACZ,kBAAiB;SACjB,eAAc;UACd,EACF,oBAAC;SACC,GAAE;SACF,QAAO;SACP,aAAY;SACZ,kBAAiB;SACjB,eAAc;UACd;SACA;;OACF,EACJ,qBAAC;MAAE,SAAQ;;OACT,oBAAC;QAAE,UAAS;kBACV,oBAAC;SACC,GAAE;SACF,QAAO;SACP,aAAY;SACZ,kBAAiB;SACjB,eAAc;UACd;SACA;OACJ,oBAAC;QAAE,UAAS;kBACV,oBAAC;SACC,GAAE;SACF,QAAO;SACP,aAAY;SACZ,kBAAiB;SACjB,eAAc;UACd;SACA;OACJ,qBAAC;QAAE,UAAS;mBACV,oBAAC;SACC,GAAE;SACF,QAAO;SACP,aAAY;SACZ,kBAAiB;SACjB,eAAc;UACd,EACF,oBAAC;SACC,GAAE;SACF,QAAO;SACP,aAAY;SACZ,kBAAiB;SACjB,eAAc;UACd;SACA;OACJ,qBAAC;QAAE,UAAS;mBACV,oBAAC;SACC,GAAE;SACF,QAAO;SACP,aAAY;SACZ,kBAAiB;SACjB,eAAc;UACd,EACF,oBAAC;SACC,GAAE;SACF,QAAO;SACP,aAAY;SACZ,kBAAiB;SACjB,eAAc;UACd;SACA;;OACF;MACF;KACF;IACF;GACF,EACJ,oBAAC;EACC,GAAE;EACF,GAAE;EACF,OAAM;EACN,QAAO;EACP,IAAG;EACH,QAAO;EACP,aAAY;GACZ,IACD;;AAKP,MAAMC,kBAAsB;AAC1B,QACE;EACE,qBAAC;GAAE,UAAS;cACV,oBAAC;IACC,UAAS;IACT,UAAS;IACT,GAAE;IACF,MAAK;KACL,EACF,oBAAC;IACC,UAAS;IACT,UAAS;IACT,GAAE;IACF,MAAK;KACL;IACA;EACJ,oBAAC;GACC,GAAE;GACF,GAAE;GACF,OAAM;GACN,QAAO;GACP,IAAG;GACH,MAAK;IACL;EACF,oBAAC;GACC,UAAS;GACT,UAAS;GACT,GAAE;GACF,MAAK;IACL;KACD;;AAIP,MAAMC,iBAAyC,EAAE,gBAAgB;AAC/D,QACE,qBAAC;EACC,SAAQ;EACR,MAAK;EACL,OAAM;EACN,MAAK;EACL,cAAW;EACA;;GAGX,oBAAC,mBAAiB;GAGlB,oBAAC,cAAY;GAGb,qBAAC;IACC,qBAAC;KAAe,IAAG;KAAW,IAAG;KAAK,IAAG;KAAK,IAAG;KAAO,IAAG;;MACzD,oBAAC;OAAK,QAAO;OAAK,WAAU;QAAY;MACxC,oBAAC;OAAK,QAAO;OAAM,WAAU;QAAY;MACzC,oBAAC;OAAK,QAAO;OAAO,WAAU;QAAY;;MAC3B;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;gBAEd,oBAAC,UAAK,WAAU,UAAU,EAC1B,oBAAC;MAAK,QAAO;MAAI,WAAU;MAAQ,aAAY;OAAM;MACtC;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;;MAEd,oBAAC,UAAK,WAAU,YAAY;MAC5B,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAI,WAAU;QAAY;;MACxB;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;;MAEd,oBAAC,UAAK,WAAU,YAAY;MAC5B,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAI,WAAU;QAAY;;MACxB;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;;MAEd,oBAAC,UAAK,WAAU,YAAY;MAC5B,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAI,WAAU;QAAY;;MACxB;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;;MAEd,oBAAC,UAAK,WAAU,YAAY;MAC5B,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAI,WAAU;QAAY;;MACxB;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;;MAEd,oBAAC,UAAK,WAAU,YAAY;MAC5B,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAI,WAAU;QAAY;;MACxB;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;;MAEd,oBAAC,UAAK,WAAU,YAAY;MAC5B,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAI,WAAU;QAAY;;MACxB;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;;MAEd,oBAAC,UAAK,WAAU,YAAY;MAC5B,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAI,WAAU;QAAY;;MACxB;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;;MAEd,oBAAC,UAAK,WAAU,YAAY;MAC5B,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAI,WAAU;QAAY;;MACxB;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;;MAEd,oBAAC,UAAK,WAAU,YAAY;MAC5B,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAI,WAAU;QAAY;;MACxB;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;;MAEd,oBAAC,UAAK,WAAU,YAAY;MAC5B,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAI,WAAU;QAAY;;MACxB;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;;MAEd,oBAAC,UAAK,WAAU,YAAY;MAC5B,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAI,WAAU;QAAY;;MACxB;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;;MAEd,oBAAC,UAAK,WAAU,YAAY;MAC5B,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAI,WAAU;QAAY;;MACxB;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;;MAEd,oBAAC,UAAK,WAAU,YAAY;MAC5B,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAI,WAAU;QAAY;;MACxB;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;;MAEd,oBAAC,UAAK,WAAU,YAAY;MAC5B,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAI,WAAU;QAAY;;MACxB;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;;MAEd,oBAAC,UAAK,WAAU,YAAY;MAC5B,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAI,WAAU;QAAY;;MACxB;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;;MAEd,oBAAC,UAAK,WAAU,YAAY;MAC5B,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAI,WAAU;QAAY;;MACxB;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;;MAEd,oBAAC,UAAK,WAAU,YAAY;MAC5B,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAW,WAAU;QAAY;MAC9C,oBAAC;OAAK,QAAO;OAAI,WAAU;QAAY;;MACxB;IACjB,qBAAC;KACC,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,IAAG;KACH,eAAc;gBAEd,oBAAC,UAAK,WAAU,YAAY,EAC5B,oBAAC;MAAK,QAAO;MAAI,WAAU;OAAY;MACxB;IACjB,oBAAC;KAAS,IAAG;eACX,oBAAC;MAAK,OAAM;MAAM,QAAO;MAAM,IAAG;MAAU,MAAK;OAAU;MAClD;IACX,oBAAC;KAAS,IAAG;eACX,oBAAC;MAAK,OAAM;MAAM,QAAO;MAAM,MAAK;OAAU;MACrC;IACX,oBAAC;KAAS,IAAG;eACX,oBAAC;MACC,OAAM;MACN,QAAO;MACP,MAAK;MACL,WAAU;OACV;MACO;IACX,oBAAC;KAAS,IAAG;eACX,oBAAC;MACC,OAAM;MACN,QAAO;MACP,MAAK;MACL,WAAU;OACV;MACO;IACX,oBAAC;KAAS,IAAG;eACX,oBAAC;MACC,OAAM;MACN,QAAO;MACP,MAAK;MACL,WAAU;OACV;MACO;IACX,oBAAC;KAAS,IAAG;eACX,oBAAC;MACC,OAAM;MACN,QAAO;MACP,MAAK;MACL,WAAU;OACV;MACO;IACX,oBAAC;KAAS,IAAG;eACX,oBAAC;MACC,OAAM;MACN,QAAO;MACP,MAAK;MACL,WAAU;OACV;MACO;IACX,oBAAC;KAAS,IAAG;eACX,oBAAC;MACC,OAAM;MACN,QAAO;MACP,MAAK;MACL,WAAU;OACV;MACO;IACX,oBAAC;KAAS,IAAG;eACX,oBAAC;MACC,OAAM;MACN,QAAO;MACP,MAAK;MACL,WAAU;OACV;MACO;IACX,oBAAC;KAAS,IAAG;eACX,oBAAC;MACC,OAAM;MACN,QAAO;MACP,MAAK;MACL,WAAU;OACV;MACO;IACX,oBAAC;KAAS,IAAG;eACX,oBAAC;MACC,OAAM;MACN,QAAO;MACP,MAAK;MACL,WAAU;OACV;MACO;IACX,oBAAC;KAAS,IAAG;eACX,oBAAC;MACC,OAAM;MACN,QAAO;MACP,MAAK;MACL,WAAU;OACV;MACO;IACX,oBAAC;KAAS,IAAG;eACX,oBAAC;MACC,OAAM;MACN,QAAO;MACP,MAAK;MACL,WAAU;OACV;MACO;IACX,oBAAC;KAAS,IAAG;eACX,oBAAC;MACC,OAAM;MACN,QAAO;MACP,MAAK;MACL,WAAU;OACV;MACO;OACN;;GACH;;AAIV,4BAAe;;;;;;;;;;;;;;;;;;;;;;;;AE/jBf,MAAaC,uBAAqD,EAChE,QACA,SACA,cACA,gBACA,SAAS,EAAE,WAAW,aAAa,eACnC,2BACA,oBACI;CACJ,MAAM,EACJ,YACA,eACA,aACA,aACA,eACA,YACA,gBACA,OACA,gBACA,UACA,eACA,kBACA,uBACA,kBACA,qBACA,gBACA,gBACA,cACA,gBAAgB,wBAChB,UACE,qBAAqB;EACvB;EACA,SAAS;GAAE;GAAW;GAAa;GAAa;EAChD;EACA;EACD,CAAC;CAGF,MAAM,YADU,UAAU,YACI;CAE9B,MAAM,iBAAiB,YAAY;AAEjC,MADgB,MAAM,wBAAwB,EACjC;AACX,OAAI,aACF,eAAc;AAEhB,gBAAa;;;CAIjB,MAAM,oBAAoB;AACxB,SAAO;AACP,WAAS;;AAGX,KAAI,CAAC,eACH,QAAO;AAGT,QACE,oBAAC,OAAO;EAAK,MAAM;EAAQ,eAAc,SAAQ,CAAC,QAAQ,aAAa;YACrE,qBAAC,OAAO,qBACN,oBAAC,OAAO;GACN,WAAWC;GACX,OAAO;IACL,QAAQ;IACR,iBAAiB;IAClB;IACD,EACF,qBAAC,OAAO;GACN,WAAWC;GACX,OAAO;IAAE,UAAU;IAAS,QAAQ;IAAI;;KAGtC,iBAAiB,eACjB,oBAAC;KACC,OAAO;MACL,UAAU;MACV,OAAO;MACP,iBAAiB;MACjB,gBAAgB;MAChB,SAAS;MACT,YAAY;MACZ,gBAAgB;MAChB,QAAQ;MACR,cAAc;MACf;eAED,qBAAC;MACC,OAAO;OACL,SAAS;OACT,eAAe;OACf,YAAY;OACZ,KAAK;OACN;iBAED,oBAAC,WACC,OAAO;OACL,OAAO;OACP,QAAQ;OACR,WAAW;OACX,OAAO;OACR,GACD,EACF,oBAAC;OAAE,OAAO;QAAE,UAAU;QAAY,OAAO;QAAS;iBAC/C,aACG,4BACA;QACF;OACA;MACF;IAIR,qBAAC;KAAI,WAAWC;;MACd,oBAAC,OAAO;OAAM,WAAWC;iBAAc;QAExB;MACf,oBAAC,OAAO;OAAY,WAAWC;iBAAoB;QAE9B;MACrB,oBAAC,OAAO;OAAM;iBACZ,oBAAC;QACC,MAAK;QACL,SAAS;QACT,UAAU;QACV,OAAO;SACL,UAAU;SACV,OAAO;SACP,KAAK;SACL,SAAS;SACT,cAAc;SACd,QAAQ;SACR,YAAY;SACZ,QAAQ;SACR,SAAS;SACT,YAAY;SACZ,gBAAgB;SACjB;kBAED,oBAAC,KAAE,OAAO;SAAE,OAAO;SAAQ,QAAQ;SAAQ,GAAI;SACxC;QACI;;MACX;IAGN,qBAAC;KAAI,WAAWC;;MAEd,qBAAC;OAAI,OAAO,EAAE,cAAc,QAAQ;kBAClC,oBAAC;QACC,SAAQ;QACR,OAAO;SACL,SAAS;SACT,UAAU;SACV,YAAY;SACZ,cAAc;SACf;kBACF;SAEO,EACR,qBAAC;QAAI,OAAO;SAAE,SAAS;SAAQ,KAAK;SAAU;mBAC5C,qBAAC;SAAI,OAAO;UAAE,UAAU;UAAY,MAAM;UAAG;oBAC3C,oBAAC;UACC,IAAG;UACH,MAAK;UACL,OAAO;UACP,WAAU,MAAK;AACb,yBAAc,EAAE,OAAO,MAAM;;UAE/B,YAAW,MAAK;AACd,eAAI,EAAE,QAAQ,WAAW,eACvB,eAAc;;UAGlB,aAAY;UACZ,UAAU,eAAe;UACzB,OAAO,EAAE,cAAc,QAAQ;WAC/B,EACF,oBAAC;UACC,OAAO;WACL,UAAU;WACV,OAAO;WACP,KAAK;WACL,WAAW;WACX,UAAU;WACV,OAAO;WACP,eAAe;WAChB;oBACF;WAEM;UACH,EACN,oBAAC;SACC,SAAS;SACT,UAAU,eAAe,iBAAiB,CAAC;SAC3C,MAAK;mBAEJ,cACC,oBAAC,WACC,OAAO;UACL,OAAO;UACP,QAAQ;UACR,WAAW;UACZ,GACD,GAEF,oBAAC,UAAO,OAAO;UAAE,OAAO;UAAQ,QAAQ;UAAQ,GAAI;UAE/C;SACL;QACF;MAGL,gBAAgB,QACf,qBAAC;OACC,OAAO;QACL,SAAS;QACT,YAAY;QACZ,KAAK;QACL,SAAS;QACT,cAAc;QACd,QAAQ,aACN,cACI,2BACA;QAEN,iBAAiB,cACb,2BACA;QACJ,OAAO,cAAc,qBAAqB;QAC1C,cAAc;QACf;kBAED,oBAAC,gBACC,OAAO;QACL,OAAO;QACP,QAAQ;QACR,YAAY;QACb,GACD,EACF,oBAAC;QAAI,OAAO;SAAE,MAAM;SAAG,UAAU;SAAG;kBAClC,oBAAC;SAAE,OAAO;UAAE,UAAU;UAAY,YAAY;UAAK;mBAChD,cACG,GAAG,SAAS,kBACZ,GAAG,SAAS;UACd;SACA;QACF;MAIP,eACC,qBAAC;OAAI,OAAO,EAAE,cAAc,QAAQ;kBAClC,oBAAC;QACC,SAAQ;QACR,OAAO;SACL,SAAS;SACT,UAAU;SACV,YAAY;SACZ,cAAc;SACf;kBACF;SAEO,EACR,oBAAC;QACC,OAAO;SACL,SAAS;SACT,KAAK;SACL,UAAU;SACX;kBAEA;SAAC;SAAG;SAAG;SAAG;SAAG;SAAE,CAAC,KAAI,SACnB,qBAAC;SAEC,MAAK;SACL,eAAe,iBAAiB,KAAK;SACrC,UAAU,iBAAiB;SAC3B,OAAO;UACL,SAAS;UACT,cAAc;UACd,QAAQ,aACN,kBAAkB,OACd,4BACA;UAEN,iBACE,kBAAkB,OACd,4BACA;UACN,OACE,kBAAkB,OACd,qBACA;UACN,YAAY,kBAAkB,OAAO,MAAM;UAC3C,QACE,iBAAiB,aACb,gBACA;UACN,UAAU;UACV,YAAY;UACZ,SAAS,iBAAiB,aAAa,KAAM;UAC9C;;UAEA;UAAK;UAAE,SAAS,IAAI,SAAS;;WA9BzB,KA+BE,CACT;SACE;QACF;MAIP,gBAAgB,yBAAyB,mBACxC,qBAAC;OACC,OAAO;QACL,SAAS;QACT,cAAc;QACd,iBAAiB;QACjB,QAAQ;QACR,cAAc;QACf;kBAED,oBAAC;QACC,OAAO;SACL,UAAU;SACV,YAAY;SACZ,cAAc;SACd,OAAO;SACR;kBACF;SAEI,EACL,qBAAC;QACC,OAAO;SACL,SAAS;SACT,eAAe;SACf,KAAK;SACN;;SAED,qBAAC;UACC,OAAO;WACL,SAAS;WACT,gBAAgB;WAChB,YAAY;WACb;qBAED,oBAAC;WACC,OAAO;YACL,UAAU;YACV,OAAO;YACR;qBACF;YAEM,EACP,qBAAC;WACC,OAAO;YACL,SAAS;YACT,eAAe;YACf,YAAY;YACZ,KAAK;YACN;sBAED,oBAAC;YACC,OAAO;aACL,UAAU;aACV,YAAY;aACZ,OAAO;aACR;sBAEA,yBAAyB;aACrB,EACN,aAAa,oBACZ,qBAAC;YACC,OAAO;aACL,UAAU;aACV,OAAO;aACP,SAAS;aACV;;aACF;aACG;aAAiB;;aACd;YAEL;WACF;SACN,qBAAC;UACC,OAAO;WACL,SAAS;WACT,gBAAgB;WAChB,YAAY;WACb;qBAED,oBAAC;WACC,OAAO;YACL,UAAU;YACV,OAAO;YACR;qBACF;YAEM,EACP,oBAAC;WACC,OAAO;YACL,UAAU;YACV,YAAY;YACZ,OAAO;YACR;qBAEA;YACI;WACH;SACN,oBAAC,SACC,OAAO;UACL,QAAQ;UACR,iBAAiB;UACjB,QAAQ;UACT,GACD;SACF,qBAAC;UACC,OAAO;WACL,SAAS;WACT,gBAAgB;WAChB,YAAY;WACb;qBAED,oBAAC;WACC,OAAO;YACL,UAAU;YACV,YAAY;YACZ,OAAO;YACR;qBACF;YAEM,EACP,qBAAC;WACC,OAAO;YACL,SAAS;YACT,eAAe;YACf,YAAY;YACZ,KAAK;YACN;sBAED,oBAAC;YACC,OAAO;aACL,UAAU;aACV,YAAY;aACZ,OAAO;aACR;sBAEA,uBAAuB;aACnB,EACN,aAAa,kBACZ,qBAAC;YACC,OAAO;aACL,UAAU;aACV,OAAO;aACP,SAAS;aACV;;aACF;aACG;aAAe;;aACZ;YAEL;WACF;SACL,kBACC,oBAAC;UACC,OAAO;WACL,WAAW;WACX,YAAY;WACZ,WAAW;WACZ;oBAED,qBAAC;WACC,OAAO;YACL,SAAS;YACT,gBAAgB;YAChB,YA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"}
|