@powerhousedao/design-system 6.2.0-dev.10 → 6.2.0-dev.12
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/{command-DFzB66Ou.d.ts → command-CSpijG6c.d.ts} +4 -4
- package/dist/{command-DFzB66Ou.d.ts.map → command-CSpijG6c.d.ts.map} +1 -1
- package/dist/connect/index.d.ts +9 -1
- package/dist/connect/index.d.ts.map +1 -1
- package/dist/connect/index.js +80 -57
- package/dist/connect/index.js.map +1 -1
- package/dist/{enum-field-UxIet5Lp.d.ts → enum-field-tdsq3ox_.d.ts} +2 -2
- package/dist/{enum-field-UxIet5Lp.d.ts.map → enum-field-tdsq3ox_.d.ts.map} +1 -1
- package/dist/{radio-group-field-wlqeiLN3.d.ts → radio-group-field-JewKPpm4.d.ts} +2 -2
- package/dist/{radio-group-field-wlqeiLN3.d.ts.map → radio-group-field-JewKPpm4.d.ts.map} +1 -1
- package/dist/ui/components/command/command.d.ts +1 -1
- package/dist/ui/components/enum-field/enum-field.d.ts +1 -1
- package/dist/ui/components/index.d.ts +3 -3
- package/dist/ui/components/radio-group-field/radio-group-field.d.ts +1 -1
- package/dist/ui/index.d.ts +3 -3
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["Popover","PopoverContent","PopoverTrigger","AccountPopover","children","content","ConnectLoaderVideo","getDimensions","AnimatedLoader","props","style","size","delegatedProps","dimensions","_style","objectFit","pointerEvents","width","replace","height","useLayoutEffect","useRef","useState","twMerge","useEventListener","useOnClickOutside","NodeInput","props","onSubmit","onCancel","defaultValue","className","minLength","inputProps","value","setValue","ref","handleSubmit","length","e","key","setTimeout","current","focus","select","scroll","left","target","Icon","addFolder","setSelectedDrive","setSelectedNode","useDragNode","useDropNode","useSelectedDriveId","useSelectedDriveSafe","useSelectedNodePath","useUserPermissions","Fragment","useState","twMerge","NodeInput","Breadcrumbs","isAllowedToCreateDocuments","selectedDrive","selectedDriveId","selectedNodePath","isCreating","setIsCreating","onAddNew","onSubmit","name","at","id","then","node","catch","error","console","finally","onCancel","hasSelectedDrive","hasNodePath","length","undefined","state","global","header","map","parentFolder","Breadcrumb","props","parentId","onClick","isDragging","dragProps","srcId","isDropTarget","dropProps","containerStyles","Icon","useTheme","Select","components","DropdownIndicator","props","ClearIndicator","MenuList","label","onClick","rest","hasAddItemButton","children","Combobox","invalid","addItemButtonProps","theme","dark","menuListProps","menuList","dropdownIndicator","display","transition","color","padding","boxSizing","clearIndicator","baseStyles","container","borderColor","fontSize","placeholder","control","alignItems","cursor","flexWrap","justifyContent","minHeight","outline","position","backgroundColor","borderStyle","borderWidth","borderRadius","option","state","isSelected","colors","primary","primary25","primary50","primary75","danger","dangerLight","neutral0","neutral5","neutral10","neutral20","neutral30","neutral40","neutral50","neutral60","neutral70","neutral80","neutral90","PowerhouseButton","twMerge","useState","CookieBanner","props","children","cookies","submitLabel","rejectLabel","onSubmit","onReject","className","divProps","cookiesValue","setCookiesValue","handleOnChange","event","id","checked","target","prevState","map","cookie","value","buttonStyles","i","label","twMerge","defaultStyle","ModalButton","props","variant","className","rest","confirmStyle","cancelStyle","variantStyle","Modal","ModalButton","ConnectConfirmationModal","props","open","onOpenChange","header","body","cancelLabel","continueLabel","onCancel","onContinue","continueDisabled","overlayProps","contentProps","Icon","useState","twMerge","INDENT_PX","TreeItem","label","depth","expanded","selected","hasChildren","icon","onToggle","onClick","children","handleChevronClick","e","stopPropagation","paddingLeft","ColumnItem","column","typeLabel","dataType","length","slice","name","SchemaTreeSidebar","schema","tables","selectedTable","onSelectTable","onRefresh","loading","expandedNodes","setExpandedNodes","toggleNode","nodeId","prev","handleTableClick","tableName","isSchemaExpanded","handleRefreshClick","undefined","map","table","isTableExpanded","isSelected","columns","col","Icon","forwardRef","useState","twJoin","twMerge","fixedForwardRef","render","ConnectSelect","Select","props","ref","items","value","id","onChange","containerClassName","menuClassName","itemClassName","absolutePositionMenu","borderRadius","showItems","setShowItems","selectedItem","getItemByValue","onItemClick","item","disabled","find","itemsToShow","filter","map","ItemContainer","className","icon","displayValue","description","toLowerCase","Icon","useCallback","useMemo","useState","twMerge","ConnectSelect","getAvailableOperators","column","baseOperators","dataType","toLowerCase","includes","getInputType","operator","FilterClauseComponent","clause","columns","onUpdate","onRemove","showConnector","connector","onConnectorChange","find","c","name","availableOperators","inputType","showValueInput","columnItems","map","col","value","displayValue","operatorItems","op","connectorItems","handleColumnChange","columnName","newColumn","newAvailableOperators","newOperator","handleOperatorChange","handleValueChange","id","e","target","FilterBar","filters","onFiltersChange","isExpanded","setIsExpanded","handleAddFilter","newClause","Date","now","Math","random","clauses","connectors","length","handleUpdateClause","index","newClauses","handleRemoveClause","filter","_","i","newConnectors","undefined","handleConnectorChange","hasFilters","updatedClause","Icon","useState","twMerge","FilterBar","formatCellValue","value","undefined","JSON","stringify","toString","String","escapeCsvValue","includes","replace","rowToCsv","row","columns","map","column","name","join","rowsToCsv","rows","header","col","dataRows","copyToClipboard","text","navigator","clipboard","writeText","SortIcon","direction","active","TableView","pagination","onPageChange","onSort","currentSort","loading","filters","onFiltersChange","onCopyAll","offset","limit","total","currentPage","Math","floor","totalPages","ceil","startItem","endItem","min","length","goToPage","page","handleSort","columnName","newDirection","getVisiblePages","maxVisible","Array","from","_","i","start","max","end","pages","push","visiblePages","copying","setCopying","copiedRowIndex","setCopiedRowIndex","handleCopyAll","csv","setTimeout","err","console","error","handleCopyRow","rowIndex","toLocaleString","index","isActive","sortDirection","colIndex","useCallback","useEffect","useRef","useState","ConnectConfirmationModal","SchemaTreeSidebar","TableView","rowsToCsv","DEFAULT_PAGE_SIZE","DBExplorer","schema","getTables","getTableRows","getDefaultSort","pageSize","onImportDb","onExportDb","pgVersionControl","fileInputRef","tables","setTables","tablesLoading","setTablesLoading","selectedTable","setSelectedTable","tableData","setTableData","pagination","setPagination","offset","limit","total","sort","setSort","filters","setFilters","loading","setLoading","pendingImport","setPendingImport","pendingResetMajor","setPendingResetMajor","resetting","setResetting","columns","find","t","name","loadTableData","data","prev","handleCopyAll","rows","loadTables","handleRefresh","newTables","some","undefined","handleSelectTable","table","handlePageChange","handleSort","newSort","handleImportClick","current","click","handleFileChange","e","file","target","files","text","then","content","value","handleImportConfirm","handleImportCancel","handleExportClick","resetTargetMajor","supportedPgVersions","m","currentPgVersion","handleResetConfirm","onResetToPgVersion","open","newFilters","useState","DebugInspector","supportedPgVersions","currentPgVersion","onResetToPgVersion","status","setStatus","pendingMajor","setPendingMajor","confirmMajor","setConfirmMajor","error","setError","handleReset","major","err","Error","message","String","running","map","isPending","useEffect","useRef","twMerge","SEQUENCE","id","dropDelay","fallDelay","ANIM_DUR","HOLD","LAST_DROP","LAST_FALL","LOOP_TOTAL","DROP_STYLE","FALL_STYLE","PATHS","b1","b2","b3","b4","b5","b6","b7","b8","b9","b10","LogoAnimation","size","className","refsMap","timers","getEls","current","clearTimers","forEach","clearTimeout","schedule","fn","delay","push","setTimeout","resetAll","Object","values","flat","el","style","animation","opacity","runDrop","runFall","startLoop","fallStart","refFor","includes","map","LogoAnimation","DefaultEditorLoader","props","message","divProps","Icon","twJoin","twMerge","Disclosure","props","title","isOpen","onOpenChange","children","containerClassName","toggleClassName","contentClassName","twMerge","Divider","props","className","TabContent","props","label","_label","children","Content","List","Root","Trigger","React","Tabs","children","defaultValue","Children","map","child","_i","isValidElement","label","disabled","props","i","JsonViewer","useMemo","twMerge","TabContent","Tabs","formatScopeLabel","text","charAt","toUpperCase","slice","toLowerCase","DocumentStateViewer","state","ignoredScopes","defaultScope","className","scopes","Object","keys","filter","scope","includes","initialScope","at","length","map","Content","Portal","Provider","Root","Trigger","twMerge","ConnectTooltip","props","children","content","open","defaultOpen","onOpenChange","className","side","sideOffset","delayDuration","rest","ConnectTooltipProvider","Icon","formatDistanceToNow","useEffect","useState","twMerge","ConnectTooltip","HDivider","props","className","timestampUtcMs","timestamp","title","subtitle","onClick","isSelected","open","setOpen","hasContent","setTimeout","formatTimestamp","isoString","Date","addSuffix","tooltipContent","handleMouseEnter","handleMouseLeave","Icon","format","parseISO","useState","twMerge","ConnectTooltip","getBarHeight","size","formatTimestamp","isoString","date","TimelineBar","onClick","className","timestampUtcMs","timestamp","additions","deletions","addSize","delSize","isSelected","open","setOpen","noChanges","addBarHeight","delBarHeight","tooltipContent","handleMouseEnter","handleMouseLeave","useCallback","useEffect","useMemo","useRef","useState","ConnectTooltipProvider","HDivider","TimelineBar","defaultTimeLineItem","id","type","addSize","delSize","DocumentTimeline","props","timeline","onItemClick","selectedItem","setSelectedItem","scrollContainerRef","handleClick","item","mergedTimelineItems","unselectedItems","selectedItems","indexSelected","findIndex","slice","renderTimelineItems","items","map","timestampUtcMs","title","subtitle","additions","deletions","unselectedContent","selectedContent","current","scrollLeft","scrollWidth","twMerge","ToolbarContainer","props","children","className","rest","ToolbarControlsContainer","useDocumentById","redo","undo","defaultTo","filter","hasAtLeast","isTruthy","merge","pipe","prop","values","hasRevisions","document","useUndo","documentId","dispatch","canUndo","useRedo","canRedo","clipboard","useDocumentUndoRedo","undoProps","redoProps","setSelectedNode","showRevisionHistory","useDownloadDocument","useGetSwitchboardLink","useNodeParentFolderById","isDefined","twMerge","Icon","useRedo","useUndo","ToolbarButton","props","className","children","disabled","rest","ToolbarUndoButton","onClick","onClickOverride","document","undo","canUndo","header","id","makeOnClick","ToolbarRedoButton","redo","canRedo","ToolbarDownloadButton","downloadDocument","ToolbarSwitchboardButton","getSwitchboardLink","then","url","window","open","catch","error","console","ToolbarHistoryButton","ToolbarCloseButton","parentFolder","defaultOnClick","twMerge","NodeInput","ToolbarInput","props","defaultValue","className","onSubmit","onCancel","ariaLabel","useNodeActions","useNodeById","useState","twMerge","ToolbarInput","ToolbarName","props","document","inputClassName","titleClassName","isEditing","setIsEditing","node","header","id","onRenameNode","onRenameDriveNodes","documentName","name","documentId","activateEditing","cancelEditing","onSubmit","newName","Promise","all","catch","console","error","keys","ToolbarCloseButton","ToolbarDownloadButton","ToolbarHistoryButton","ToolbarRedoButton","ToolbarSwitchboardButton","ToolbarUndoButton","ToolbarName","defaultControlSlots","first","second","third","controlSlots","documentToolbarControls","defaultControlComponents","undo","redo","download","name","switchboard","history","close","defaultTo","filter","hasAtLeast","isArray","isDefined","isIncludedIn","map","pipe","prop","defaultControlComponents","defaultControlSlots","documentToolbarControls","makeIsEnabledChecker","args","enabledControls","disabledControls","control","makeToolbarControlsRenderer","document","componentOverrides","checkIsEnabled","renderComponent","Component","slot","isControlInPosition","position","makeCustomControlsRenderer","customControls","pos","controlOrControlList","renderCustomControlList","renderCustomControl","component","controls","controlsInPosition","key","useSelectedDocumentSafe","map","controlSlots","ToolbarContainer","ToolbarControlsContainer","makeCustomControlsRenderer","makeToolbarControlsRenderer","DocumentToolbar","props","selectedDocument","toolbarClassName","document","toolbarContainer","Container","children","slot","ControlsContainerSlot","controlsContainerClassName","enabledControls","disabledControls","componentOverrides","customControls","controlsContainer","ControlsContainer","renderToolbarControls","renderCustomControls","Icon","Modal","ModalButton","ConnectReplaceDuplicateModal","props","open","onOpenChange","title","fileName","message","duplicateLabel","onDuplicate","overlayProps","contentProps","defaultMessage","UploadFileItemErrorDetails","props","status","errorDetails","Icon","getDocumentIcon","documentType","UploadFileItemHeader","props","fileName","fileSize","onClose","delegatedProps","UploadFileItemProgressBar","props","status","progress","clamped","Math","min","max","width","twMerge","getStatusText","status","getStatusColor","shouldShowCTA","onOpenDocument","onFindResolution","Boolean","getCTAText","UploadFileItemStatusRow","props","progress","handleCTAClick","Math","round","forwardRef","twMerge","UploadFileItemErrorDetails","UploadFileItemHeader","UploadFileItemProgressBar","UploadFileItemStatusRow","UploadFileItem","props","ref","fileName","fileSize","status","documentType","progress","errorDetails","onClose","onOpenDocument","onFindResolution","className","delegatedProps","getUploadListTitle","count","explicitTitle","Icon","useMemo","useState","twMerge","UploadFileItem","getUploadListTitle","UploadFileList","props","items","title","defaultCollapsed","onClose","className","delegatedProps","isCollapsed","setIsCollapsed","computedTitle","length","v","map","item","idx","fileName","generateId","Date","now","Math","random","toString","substring","formatFileSize","bytes","k","sizes","i","floor","log","parseFloat","pow","toFixed","mapProgressStageToStatus","stage","mapUploadsToFileItems","uploadsArray","removeUpload","setSelectedNodeFn","onConflictResolution","filter","upload","undefined","map","fileName","fileSize","status","progress","errorDetails","documentType","onClose","id","onOpenDocument","fileNode","console","error","onFindResolution","twMerge","UploadFileList","mapUploadsToFileItems","UploadFileListContainer","props","uploadsArray","uploadsCount","removeUpload","clearAllUploads","setSelectedNode","onClose","onConflictResolution","className","delegatedProps","items","handleClose","useCallback","useEffect","useReducer","formatFileSize","generateId","mapProgressStageToStatus","uploadsReducer","state","action","type","payload","id","fileName","fileSize","status","progress","fileNode","undefined","currentUpload","stage","errorDetails","error","documentType","duplicateType","uploadToUpdate","failedUpload","removed","rest","conflictUpload","file","parentNode","filteredUploads","upload","Object","entries","useUploadTracker","useLocalStorage","driveId","getInitialState","stored","localStorage","getItem","parsed","JSON","parse","console","uploads","dispatch","setItem","stringify","createUploadHandler","onAddFile","parent","fileId","name","size","progressCallback","Error","message","removeUpload","uploadId","clearAllUploads","clearConflictedUploads","getUploadsArray","values","getUploadsCount","keys","length","resolveConflict","resolution","result","Promise","resolve","then","catch","uploadsArray","uploadsCount","Icon","setSelectedNode","useDropFile","useEffect","useState","twMerge","ConnectReplaceDuplicateModal","UploadFileListContainer","useUploadTracker","DropZone","props","title","subtitle","node","_node","enable","children","onAddFile","useLocalStorage","driveId","acceptedFileExtensions","_acceptedFileExtensions","className","delegatedProps","modalOpen","setModalOpen","conflictUploadId","setConflictUploadId","uploadsArray","uploadsCount","createUploadHandler","clearAllUploads","clearConflictedUploads","removeUpload","resolveConflict","handleAddFile","handleConflictResolution","uploadId","handleDuplicate","handleModalClose","isDropTarget","dropProps","find","u","id","fileName","undefined","useIsDragAndDropEnabled","useOnDropFile","useSelectedDriveId","DropZone","DropZoneWrapper","children","props","isDragAndDropEnabled","selectedDriveId","onDropFile","onAddFile","file","parent","onProgress","resolveConflict","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","twMerge","ConnectDropdownMenu","props","children","items","open","onItemClick","onOpenChange","menuClassName","map","id","label","icon","className","e","stopPropagation","Icon","EditorActionButtons","props","onSwitchboardLinkClick","onDownloadDocument","_onDownloadDocument","onClose","onShowRevisionHistory","onShowTimeline","Icon","twMerge","EditorUndoRedoButtons","props","canUndo","canRedo","undo","redo","buttonStyles","ImgPowerhouse","ENSAvatar","props","avatarUrl","size","style","width","height","Icon","defaultDriveOptions","defaultNodeOptions","normalNodeOptions","debugNodeOptions","nodeOptions","sharingTypeOptions","value","icon","description","disabled","locationInfoByLocation","CLOUD","title","LOCAL","SWITCHBOARD","debugNodeOptionsMap","ADD_TRIGGER","label","REMOVE_TRIGGER","ADD_INVALID_TRIGGER","folderNodeDropdownOptions","DUPLICATE","RENAME","DELETE","className","fileNodeDropdownOptions","DOWNLOAD","SYNCING","SUCCESS","CONFLICT","MISSING","ERROR","INITIAL_SYNC","syncStatuses","Icon","twMerge","CONFLICT","ERROR","INITIAL_SYNC","MISSING","SUCCESS","SYNCING","syncIcons","SyncStatusIcon","props","syncStatus","className","overrideSyncIcons","iconProps","icons","syncStatusIcons","Icon","getSyncStatusSync","setSelectedNode","showDeleteNodeModal","useDownloadDocument","useDragNode","useNodeActions","useSelectedDriveSafe","useUserPermissions","useState","addProp","entries","map","pipe","twMerge","fileNodeDropdownOptions","ConnectDropdownMenu","NodeInput","SyncStatusIcon","getDriveSharingType","drive","isReadDrive","sharingType","_sharingType","state","local","__sharingType","toUpperCase","validTypes","includes","FileItem","props","fileNode","className","customDocumentIconSrc","mode","setMode","isDropdownMenuOpen","setIsDropdownMenuOpen","selectedDrive","isDragging","dragProps","srcId","id","parentId","parentFolder","undefined","isAllowedToCreateDocuments","onRenameNode","onRenameDriveNodes","onDuplicateNode","downloadDocument","isReadMode","syncStatus","dropdownMenuHandlers","DOWNLOAD","DUPLICATE","RENAME","DELETE","dropdownMenuOptions","option","onSubmit","name","Promise","all","catch","error","console","finally","onCancel","onDropdownMenuOptionClick","itemId","handler","icon","iconNode","SUCCESS","containerStyles","content","documentType","e","stopPropagation","DefaultFileIcon","Icon","setSelectedNode","showDeleteNodeModal","useDragNode","useDropNode","useNodeActions","useUserPermissions","useState","addProp","entries","map","pipe","twMerge","folderNodeDropdownOptions","ConnectDropdownMenu","NodeInput","FolderItem","props","folderNode","className","isAllowedToCreateDocuments","mode","setMode","isDropdownMenuOpen","setIsDropdownMenuOpen","isDragging","dragProps","srcId","id","parentId","parentFolder","isDropTarget","dropProps","onRenameNode","onRenameDriveNodes","onDuplicateNode","isReadMode","onCancel","onSubmit","name","Promise","all","catch","error","console","finally","dropdownMenuHandlers","DUPLICATE","RENAME","DELETE","dropdownMenuOptions","option","onDropdownMenuOptionClick","itemId","handler","content","containerStyles","undefined","e","stopPropagation","twMerge","FooterLink","props","as","Component","className","restProps","twMerge","Footer","children","className","props","forwardRef","twJoin","twMerge","FormInput","props","ref","icon","errorMessage","isDirty","containerClassName","inputClassName","errorMessageClassName","hideErrors","delegatedProps","type","isError","Icon","Controller","ConnectSelect","appToInputOption","app","value","id","displayValue","name","icon","description","AppFormInput","props","control","appOptions","delegatedProps","items","map","field","forwardRef","Toggle","props","ref","id","forwardRef","Toggle","AvailableOfflineToggle","props","ref","twMerge","Label","props","children","className","labelProps","Controller","ConnectSelect","sharingTypeOptions","SharingTypeFormInput","props","control","delegatedProps","field","PowerhouseButton","useForm","FormInput","AppFormInput","AvailableOfflineToggle","Label","SharingTypeFormInput","AddLocalDriveForm","props","register","handleSubmit","control","formState","errors","defaultValues","name","sharingType","availableOffline","id","appOptions","e","onSubmit","required","message","Icon","DriveName","props","driveName","twMerge","locationInfoByLocation","LocationInfo","props","location","className","divProps","locationInfo","icon","title","description","PowerhouseButton","useEffect","useState","useForm","useDebounceValue","Disclosure","Divider","FormInput","AvailableOfflineToggle","DriveName","LocationInfo","AddRemoteDriveForm","props","sharingType","requestPublicDrive","remoteDriveDetails","setPublicDriveDetails","showLocationSettings","setShowLocationSettings","isUrlValid","setIsUrlValid","hasConfirmedUrl","setHasConfirmedUrl","errorMessage","setErrorMessage","url","setUrl","debouncedUrl","setDebouncedUrl","register","handleSubmit","setValue","mode","defaultValues","availableOffline","fetchPublicDrive","catch","console","error","id","name","location","undefined","message","onSubmit","e","target","value","preventDefault","useTheme","JsonView","darkTheme","lightTheme","isStrictEqual","isString","Icon","FormattedJsonViewer","props","theme","style","onClick","children","rest","value","keyName","maxLength","length","maxWidth","toString","HomeBackgroundImage","src","mixBlendMode","Icon","twMerge","HomeScreenItem","props","icon","title","description","containerClassName","shareable","onClick","slice","toUpperCase","Icon","showPHModal","HomeScreenItem","HomeScreenAddDriveItem","props","containerClassName","type","twMerge","HomeBackgroundImage","HomeScreen","props","children","containerClassName","homeBackground","undefined","Icon","useCallback","useState","twMerge","IntegrityInspector","onValidate","onRebuildKeyframes","onRebuildSnapshots","documentId","setDocumentId","branch","setBranch","status","setStatus","validationResult","setValidationResult","rebuildResult","setRebuildResult","error","setError","confirmAction","setConfirmAction","clearResults","handleValidate","trim","result","undefined","err","Error","message","String","handleRebuildKeyframes","handleRebuildSnapshots","e","target","value","ValidationResultView","totalIssues","keyframeIssues","length","snapshotIssues","isConsistent","map","issue","i","scope","revision","keyframeHash","replayedHash","snapshotHash","RebuildResultView","keyframesDeleted","scopesInvalidated","twMerge","LogoAnimation","LoadingScreen","props","showLoadingScreen","loadingComponent","size","className","Modal","twMerge","AddLocalDriveForm","AddRemoteDriveForm","TabContent","Tabs","AddDriveModal","props","handleCancel","onOpenChange","open","onAddRemoteDrive","onAddLocalDrive","requestPublicDrive","modalProps","containerProps","className","appOptions","Icon","Modal","isValidName","useCallback","useState","FormInput","ModalButton","CLOSE_ANIMATION_DURATION","CreateDocumentModal","props","onOpenChange","onContinue","overlayProps","contentProps","restProps","nodeName","setNodeName","isValid","setIsValid","handleCancel","setTimeout","handleCreate","handleSubmit","e","preventDefault","className","name","target","value","Icon","useState","FormInput","ConnectConfirmationModal","ConnectDeleteDriveModal","props","inputPlaceholder","body","driveName","confirmationModalProps","inputName","setInputName","e","target","value","ConnectConfirmationModal","ConnectDeleteItemModal","props","onDelete","deleteLabel","restProps","Icon","forwardRef","FormInput","DriveNameInput","props","ref","icon","Icon","PowerhouseButton","useState","DriveNameInput","DeleteDrive","props","drive","handleDeleteDrive","onCancel","driveNameInput","setDriveNameInput","isAllowedToDelete","header","name","deleteDrive","event","target","value","Icon","PowerhouseButton","useState","useForm","Disclosure","Divider","AvailableOfflineToggle","DeleteDrive","DriveNameInput","Label","LocationInfo","SharingTypeFormInput","DriveSettingsForm","props","drive","sharingType","availableOffline","systemInfo","onSubmit","handleDeleteDrive","name","header","showLocationSettings","setShowLocationSettings","showAbout","setShowAbout","showDangerZone","setShowDangerZone","showDeleteDrive","setShowDeleteDrive","register","handleSubmit","control","mode","defaultValues","location","e","status","version","gitHash","Icon","Modal","twMerge","Divider","DriveSettingsForm","DriveSettingsModal","props","drive","open","sharingType","availableOffline","systemInfo","onOpenChange","onDeleteDrive","onRenameDrive","onChangeSharingType","onChangeAvailableOffline","modalProps","containerProps","onSubmit","data","name","header","handleDeleteDrive","handleCancel","className","Icon","Modal","JsonViewer","toSerializableObject","obj","JSON","parse","stringify","_key","value","Error","name","message","ObjectInspectorModal","open","onOpenChange","title","object","serializableObject","className","style","height","width","maxWidth","Icon","useCallback","useEffect","useState","twMerge","ObjectInspectorModal","VIEW_COLUMN","key","label","width","COLUMNS","truncateId","id","maxLength","length","slice","sortProcessors","processors","sort","a","b","comparison","column","status","localeCompare","processorId","factoryId","driveId","processorIndex","lastOrdinal","lastError","lastErrorTimestamp","getTime","direction","SortIcon","active","undefined","ProcessorsInspector","getProcessors","onRetry","setProcessors","loading","setLoading","setSort","retryingId","setRetryingId","selectedProcessor","setSelectedProcessor","error","setError","loadProcessors","result","e","Error","message","String","interval","setInterval","clearInterval","handleRefresh","handleRetry","handleSort","columnKey","newDirection","sortedProcessors","activeCount","filter","p","erroredCount","map","index","isActive","sortDirection","processor","toISOString","toLocaleString","open","Icon","useCallback","useEffect","useState","twMerge","ObjectInspectorModal","VIEW_COLUMN","key","label","width","COLUMNS","truncateId","id","maxLength","length","slice","formatDate","dateStr","date","Date","toLocaleString","sortJobs","jobs","sort","a","b","comparison","column","localeCompare","kind","documentId","scope","branch","createdAt","retryCount","status","direction","SortIcon","active","undefined","QueueInspector","getQueueState","onPause","onResume","state","setState","isPaused","pendingJobs","executingJobs","totalPending","totalExecuting","loading","setLoading","setSort","actionInProgress","setActionInProgress","selectedJob","setSelectedJob","loadState","newState","interval","setInterval","clearInterval","handleRefresh","handlePauseResume","handleSort","columnKey","newDirection","allJobs","map","job","sortedJobs","index","isActive","sortDirection","open","twMerge","stateStyles","connected","connecting","reconnecting","error","disconnected","ConnectionStateBadge","state","failureCount","style","truncateId","id","maxLength","length","slice","Icon","SortIcon","direction","active","undefined","Icon","SyncOperationStatus","useState","twMerge","ObjectInspectorModal","truncateId","SortIcon","VIEW_COLUMN","key","label","width","COLUMNS","DEAD_LETTER_COLUMNS","toSerializableObject","obj","JSON","parse","stringify","_key","value","Error","name","message","getStatusLabel","status","Unknown","TransportPending","ExecutionPending","Applied","getStatusIcon","getErrorMessage","error","sortOperations","operations","sort","ops","a","b","comparison","column","documentId","localeCompare","branch","scopes","join","length","direction","MailboxTable","title","mailboxType","onSort","collapsed","onToggleCollapse","selectedOperation","setSelectedOperation","columns","sortedOps","handleSort","columnKey","handleCopyAll","serializable","json","navigator","clipboard","writeText","map","index","isActive","sortDirection","op","id","open","Icon","useCallback","useState","ConnectionStateBadge","MailboxTable","formatTimestamp","ms","Date","toLocaleTimeString","ChannelInspector","remoteName","channel","onBack","onRefresh","connectionState","sorts","setSorts","inbox","undefined","outbox","deadLetter","collapsed","setCollapsed","handleToggleCollapse","mailbox","prev","handleSort","columnKey","currentSort","newDirection","column","direction","getPollerControls","poller","pollerControls","pollerState","setPollerState","isPaused","isRunning","intervalMs","setIntervalMs","getIntervalMs","mailboxStates","setMailboxStates","handlePause","pause","handleResume","resume","handlePollNow","triggerNow","handleApplyInterval","handleMailboxPause","mailboxInstance","handleMailboxResume","handleMailboxFlush","flush","failureCount","state","lastSuccessUtcMs","lastFailureUtcMs","pushBlocked","pushFailureCount","e","Number","target","value","key","ackOrdinal","latestOrdinal","items","Icon","useCallback","useEffect","useMemo","useState","twMerge","ChannelInspector","ConnectionStateBadge","SortIcon","truncateId","BASE_COLUMNS","key","label","width","ACTIONS_COLUMN","formatFilter","filter","parts","branch","push","documentId","length","scope","join","sortRemotes","remotes","sort","a","b","aValue","bValue","column","id","name","collectionId","comparison","localeCompare","direction","RemotesInspector","getRemotes","removeRemote","addRemoteManual","triggerPull","connectionStates","setRemotes","loading","setLoading","setSort","selectedRemote","setSelectedRemote","manualUrl","setManualUrl","adding","setAdding","addError","setAddError","hasRowActions","columns","loadRemotes","data","handleRefresh","updated","find","r","handleSort","columnKey","newDirection","handleViewChannel","remote","handleRemove","undefined","handleBack","handleAddManual","url","trim","error","Error","message","String","handlePull","channel","get","sortedRemotes","e","target","value","map","index","isActive","sortDirection","isSortable","failureCount","state","Icon","Modal","twMerge","DBExplorer","IntegrityInspector","ProcessorsInspector","QueueInspector","RemotesInspector","TabContent","Tabs","InspectorModal","open","onOpenChange","modalProps","containerProps","dbExplorerProps","remotesInspectorProps","queueInspectorProps","processorsInspectorProps","integrityInspectorProps","defaultTab","className","style","height","width","maxWidth","useState","Modal","twMerge","buttonStyles","groupByPackage","installations","groups","Map","item","existing","get","packageName","push","documentType","set","Array","from","entries","map","documentTypes","PackageInstallModal","props","pendingInstallations","onInstall","onDismiss","open","onOpenChange","overlayProps","contentProps","restProps","installingPackages","setInstallingPackages","Set","grouped","handleInstall","prev","add","next","delete","length","isOpen","className","installing","has","join","useEffect","useRef","useState","Modal","twMerge","ReadRequiredModal","props","open","onOpenChange","header","body","closeLabel","onContinue","bodyClassName","overlayProps","contentProps","disableClose","setDisableClose","contentRef","checkScroll","element","current","scrollHeight","clientHeight","addEventListener","handleScroll","Math","ceil","scrollTop","requestAnimationFrame","removeEventListener","useState","Disclosure","PH_DEPENDENCIES","verifyPackageJsonFields","packageJson","parsed","version","dependencies","Object","fromEntries","entries","devDependencies","peerDependencies","filter","key","some","regexOrName","test","error","console","DependencyVersions","props","isOpen","setIsOpen","phCliVersion","validatedData","map","dep","replace","DependencyVersions","About","props","packageJson","phCliVersion","Icon","twMerge","capitalCase","useState","ConnectDropdownMenu","getDriveSharingType","drive","isReadDrive","sharingType","_sharingType","state","local","__sharingType","toUpperCase","validTypes","includes","DangerZone","props","className","rest","ModifyDrives","DriveList","drives","map","header","id","Drive","onDeleteDrive","isDropdownMenuOpen","setIsDropdownMenuOpen","localDriveIcon","cloudDriveIcon","publicDriveIcon","global","icon","getNodeIcon","name","label","e","stopPropagation","LocalStorage","onClearStorage","SelectFieldRaw","twMerge","DefaultEditor","props","className","rest","DefaultEditorSelect","documentModelEditor","setDocumentModelEditor","documentModelEditorOptions","value","parsePackageSpec","spec","trimmed","trim","length","name","tag","undefined","splitAt","startsWith","lastIndexOf","indexOf","slice","buildPackageSpec","Icon","twMerge","Input","Popover","PopoverContent","PopoverTrigger","useMemo","useState","resolveDefaultVersionSelection","options","distTags","versions","version","preferredTag","kind","value","latest","firstTag","Object","keys","undefined","length","VersionPicker","props","selected","onChange","disabled","className","open","setOpen","query","setQuery","tagEntries","entries","filteredTags","needle","trim","toLowerCase","filter","tag","ver","includes","filteredVersions","all","slice","reverse","v","hasAnyPickable","triggerLabel","next","e","preventDefault","target","map","isSelected","PackageAnimation","SearchAutocomplete","useCallback","useEffect","useState","buildPackageSpec","parsePackageSpec","VersionPicker","resolveDefaultVersionSelection","NPM_NAME_RE","isPlausiblePackageName","name","length","test","PackageResultCard","props","option","ctx","typedTag","selectingValue","selectLabel","selectingContent","handleSelect","baseName","label","split","value","hasVersionMetadata","distTags","Object","keys","versions","selected","setSelected","version","preferredTag","kind","includes","installSpec","isSelecting","isDisabled","disabled","description","meta","disabledLabel","PackageManagerInput","registryPackageList","onInstall","className","setTypedTag","undefined","fetchOptions","query","namePart","tag","needle","toLowerCase","localOptions","filter","pkg","manifest","map","isInstalled","status","publisher","Promise","resolve","fallbackSpec","fallbackLabel","fallbackOption","renderRow","Icon","useCallback","useEffect","useLayoutEffect","useState","twMerge","ConnectDropdownMenu","buildPackageSpec","resolveDefaultVersionSelection","VersionPicker","PackageDetail","label","value","PackageManagerListItem","props","registryPackage","onInstall","onUninstall","className","isDropdownMenuOpen","setIsDropdownMenuOpen","canPickVersion","status","hasVersionMetadata","distTags","Object","keys","length","versions","selected","setSelected","version","installDropdownItem","id","icon","uninstallDropdownItem","getDropdownItems","undefined","filter","item","dropdownItems","name","manifest","description","category","publisher","hasAnyField","url","spec","catch","console","error","e","stopPropagation","PackageManagerList","registryPackageList","maxHeight","setMaxHeight","locallyInstalledPackages","p","registryInstalledPackages","availablePackages","dismissedPackages","calculateMaxHeight","viewportHeight","window","innerHeight","availableHeight","Math","max","addEventListener","removeEventListener","hasLocallyInstalled","hasRegistryInstalled","hasAnyInstalled","hasAvailable","hasDismissed","installedCount","STORAGE_KEY","loadCollapsedSections","raw","localStorage","getItem","JSON","parse","useCollapsedSection","sectionId","collapsed","setCollapsed","current","setItem","stringify","toggle","prev","PackageSection","title","count","isEmpty","emptyText","children","contentId","PackageSubSection","PackageList","packages","map","pkg","twMerge","PackageManagerInput","PackageManagerList","PackageManager","props","registryPackageList","onInstall","onUninstall","mutable","disabled","className","Icon","Modal","useState","twMerge","SettingsModal","props","title","overlayProps","contentProps","onOpenChange","tabs","defaultTab","restProps","selectedTab","setSelectedTab","at","id","tabsContent","map","tab","icon","label","selectedTabContent","find","content","SelectedTabComponent","className","style","boxShadow","Modal","ModalButton","ConnectUpgradeDriveModal","props","body","header","onOpenChange","onContinue","cancelLabel","continueLabel","overlayProps","contentProps","restProps","className","Icon","Branch","props","branch","Icon","useCopyToClipboard","DocId","props","docId","onCopy","copy","handleCopy","text","then","catch","error","console","Icon","useCopyToClipboard","DocumentState","props","documentState","onCopyState","copy","handleCopy","jsonState","JSON","stringify","then","catch","error","console","ConnectSelect","Scope","props","value","onChange","items","displayValue","Icon","twMerge","Branch","DocId","DocumentState","Scope","Header","props","title","docId","scope","onChangeScope","onClose","className","documentState","onCopyState","onCopyDocId","divProps","useEffect","useState","ensCache","Map","fetchEns","address","cached","get","promise","fetch","then","res","ok","Error","status","json","catch","err","delete","set","useEns","data","setData","isLoading","setIsLoading","error","setError","undefined","cancelled","finally","formatEthAddress","address","slice","Anchor","Content","Portal","Root","Trigger","useState","funnel","CodePopover","props","content","trigger","anchor","isOpen","setIsOpen","opener","triggerAt","minQuietPeriodMs","closer","open","cancel","call","close","changedIsOpen","e","preventDefault","top","right","bottom","left","useEns","formatEthAddress","CodePopover","ENSAvatar","FormattedJsonViewer","Address","props","address","chainId","data","ensData","shortenedAddress","avatar_url","undefined","Icon","twMerge","CodePopover","FormattedJsonViewer","Errors","props","errors","hasErrors","length","color","icon","text","content","Icon","CodePopover","FormattedJsonViewer","Operation","props","operationType","operationInput","Icon","CodePopover","FormattedJsonViewer","RevisionNumber","props","operationIndex","eventId","stateHash","revisionNumber","Icon","CodePopover","FormattedJsonViewer","Signature","props","signatures","length","VerificationStatus","signatureCount","verifiedSignaturesCount","filter","signature","isVerified","signatureText","verificationStatusText","color","format","CodePopover","FormattedJsonViewer","Timestamp","props","timestampUtcMs","timestamp","timestampNumber","includes","parseInt","date","Date","shortDate","longDate","timestampFormatted","memo","Address","Errors","Operation","RevisionNumber","Signature","Timestamp","_Revision","props","Revision","Skip","props","operationIndex","skipCount","revisionNumber","skippedRevisions","makeRows","operations","revisionsAndSkips","seenDays","Set","operation","timestampUtcMs","day","split","has","add","push","type","height","operationIndex","index","eventId","id","stateHash","hash","operationType","action","operationInput","input","address","context","signer","user","chainId","signatures","makeSignatures","errors","error","undefined","skip","skipCount","getUniqueDatesInOrder","dates","date","Array","from","sort","a","b","Date","getTime","makeSignatureFromSignatureArray","signatureArray","signerAddress","prevStateHash","signatureBytes","isVerified","signaturesArray","map","Icon","format","Day","props","timestampUtcMs","timestamp","formattedDate","useVirtualizer","useEffect","useMemo","useRef","useState","Revision","Skip","makeRows","Day","Timeline","props","localOperations","globalOperations","scope","operations","initialNumRowsToShow","allRows","scrollAmount","setScrollAmount","numRowsToShow","setNumRowsToShow","rows","setRows","slice","parentRef","hasNextPage","length","rowVirtualizer","count","getScrollElement","current","estimateSize","i","height","gap","ratio","Math","floor","newNumRevisions","prev","handleScroll","e","n","deltaY","window","addEventListener","removeEventListener","getTotalSize","width","position","getVirtualItems","map","virtualRow","row","index","top","left","size","transform","start","type","key","Pagination","usePagination","garbageCollect","sortOperations","useMemo","useState","ConnectTooltipProvider","Header","Timeline","RevisionHistory","props","documentTitle","documentId","globalOperations","localOperations","onClose","itemsPerPage","documentState","onCopyState","onCopyDocId","scope","setScope","visibleOperations","operations","sort","a","b","index","pageItems","pages","goToPage","goToNextPage","goToPreviousPage","goToFirstPage","goToLastPage","hiddenNextPages","isNextPageAvailable","isPreviousPageAvailable","onChangeScope","showPagination","length","PaginationComponent","twMerge","FilterItem","props","item","className","containerProps","icon","label","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","Icon","useMemo","twMerge","FilterItem","ConnectSearchBar","props","value","onChange","placeholder","filterLabel","filterItems","selectedFilter","onFilterSelect","className","items","map","item","id","content","selectedItemFilter","find","filterLabelContent","handleChange","event","target","twMerge","ConnectTooltip","SidebarItem","props","icon","title","description","_description","containerClassName","active","onClick","slice","toUpperCase","Icon","SidebarItem","SidebarAddDriveItem","props","containerClassName","onClick","useTheme","Monitor","Moon","Sun","twMerge","OPTIONS","value","Icon","label","ThemeSwitch","theme","isSystem","setTheme","select","val","isActive","map","e","key","Icon","useState","twMerge","AccountPopoverLogin","onLogin","loading","setLoading","allowLogin","content","handleLogin","undefined","renownShortDark","renownShortHoverDark","renownShortHover","renownShort","useTheme","twMerge","AccountPopoverLogin","AccountPopover","SidebarLogin","onLogin","content","theme","isDark","src","hoverSrc","Icon","PowerhouseButton","useCallback","useState","twMerge","shortAddress","address","slice","AccountPopoverUser","onDisconnect","etherscanUrl","username","isCopied","setIsCopied","copyToClipboard","text","navigator","clipboard","writeText","setTimeout","err","console","error","AccountPopoverUser","AccountPopover","ENSAvatar","SidebarUser","address","ensName","avatarUrl","etherscanUrl","onDisconnect","content","Icon","SidebarFooter","Settings","twMerge","ThemeSwitch","SidebarLogin","SidebarUser","ConnectSidebarFooter","address","ensName","avatarUrl","className","onLogin","onClickSettings","onDisconnect","onHomeClick","showDebug","onDebugClick","etherscanUrl","props","SidebarHeader","twMerge","ConnectSidebarHeader","className","children","props","Sidebar","SidebarPanel","ConnectSidebarFooter","ConnectSidebarHeader","ConnectSidebar","onClick","address","ensName","avatarUrl","headerContent","onClickSettings","maxWidth","minWidth","onLogin","onDisconnect","etherscanUrl","showDebug","onDebugClick","props","children","getFolderStatus","folderPath","sortedFiles","file","path","startsWith","status","sortFilesByStatus","files","sort","a","b","statusOrder","indexOf","removeSuccessFiles","filter"],"sources":["../../src/connect/components/account-popover/account-popover.tsx","../../assets/connect-loader.mp4","../../src/connect/components/animated-loader/animated-loader.tsx","../../src/connect/components/node-input/node-input.tsx","../../src/connect/components/breadcrumbs/breadcrumbs.tsx","../../src/connect/components/combobox/combobox.tsx","../../src/connect/components/cookie-banner/cookie-banner.tsx","../../src/connect/components/modal/modal-button.tsx","../../src/connect/components/modal/confirmation-modal.tsx","../../src/connect/components/db-explorer/components/schema-tree-sidebar.tsx","../../src/connect/components/select/select.tsx","../../src/connect/components/db-explorer/components/filter-bar.tsx","../../src/connect/components/db-explorer/components/table-view.tsx","../../src/connect/components/db-explorer/db-explorer.tsx","../../src/connect/components/debug-inspector/debug-inspector.tsx","../../src/connect/components/logo-animation.tsx","../../src/connect/components/default-editor-loader/default-editor-loader.tsx","../../src/connect/components/disclosure/disclosure.tsx","../../src/connect/components/divider/divider.tsx","../../src/connect/components/tabs/tab-content.tsx","../../src/connect/components/tabs/tabs.tsx","../../src/connect/components/document-state-viewer/document-state-viewer.tsx","../../src/connect/components/tooltip/tooltip.tsx","../../src/connect/components/document-timeline/components/h-divider.tsx","../../src/connect/components/document-timeline/components/timeline-bar.tsx","../../src/connect/components/document-timeline/document-timeline.tsx","../../src/connect/components/document-toolbar/containers.tsx","../../src/connect/components/document-toolbar/use-document-undo-redo.ts","../../src/connect/components/document-toolbar/toolbar-button.tsx","../../src/connect/components/document-toolbar/toolbar-input.tsx","../../src/connect/components/document-toolbar/toolbar-name.tsx","../../src/connect/components/document-toolbar/constants.ts","../../src/connect/components/document-toolbar/utils.tsx","../../src/connect/components/document-toolbar/document-toolbar.tsx","../../src/connect/components/modal/replace-duplicate-modal.tsx","../../src/connect/components/upload-file-item/components/error-details.tsx","../../src/connect/components/upload-file-item/components/header.tsx","../../src/connect/components/upload-file-item/components/progress-bar.tsx","../../src/connect/components/upload-file-item/components/status-row.tsx","../../src/connect/components/upload-file-item/upload-file-item.tsx","../../src/connect/components/upload-file-list/utils.ts","../../src/connect/components/upload-file-list/upload-file-list.tsx","../../src/connect/components/drop-zone/utils.ts","../../src/connect/components/drop-zone/upload-file-list-container.tsx","../../src/connect/components/drop-zone/use-upload-tracker.ts","../../src/connect/components/drop-zone/drop-zone.tsx","../../src/connect/components/drop-zone/drop-zone-wrapper.tsx","../../src/connect/components/dropdown-menu/dropdown-menu.tsx","../../src/connect/components/editor-action-buttons/editor-action-buttons.tsx","../../src/connect/components/editor-undo-redo-buttons/editor-undo-redo-buttons.tsx","../../assets/powerhouse-rounded.png","../../src/connect/components/ens-avatar/ens-avatar.tsx","../../src/connect/constants/options.tsx","../../src/connect/constants/syncing.ts","../../src/connect/components/status-icon/sync-status-icon.tsx","../../src/connect/components/file-item/file-item.tsx","../../src/connect/components/folder-item/folder-item.tsx","../../src/connect/components/footer/footer-link.tsx","../../src/connect/components/footer/footer.tsx","../../src/connect/components/form-input/form-input.tsx","../../src/connect/components/form/inputs/app-form-input.tsx","../../src/connect/components/toggle/toggle.tsx","../../src/connect/components/form/inputs/available-offline-toggle.tsx","../../src/connect/components/form/inputs/label.tsx","../../src/connect/components/form/inputs/sharing-type-form-input.tsx","../../src/connect/components/form/add-local-drive-form.tsx","../../src/connect/components/form/inputs/drive-name.tsx","../../src/connect/components/form/inputs/location-info.tsx","../../src/connect/components/form/add-remote-drive-form.tsx","../../src/connect/components/formatted-json-viewer.tsx","../../src/connect/components/home-screen/home-background-image.tsx","../../src/connect/components/home-screen/home-screen-item.tsx","../../src/connect/components/home-screen/home-screen-add-drive-item.tsx","../../src/connect/components/home-screen/home-screen.tsx","../../src/connect/components/integrity-inspector/integrity-inspector.tsx","../../src/connect/components/loading-screen/loading-screen.tsx","../../src/connect/components/modal/add-drive-modal/add-drive-modal.tsx","../../src/connect/components/modal/create-document-modal.tsx","../../src/connect/components/modal/delete-drive-modal.tsx","../../src/connect/components/modal/delete-item-modal.tsx","../../src/connect/components/form/inputs/drive-name-input.tsx","../../src/connect/components/form/inputs/delete-drive.tsx","../../src/connect/components/form/drive-settings-form.tsx","../../src/connect/components/modal/drive-settings-modal.tsx","../../src/connect/components/object-inspector-modal/object-inspector-modal.tsx","../../src/connect/components/processors-inspector/processors-inspector.tsx","../../src/connect/components/queue-inspector/queue-inspector.tsx","../../src/connect/components/remotes-inspector/components/connection-state-badge.tsx","../../src/connect/components/remotes-inspector/utils.ts","../../src/connect/components/remotes-inspector/components/sort-icon.tsx","../../src/connect/components/remotes-inspector/components/mailbox-table.tsx","../../src/connect/components/remotes-inspector/components/channel-inspector.tsx","../../src/connect/components/remotes-inspector/remotes-inspector.tsx","../../src/connect/components/modal/inspector-modal/inspector-modal.tsx","../../src/connect/components/modal/missing-package-modal.tsx","../../src/connect/components/modal/read-required-modal.tsx","../../src/connect/components/modal/settings-modal/dependency-versions/dependency-versions.tsx","../../src/connect/components/modal/settings-modal-v2/about.tsx","../../src/connect/components/modal/settings-modal-v2/danger-zone.tsx","../../src/connect/components/modal/settings-modal-v2/default-editor.tsx","../../src/connect/components/modal/settings-modal-v2/package-manager/parse-package-spec.ts","../../src/connect/components/modal/settings-modal-v2/package-manager/version-picker.tsx","../../src/connect/components/modal/settings-modal-v2/package-manager/package-manager-input.tsx","../../src/connect/components/modal/settings-modal-v2/package-manager/package-manager-list.tsx","../../src/connect/components/modal/settings-modal-v2/package-manager/package-manager.tsx","../../src/connect/components/modal/settings-modal-v2/settings-modal.tsx","../../src/connect/components/modal/upgrade-drive-modal.tsx","../../src/connect/components/revision-history/header/branch.tsx","../../src/connect/components/revision-history/header/doc-id.tsx","../../src/connect/components/revision-history/header/document-state.tsx","../../src/connect/components/revision-history/header/scope.tsx","../../src/connect/components/revision-history/header/header.tsx","../../src/connect/hooks/use-ens.ts","../../src/connect/utils/address.ts","../../src/connect/components/code-popover.tsx","../../src/connect/components/revision-history/revision/address.tsx","../../src/connect/components/revision-history/revision/errors.tsx","../../src/connect/components/revision-history/revision/operation.tsx","../../src/connect/components/revision-history/revision/revision-number.tsx","../../src/connect/components/revision-history/revision/signature.tsx","../../src/connect/components/revision-history/revision/timestamp.tsx","../../src/connect/components/revision-history/revision/revision.tsx","../../src/connect/components/revision-history/skip/skip.tsx","../../src/connect/components/revision-history/utils.ts","../../src/connect/components/revision-history/timeline/day.tsx","../../src/connect/components/revision-history/timeline/timeline.tsx","../../src/connect/components/revision-history/revision-history.tsx","../../src/connect/components/search-bar/filter-item.tsx","../../src/connect/components/search-bar/search-bar.tsx","../../src/connect/components/sidebar/sidebar-item.tsx","../../src/connect/components/sidebar/sidebar-add-drive-item.tsx","../../src/connect/components/theme-switch.tsx","../../assets/renown-short-dark.png","../../assets/renown-short-hover-dark.png","../../assets/renown-short-hover.png","../../assets/renown-short.png","../../src/connect/components/account-popover/account-popover-login.tsx","../../src/connect/components/sidebar/sidebar-login.tsx","../../src/connect/components/account-popover/account-popover-user.tsx","../../src/connect/components/sidebar/sidebar-user.tsx","../../src/connect/components/sidebar/sidebar-footer.tsx","../../src/connect/components/sidebar/sidebar-header.tsx","../../src/connect/components/sidebar/sidebar.tsx","../../src/connect/utils/get-folder-status.ts"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"#design-system/ui\";\n\nexport interface AccountPopoverProps {\n children: ReactNode;\n content: ReactNode;\n}\n\nexport const AccountPopover = ({ children, content }: AccountPopoverProps) => {\n return (\n <Popover>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n aria-label=\"Open Account\"\n className=\"cursor-pointer\"\n >\n {children}\n </button>\n </PopoverTrigger>\n <PopoverContent className=\"w-52 p-0\" align=\"start\">\n {content}\n </PopoverContent>\n </Popover>\n );\n};\n","\"data:video/mp4;base64,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\"","import ConnectLoaderVideo from \"#assets/connect-loader.mp4\";\nimport type { Size } from \"#design-system\";\nimport { getDimensions } from \"#design-system\";\nimport type { ComponentPropsWithoutRef, CSSProperties } from \"react\";\n\ntype Props = ComponentPropsWithoutRef<\"video\"> & {\n readonly size?: Size;\n};\nexport function AnimatedLoader(props: Props) {\n const { style, size = 100, ...delegatedProps } = props;\n\n const dimensions = getDimensions(size);\n\n const _style: CSSProperties = {\n objectFit: \"contain\",\n pointerEvents: \"none\",\n ...dimensions,\n ...style,\n };\n\n const width = dimensions.width?.replace(\"px\", \"\");\n const height = dimensions.height?.replace(\"px\", \"\");\n\n return (\n <video\n autoPlay\n height={height}\n loop\n muted\n playsInline\n width={width}\n {...delegatedProps}\n style={_style}\n >\n <source src={ConnectLoaderVideo} type=\"video/mp4\" />\n </video>\n );\n}\n","import { useLayoutEffect, useRef, useState, type RefObject } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { useEventListener, useOnClickOutside } from \"usehooks-ts\";\n\ntype Props = {\n readonly name?: string;\n readonly defaultValue?: string;\n readonly placeholder?: string;\n readonly \"aria-label\"?: string;\n readonly className?: string;\n readonly minLength?: number;\n readonly onSubmit: (value: string) => void;\n readonly onCancel: () => void;\n};\nexport function NodeInput(props: Props) {\n const {\n onSubmit,\n onCancel,\n defaultValue,\n className,\n minLength = 1,\n ...inputProps\n } = props;\n const [value, setValue] = useState(defaultValue ?? \"\");\n\n const ref = useRef<HTMLInputElement>(null);\n\n function handleSubmit() {\n if (value.length >= minLength) {\n onSubmit(value);\n }\n }\n\n useOnClickOutside(ref as RefObject<HTMLElement>, handleSubmit);\n\n useEventListener(\"keyup\", (e) => {\n if (e.key === \"Enter\") {\n handleSubmit();\n }\n if (e.key === \"Escape\") {\n onCancel();\n }\n });\n\n useLayoutEffect(() => {\n setTimeout(() => {\n ref.current?.focus();\n ref.current?.select();\n ref.current?.scroll({ left: 9999 });\n }, 100);\n }, []);\n\n return (\n <input\n {...inputProps}\n autoFocus\n className={twMerge(\"bg-inherit text-inherit outline-none\", className)}\n minLength={minLength}\n onChange={(e) => setValue(e.target.value)}\n ref={ref}\n required\n type=\"text\"\n value={value}\n />\n );\n}\n","import { Icon } from \"#design-system\";\nimport {\n addFolder,\n setSelectedDrive,\n setSelectedNode,\n useDragNode,\n useDropNode,\n useSelectedDriveId,\n useSelectedDriveSafe,\n useSelectedNodePath,\n useUserPermissions,\n} from \"@powerhousedao/reactor-browser\";\nimport { Fragment, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { NodeInput } from \"../node-input/node-input.js\";\n\nexport function Breadcrumbs() {\n const { isAllowedToCreateDocuments } = useUserPermissions();\n const [selectedDrive] = useSelectedDriveSafe();\n const selectedDriveId = useSelectedDriveId();\n const selectedNodePath = useSelectedNodePath();\n const [isCreating, setIsCreating] = useState(false);\n function onAddNew() {\n setIsCreating(true);\n }\n\n function onSubmit(name: string) {\n if (!isAllowedToCreateDocuments || !selectedDriveId) return;\n\n addFolder(selectedDriveId, name, selectedNodePath.at(-1)?.id)\n .then((node) => {\n setSelectedNode(node);\n })\n .catch((error) => {\n console.error(error);\n })\n .finally(() => {\n setIsCreating(false);\n });\n }\n\n function onCancel() {\n setIsCreating(false);\n }\n\n const hasSelectedDrive = !!selectedDrive;\n const hasNodePath = !!selectedNodePath.length;\n\n return (\n <div className=\"flex h-9 flex-row items-center gap-2 p-6 text-gray-500 dark:text-slate-400\">\n {hasSelectedDrive && (\n <>\n <button\n type=\"button\"\n aria-label=\"Back to home\"\n title=\"Back to home\"\n className=\"flex items-center justify-center rounded-md p-1 text-gray-700 transition-colors hover:bg-gray-100 hover:text-gray-800 dark:text-slate-200 dark:hover:bg-slate-700 dark:hover:text-slate-100\"\n onClick={() => setSelectedDrive(undefined)}\n >\n <Icon name=\"ArrowLeft\" size={14} />\n </button>\n <Breadcrumb\n id={selectedDriveId}\n parentId={undefined}\n name={selectedDrive.state.global.name || selectedDrive.header.name}\n onClick={() => setSelectedDrive(selectedDrive)}\n />\n <span>/</span>\n </>\n )}\n {hasNodePath &&\n selectedNodePath.map((node) => (\n <Fragment key={node.id}>\n <Breadcrumb\n id={node.id}\n parentId={node.parentFolder}\n name={node.name}\n onClick={() => setSelectedNode(node)}\n />\n <span>/</span>\n </Fragment>\n ))}\n {isAllowedToCreateDocuments &&\n (isCreating ? (\n <NodeInput\n className=\"text-gray-900 dark:text-slate-100\"\n defaultValue=\"New Folder\"\n onCancel={onCancel}\n onSubmit={onSubmit}\n placeholder=\"New Folder\"\n />\n ) : (\n <button\n type=\"button\"\n className=\"ml-1 flex items-center justify-center gap-2 rounded-md bg-gray-50 px-2 py-1.5 text-gray-700 transition-colors hover:bg-gray-200 hover:text-gray-800 dark:bg-slate-800 dark:text-slate-200 dark:hover:bg-slate-600 dark:hover:text-slate-100\"\n onClick={onAddNew}\n >\n <Icon name=\"Plus\" size={14} />\n Add new\n </button>\n ))}\n </div>\n );\n}\n\nexport type BreadcrumbProps = {\n name: string;\n id: string | undefined;\n parentId: string | null | undefined;\n onClick: () => void;\n};\n\nexport function Breadcrumb(props: BreadcrumbProps) {\n const { name, id, parentId, onClick } = props;\n const { isDragging, ...dragProps } = useDragNode({\n srcId: id,\n parentId: parentId ?? undefined,\n });\n const { isDropTarget, ...dropProps } = useDropNode(id);\n\n const containerStyles = twMerge(\n \"cursor-pointer transition-colors last-of-type:text-gray-800 hover:text-gray-800 dark:text-slate-200 last-of-type:dark:text-slate-100 dark:hover:text-slate-100\",\n isDragging\n ? \"opacity-60\"\n : isDropTarget\n ? \"bg-blue-100 dark:bg-blue-800\"\n : \"\",\n );\n\n return (\n <div\n {...dragProps}\n {...dropProps}\n className={containerStyles}\n onClick={onClick}\n role=\"button\"\n >\n {name}\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { useTheme } from \"@powerhousedao/reactor-browser\";\nimport type { ComponentPropsWithoutRef, ReactNode } from \"react\";\nimport type {\n ClearIndicatorProps,\n DropdownIndicatorProps,\n MenuListProps,\n} from \"react-select\";\nimport Select, { components } from \"react-select\";\n\ntype SelectProps = ComponentPropsWithoutRef<typeof Select>;\n\ntype Props = Omit<SelectProps, \"components\" | \"styles\" | \"theme\"> & {\n readonly addItemButtonProps?: {\n label?: ReactNode;\n onClick?: () => void;\n };\n};\n\nfunction DropdownIndicator(props: DropdownIndicatorProps) {\n return (\n <components.DropdownIndicator {...props}>\n <Icon name=\"ChevronDown\" size={16} />\n </components.DropdownIndicator>\n );\n}\n\nfunction ClearIndicator(props: ClearIndicatorProps) {\n return (\n <components.ClearIndicator {...props}>\n <Icon name=\"Xmark\" size={16} />\n </components.ClearIndicator>\n );\n}\n\nfunction MenuList(\n props: MenuListProps & {\n readonly label?: ReactNode;\n readonly onClick?: () => void;\n },\n) {\n const { label, onClick, ...rest } = props;\n\n const hasAddItemButton = !!label && !!onClick;\n\n return (\n <components.MenuList {...rest}>\n {props.children}\n {hasAddItemButton ? (\n <button\n className=\"w-full px-2 py-3 hover:bg-gray-50 dark:hover:bg-slate-800\"\n onClick={onClick}\n >\n {label}\n </button>\n ) : null}\n </components.MenuList>\n );\n}\n\nexport function Combobox(props: Props) {\n const invalid = props[\"aria-invalid\"] === \"true\";\n const { addItemButtonProps, ...rest } = props;\n const { theme } = useTheme();\n const dark = theme === \"dark\";\n\n return (\n <Select\n {...rest}\n components={{\n DropdownIndicator,\n ClearIndicator,\n MenuList: (menuListProps) =>\n MenuList({ ...menuListProps, ...addItemButtonProps }),\n }}\n classNames={{\n menuList: () =>\n \"scrollbar-thin scrollbar-track-transparent scrollbar-thumb-rounded-md scrollbar-thumb-gray-300 dark:scrollbar-thumb-slate-600\",\n }}\n styles={{\n dropdownIndicator: () => {\n return {\n label: \"indicatorContainer\",\n display: \"flex\",\n transition: \"color 150ms\",\n color: dark ? \"var(--color-slate-50)\" : \"var(--color-gray-900)\",\n padding: 8,\n boxSizing: \"border-box\",\n };\n },\n clearIndicator: (baseStyles) => {\n return {\n ...baseStyles,\n color: dark ? \"var(--color-slate-50)\" : \"var(--color-gray-900)\",\n };\n },\n container: (baseStyles) => {\n return {\n ...baseStyles,\n borderColor: dark\n ? \"var(--color-slate-700)\"\n : \"var(--color-gray-200)\",\n fontSize: 12,\n };\n },\n placeholder: (baseStyles) => {\n return {\n ...baseStyles,\n color: invalid\n ? dark\n ? \"var(--color-red-400)\"\n : \"var(--color-red-800)\"\n : dark\n ? \"var(--color-slate-100)\"\n : \"var(--color-gray-500)\",\n };\n },\n control: () => {\n return {\n label: \"control\",\n alignItems: \"center\",\n cursor: \"default\",\n display: \"flex\",\n flexWrap: \"wrap\",\n justifyContent: \"space-between\",\n minHeight: 32,\n outline: \"0 !important\",\n position: \"relative\",\n transition: \"all 100ms\",\n backgroundColor: dark\n ? \"var(--color-slate-800)\"\n : \"var(--color-white)\",\n borderColor: invalid\n ? dark\n ? \"var(--color-red-400)\"\n : \"var(--color-red-900)\"\n : dark\n ? \"var(--color-slate-600)\"\n : \"var(--color-gray-200)\",\n borderStyle: \"solid\",\n borderWidth: 1,\n borderRadius: \"6px\",\n boxSizing: \"border-box\",\n };\n },\n option: (baseStyles, state) => {\n return {\n ...baseStyles,\n backgroundColor: state.isSelected\n ? dark\n ? \"var(--color-slate-700)\"\n : \"var(--color-slate-50)\"\n : dark\n ? \"var(--color-slate-800)\"\n : \"var(--color-white)\",\n color: dark ? \"var(--color-slate-50)\" : \"var(--color-gray-800)\",\n \":hover\": {\n backgroundColor: dark\n ? \"var(--color-slate-700)\"\n : \"var(--color-slate-50)\",\n },\n };\n },\n menuList: (baseStyles) => ({\n ...baseStyles,\n padding: 0,\n borderRadius: \"6px\",\n }),\n }}\n theme={(theme) => ({\n ...theme,\n colors: {\n ...theme.colors,\n primary: dark ? \"var(--color-slate-700)\" : \"var(--color-slate-100)\",\n primary25: dark ? \"var(--color-slate-800)\" : \"var(--color-slate-50)\",\n primary50: dark ? \"var(--color-slate-700)\" : \"var(--color-slate-100)\",\n primary75: dark ? \"var(--color-slate-700)\" : \"var(--color-slate-100)\",\n danger: dark ? \"var(--color-red-400)\" : \"var(--color-red-900)\",\n dangerLight: dark ? \"var(--color-red-900)\" : \"var(--color-red-100)\",\n neutral0: dark ? \"var(--color-slate-800)\" : \"var(--color-white)\",\n neutral5: dark ? \"var(--color-slate-800)\" : \"var(--color-gray-50)\",\n neutral10: dark ? \"var(--color-slate-700)\" : \"var(--color-gray-100)\",\n neutral20: dark ? \"var(--color-slate-600)\" : \"var(--color-gray-200)\",\n neutral30: dark ? \"var(--color-slate-600)\" : \"var(--color-gray-300)\",\n neutral40: dark ? \"var(--color-slate-400)\" : \"var(--color-gray-400)\",\n neutral50: dark ? \"var(--color-slate-300)\" : \"var(--color-gray-500)\",\n neutral60: dark ? \"var(--color-slate-200)\" : \"var(--color-gray-600)\",\n neutral70: dark ? \"var(--color-slate-100)\" : \"var(--color-gray-700)\",\n neutral80: dark ? \"var(--color-slate-50)\" : \"var(--color-gray-800)\",\n neutral90: dark ? \"var(--color-slate-50)\" : \"var(--color-gray-900)\",\n },\n })}\n />\n );\n}\n","import { PowerhouseButton } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\nimport { useState } from \"react\";\n\nexport type CookieInput = {\n id: string;\n label: string;\n value: boolean;\n};\n\nexport interface CookieBannerProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n \"onSubmit\"\n> {\n cookies: CookieInput[];\n submitLabel?: string;\n rejectLabel?: string;\n onSubmit?: (cookies: CookieInput[]) => void;\n onReject?: () => void;\n}\n\nexport const CookieBanner: React.FC<CookieBannerProps> = (props) => {\n const {\n children,\n cookies,\n submitLabel,\n rejectLabel,\n onSubmit = () => {},\n onReject = () => {},\n className,\n ...divProps\n } = props;\n\n const [cookiesValue, setCookiesValue] = useState(cookies);\n\n const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const { id, checked } = event.target;\n\n setCookiesValue((prevState) =>\n prevState.map((cookie) =>\n cookie.id === id ? { ...cookie, value: checked } : cookie,\n ),\n );\n };\n\n const buttonStyles = \"min-w-64 h-8 text-base\";\n\n return (\n <div\n className={twMerge(\n \"flex flex-col items-center\",\n typeof className === \"string\" && className,\n )}\n {...divProps}\n >\n <div className=\"text-center\">{children}</div>\n <div className=\"my-8 flex gap-x-16 text-sm font-medium\">\n {cookiesValue.map((cookie, i) => (\n <div className=\"cursor-pointer\" key={i}>\n <input\n checked={cookie.value}\n className=\"mr-1 size-3 cursor-pointer rounded-sm border-2 border-gray-900 accent-gray-900 focus:outline-none dark:border-slate-50\"\n id={cookie.id}\n onChange={handleOnChange}\n type=\"checkbox\"\n />\n <label\n className=\"cursor-pointer text-gray-900 select-none dark:text-slate-50\"\n htmlFor={cookie.id}\n >\n {cookie.label}\n </label>\n </div>\n ))}\n </div>\n <div className=\"flex gap-x-8\">\n <PowerhouseButton\n className={buttonStyles}\n color=\"light\"\n onClick={() => onReject()}\n size=\"small\"\n key={\"button-reject\"}\n >\n {rejectLabel}\n </PowerhouseButton>\n <PowerhouseButton\n className={buttonStyles}\n onClick={() => onSubmit(cookiesValue)}\n size=\"small\"\n key={\"button-submit\"}\n >\n {submitLabel}\n </PowerhouseButton>\n </div>\n </div>\n );\n};\n","import type { ComponentProps } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\nconst defaultStyle =\n \"min-h-12 min-w-35.5 flex-1 transform place-items-center rounded-xl px-6 py-3 text-base font-semibold transition-all outline-none hover:scale-105 active:opacity-75 disabled:cursor-not-allowed disabled:hover:scale-none\";\n\nexport function ModalButton(\n props: ComponentProps<\"button\"> & { variant: \"confirm\" | \"cancel\" },\n) {\n const { variant, className, ...rest } = props;\n const confirmStyle = twMerge(\n defaultStyle,\n \"bg-gray-800 text-gray-50 dark:bg-slate-100 dark:text-slate-900\",\n );\n const cancelStyle = twMerge(\n defaultStyle,\n \"bg-gray-400 text-gray-50 dark:bg-slate-400 dark:text-slate-900\",\n );\n const variantStyle = twMerge(\n variant === \"confirm\" ? confirmStyle : cancelStyle,\n className,\n );\n return <button className={variantStyle} {...rest} />;\n}\n","import { Modal } from \"#design-system\";\nimport type { ComponentPropsWithoutRef, ReactNode } from \"react\";\nimport { ModalButton } from \"./modal-button.js\";\n\ntype ModalProps = ComponentPropsWithoutRef<typeof Modal>;\n\nexport type ConfirmationModalProps = {\n readonly open?: boolean;\n readonly onOpenChange?: (open: boolean) => void;\n readonly header: ReactNode;\n readonly body?: ReactNode;\n readonly cancelLabel: string;\n readonly continueLabel: string;\n readonly onCancel: () => void;\n readonly onContinue: () => void;\n readonly continueDisabled?: boolean;\n readonly overlayProps?: ModalProps[\"overlayProps\"];\n readonly contentProps?: ModalProps[\"contentProps\"];\n};\n\nexport function ConnectConfirmationModal(props: ConfirmationModalProps) {\n const {\n open,\n onOpenChange,\n header,\n body,\n cancelLabel,\n continueLabel,\n onCancel,\n onContinue,\n continueDisabled,\n overlayProps,\n contentProps,\n } = props;\n\n return (\n <Modal\n open={open}\n onOpenChange={onOpenChange}\n overlayProps={overlayProps}\n contentProps={contentProps}\n >\n <div className=\"w-[400px] p-6\">\n <div className=\"pb-2 text-2xl font-bold text-gray-900 dark:text-slate-100\">\n {header}\n </div>\n <div className=\"my-6 rounded-md bg-gray-50 p-4 text-center text-gray-900 dark:bg-slate-700 dark:text-slate-100\">\n {body}\n </div>\n <div className=\"mt-8 flex justify-between gap-3\">\n <ModalButton variant=\"cancel\" onClick={onCancel}>\n {cancelLabel}\n </ModalButton>\n <ModalButton\n variant=\"confirm\"\n disabled={continueDisabled}\n onClick={onContinue}\n >\n {continueLabel}\n </ModalButton>\n </div>\n </div>\n </Modal>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport type { ColumnInfo } from \"./table-view.js\";\n\nexport type TableInfo = {\n readonly name: string;\n readonly columns: ColumnInfo[];\n};\n\ntype TreeExpandedState = Record<string, boolean>;\n\nexport type SchemaTreeSidebarProps = {\n readonly schema: string;\n readonly tables: TableInfo[];\n readonly selectedTable?: string;\n readonly onSelectTable: (table: string) => void;\n readonly onRefresh?: () => void | Promise<void>;\n readonly loading?: boolean;\n};\n\ntype TreeItemProps = {\n readonly label: React.ReactNode;\n readonly depth: number;\n readonly expanded?: boolean;\n readonly selected?: boolean;\n readonly hasChildren?: boolean;\n readonly icon?: React.ReactNode;\n readonly onToggle?: () => void;\n readonly onClick?: () => void;\n readonly children?: React.ReactNode;\n};\n\nconst INDENT_PX = 16;\n\nfunction TreeItem({\n label,\n depth,\n expanded,\n selected,\n hasChildren,\n icon,\n onToggle,\n onClick,\n children,\n}: TreeItemProps) {\n const handleChevronClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n onToggle?.();\n };\n\n return (\n <div>\n <div\n className={twMerge(\n \"flex cursor-pointer items-center gap-1 py-1 pr-2 text-sm hover:bg-gray-100 dark:hover:bg-slate-700\",\n selected && \"bg-blue-50 dark:bg-blue-900\",\n )}\n style={{ paddingLeft: depth * INDENT_PX + 4 }}\n onClick={onClick}\n >\n {hasChildren ? (\n <button\n className=\"flex size-4 shrink-0 items-center justify-center text-gray-500 hover:text-gray-700 dark:text-slate-200 dark:hover:text-slate-100\"\n onClick={handleChevronClick}\n type=\"button\"\n >\n <Icon\n className={twMerge(\n \"transition-transform\",\n expanded && \"rotate-90\",\n )}\n name=\"CaretRight\"\n size={12}\n />\n </button>\n ) : (\n <span className=\"w-4 shrink-0\" />\n )}\n {icon && (\n <span className=\"shrink-0 text-gray-500 dark:text-slate-400\">\n {icon}\n </span>\n )}\n <span className=\"min-w-0 flex-1 truncate text-gray-700 dark:text-slate-200\">\n {label}\n </span>\n {selected && (\n <span className=\"ml-auto size-2 shrink-0 rounded-full bg-blue-500 dark:bg-blue-400\" />\n )}\n </div>\n {expanded && children}\n </div>\n );\n}\n\nfunction ColumnItem({\n column,\n depth,\n}: {\n readonly column: ColumnInfo;\n readonly depth: number;\n}) {\n const typeLabel =\n column.dataType.length > 10\n ? column.dataType.slice(0, 10) + \"…\"\n : column.dataType;\n\n return (\n <div\n className=\"flex items-center gap-1 py-0.5 pr-2 text-xs text-gray-500 dark:text-slate-200\"\n style={{ paddingLeft: depth * INDENT_PX + 4 }}\n >\n <span className=\"w-4 shrink-0\" />\n <span className=\"truncate\">{column.name}</span>\n <span className=\"ml-auto shrink-0 text-gray-400 dark:text-slate-200\">\n ({typeLabel})\n </span>\n </div>\n );\n}\n\nexport function SchemaTreeSidebar({\n schema,\n tables,\n selectedTable,\n onSelectTable,\n onRefresh,\n loading,\n}: SchemaTreeSidebarProps) {\n const [expandedNodes, setExpandedNodes] = useState<TreeExpandedState>({\n [schema]: true,\n });\n\n const toggleNode = (nodeId: string) => {\n setExpandedNodes((prev) => ({\n ...prev,\n [nodeId]: !prev[nodeId],\n }));\n };\n\n const handleTableClick = (tableName: string) => {\n onSelectTable(tableName);\n setExpandedNodes((prev) => ({\n ...prev,\n [tableName]: !prev[tableName],\n }));\n };\n\n const isSchemaExpanded = expandedNodes[schema] ?? false;\n\n const handleRefreshClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n void onRefresh?.();\n };\n\n return (\n <div className=\"flex flex-col overflow-auto pt-4 text-sm\">\n <TreeItem\n depth={0}\n expanded={isSchemaExpanded}\n hasChildren={tables.length > 0}\n icon={\n <Icon\n name={isSchemaExpanded ? \"FolderOpen\" : \"FolderClose\"}\n size={16}\n />\n }\n label={\n <div className=\"flex flex-1 items-center\">\n <span className=\"truncate\">{schema}</span>\n {onRefresh && (\n <button\n className=\"ml-auto p-0.5 text-gray-400 hover:text-gray-600 dark:text-slate-200 dark:hover:text-slate-100\"\n onClick={handleRefreshClick}\n type=\"button\"\n disabled={loading}\n >\n <Icon\n name=\"Reload\"\n size={14}\n className={loading ? \"animate-spin\" : undefined}\n />\n </button>\n )}\n </div>\n }\n onClick={() => toggleNode(schema)}\n onToggle={() => toggleNode(schema)}\n >\n {tables.map((table) => {\n const isTableExpanded = expandedNodes[table.name] ?? false;\n const isSelected = selectedTable === table.name;\n\n return (\n <TreeItem\n key={table.name}\n depth={1}\n expanded={isTableExpanded}\n hasChildren={table.columns.length > 0}\n icon={<Icon name=\"TreeViewSlash\" size={16} />}\n label={table.name}\n selected={isSelected}\n onClick={() => handleTableClick(table.name)}\n onToggle={() => toggleNode(table.name)}\n >\n {table.columns.map((col) => (\n <ColumnItem key={col.name} column={col} depth={2} />\n ))}\n </TreeItem>\n );\n })}\n </TreeItem>\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport type {\n CSSProperties,\n ForwardedRef,\n ReactNode,\n Ref,\n RefAttributes,\n} from \"react\";\nimport { forwardRef, useState } from \"react\";\nimport { twJoin, twMerge } from \"tailwind-merge\";\n\nexport type ConnectSelectItem<TValue extends string> = {\n readonly value: TValue;\n readonly displayValue?: React.ReactNode;\n readonly description?: React.ReactNode;\n readonly icon?: React.JSX.Element;\n readonly disabled?: boolean;\n};\n\nexport type ConnectSelectProps<TValue extends string> = {\n items: readonly ConnectSelectItem<TValue>[];\n value: TValue;\n id: string;\n onChange: (value: TValue) => void;\n containerClassName?: string;\n menuClassName?: string;\n itemClassName?: string;\n borderRadius?: CSSProperties[\"borderRadius\"];\n absolutePositionMenu?: boolean;\n};\n\nfunction fixedForwardRef<T, P = Record<string, never>>(\n render: (props: P, ref: Ref<T>) => ReactNode,\n): (props: P & RefAttributes<T>) => ReactNode {\n // @ts-expect-error - This is a hack to make the types work\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return forwardRef(render) as any;\n}\n\nexport const ConnectSelect = /* @__PURE__ */ fixedForwardRef(function Select<\n TValue extends string,\n>(props: ConnectSelectProps<TValue>, ref: ForwardedRef<HTMLDivElement>) {\n const {\n items,\n value,\n id,\n onChange,\n containerClassName,\n menuClassName,\n itemClassName,\n absolutePositionMenu = false,\n borderRadius = \"6px\",\n } = props;\n const [showItems, setShowItems] = useState(false);\n const selectedItem = getItemByValue(value) ?? items[0];\n function onItemClick(item: ConnectSelectItem<TValue>) {\n if (item.disabled) return;\n onChange(item.value);\n setShowItems(false);\n }\n function getItemByValue(value: TValue) {\n return items.find((item) => item.value === value);\n }\n\n const itemsToShow = items.filter((item) => item.value !== value);\n\n return (\n <div\n className={twMerge(\n \"border border-gray-200 bg-gray-50 text-gray-900 transition-[border-radius] dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n absolutePositionMenu && \"relative\",\n containerClassName,\n )}\n data-open={showItems}\n ref={ref}\n style={{\n borderRadius: borderRadius,\n }}\n >\n <div\n className={twMerge(\n \"flex min-w-[360px] cursor-pointer items-center justify-between pr-3 text-gray-900 outline-none dark:text-slate-100\",\n menuClassName,\n )}\n id={id}\n onClick={() => setShowItems(!showItems)}\n >\n <ItemContainer {...selectedItem} className={itemClassName} />\n <Icon\n className={twJoin(\"transition\", showItems ? \"\" : \"-rotate-90\")}\n name=\"ChevronDown\"\n />\n </div>\n <div\n className={twMerge(\n \"max-h-0 w-full overflow-hidden bg-inherit transition-[max-height] ease-in-out\",\n showItems && \"max-h-screen\",\n absolutePositionMenu && \"absolute\",\n )}\n style={{\n borderRadius: `0 0 ${borderRadius} ${borderRadius}`,\n }}\n >\n {itemsToShow.map((item) => (\n <ItemContainer\n key={item.value}\n {...item}\n className={itemClassName}\n onItemClick={() => onItemClick(item)}\n />\n ))}\n </div>\n </div>\n );\n});\n\nfunction ItemContainer<TValue extends string>(\n props: ConnectSelectItem<TValue> & {\n readonly onItemClick?: () => void;\n readonly className?: string;\n },\n) {\n const {\n className,\n disabled,\n onItemClick,\n icon,\n displayValue,\n value,\n description,\n } = props;\n\n return (\n <div\n className={twMerge(\n disabled\n ? \"cursor-not-allowed text-gray-500 dark:text-slate-400\"\n : \"text-gray-900 dark:text-slate-100\",\n \"flex size-full cursor-pointer items-center gap-2 bg-inherit py-3 pl-3 text-start outline-none\",\n className,\n )}\n onClick={onItemClick}\n >\n {icon}\n <div>\n <p className=\"text-inherit capitalize\">\n {displayValue ?? value.toLowerCase()}\n </p>\n <p className=\"text-xs text-gray-700 dark:text-slate-200\">\n {description}\n </p>\n </div>\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ConnectSelect } from \"../../select/select.js\";\nimport type {\n ColumnInfo,\n FilterClause,\n FilterGroup,\n FilterOperator,\n} from \"./table-view.js\";\n\nexport type FilterBarProps = {\n readonly columns: ColumnInfo[];\n readonly filters: FilterGroup | undefined;\n readonly onFiltersChange: (filters: FilterGroup | undefined) => void;\n};\n\nfunction getAvailableOperators(column: ColumnInfo): FilterOperator[] {\n const baseOperators: FilterOperator[] = [\n \"=\",\n \"!=\",\n \">\",\n \"<\",\n \">=\",\n \"<=\",\n \"IS NULL\",\n \"IS NOT NULL\",\n ];\n\n const dataType = column.dataType.toLowerCase();\n\n // Text types get LIKE and ILIKE\n if (\n dataType.includes(\"varchar\") ||\n dataType.includes(\"text\") ||\n dataType.includes(\"char\")\n ) {\n return [...baseOperators, \"LIKE\", \"ILIKE\"];\n }\n\n // Numeric types don't get LIKE/ILIKE\n if (\n dataType.includes(\"int\") ||\n dataType.includes(\"decimal\") ||\n dataType.includes(\"numeric\") ||\n dataType.includes(\"real\") ||\n dataType.includes(\"double\") ||\n dataType.includes(\"float\") ||\n dataType.includes(\"bigint\") ||\n dataType.includes(\"smallint\")\n ) {\n return baseOperators;\n }\n\n // Default: all operators except LIKE/ILIKE\n return baseOperators;\n}\n\nfunction getInputType(\n column: ColumnInfo,\n operator: FilterOperator,\n): \"text\" | \"number\" | \"datetime-local\" {\n if (operator === \"IS NULL\" || operator === \"IS NOT NULL\") {\n return \"text\"; // Will be hidden anyway\n }\n\n const dataType = column.dataType.toLowerCase();\n\n if (\n dataType.includes(\"int\") ||\n dataType.includes(\"decimal\") ||\n dataType.includes(\"numeric\") ||\n dataType.includes(\"real\") ||\n dataType.includes(\"double\") ||\n dataType.includes(\"float\") ||\n dataType.includes(\"bigint\") ||\n dataType.includes(\"smallint\")\n ) {\n return \"number\";\n }\n\n if (\n dataType.includes(\"timestamp\") ||\n dataType.includes(\"date\") ||\n dataType.includes(\"time\")\n ) {\n return \"datetime-local\";\n }\n\n return \"text\";\n}\n\nfunction FilterClauseComponent({\n clause,\n columns,\n onUpdate,\n onRemove,\n showConnector,\n connector,\n onConnectorChange,\n}: {\n readonly clause: FilterClause;\n readonly columns: ColumnInfo[];\n readonly onUpdate: (clause: FilterClause) => void;\n readonly onRemove: () => void;\n readonly showConnector: boolean;\n readonly connector: \"AND\" | \"OR\";\n readonly onConnectorChange: (connector: \"AND\" | \"OR\") => void;\n}) {\n const column = columns.find((c) => c.name === clause.column);\n const availableOperators = column\n ? getAvailableOperators(column)\n : ([\"=\", \"!=\"] as FilterOperator[]);\n const inputType = column ? getInputType(column, clause.operator) : \"text\";\n const showValueInput =\n clause.operator !== \"IS NULL\" && clause.operator !== \"IS NOT NULL\";\n\n const columnItems = useMemo(\n (): Array<{ value: string; displayValue: string }> =>\n columns.map((col) => ({\n value: col.name,\n displayValue: col.name,\n })),\n [columns],\n );\n\n const operatorItems = useMemo(\n (): Array<{ value: FilterOperator; displayValue: string }> =>\n availableOperators.map((op) => ({\n value: op,\n displayValue: op,\n })),\n [availableOperators],\n );\n\n const connectorItems = useMemo(\n (): Array<{ value: \"AND\" | \"OR\"; displayValue: string }> => [\n { value: \"AND\", displayValue: \"AND\" },\n { value: \"OR\", displayValue: \"OR\" },\n ],\n [],\n );\n\n const handleColumnChange = useCallback(\n (columnName: string) => {\n const newColumn = columns.find((c) => c.name === columnName);\n if (!newColumn) return;\n\n const newAvailableOperators = getAvailableOperators(newColumn);\n const newOperator = newAvailableOperators.includes(clause.operator)\n ? clause.operator\n : newAvailableOperators[0];\n\n onUpdate({\n ...clause,\n column: columnName,\n operator: newOperator,\n value: \"\",\n });\n },\n [clause, columns, onUpdate],\n );\n\n const handleOperatorChange = useCallback(\n (operator: FilterOperator) => {\n onUpdate({\n ...clause,\n operator,\n value:\n operator === \"IS NULL\" || operator === \"IS NOT NULL\"\n ? \"\"\n : clause.value,\n });\n },\n [clause, onUpdate],\n );\n\n const handleValueChange = useCallback(\n (value: string) => {\n onUpdate({\n ...clause,\n value,\n });\n },\n [clause, onUpdate],\n );\n\n return (\n <div className=\"flex items-center gap-2\">\n {showConnector && (\n <ConnectSelect<\"AND\" | \"OR\">\n absolutePositionMenu\n borderRadius=\"4px\"\n containerClassName=\"min-w-[80px]\"\n id={`connector-${clause.id}`}\n items={connectorItems}\n itemClassName=\"px-2 py-1 text-xs\"\n menuClassName=\"px-2 py-1 text-xs min-w-[80px]\"\n value={connector}\n onChange={onConnectorChange}\n />\n )}\n <ConnectSelect<string>\n absolutePositionMenu\n borderRadius=\"4px\"\n containerClassName=\"min-w-[150px]\"\n id={`column-${clause.id}`}\n items={columnItems}\n itemClassName=\"px-2 py-1 text-xs\"\n menuClassName=\"px-2 py-1 text-xs min-w-[150px]\"\n value={clause.column}\n onChange={handleColumnChange}\n />\n <ConnectSelect<FilterOperator>\n absolutePositionMenu\n borderRadius=\"4px\"\n containerClassName=\"min-w-[100px]\"\n id={`operator-${clause.id}`}\n items={operatorItems}\n itemClassName=\"px-2 py-1 text-xs\"\n menuClassName=\"px-2 py-1 text-xs min-w-[100px]\"\n value={clause.operator}\n onChange={handleOperatorChange}\n />\n {showValueInput && (\n <input\n className=\"min-w-[150px] rounded-sm border border-gray-300 bg-gray-50 px-2 py-1 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\"\n type={inputType}\n value={clause.value}\n onChange={(e) => handleValueChange(e.target.value)}\n />\n )}\n <button\n className=\"flex items-center justify-center rounded-sm p-1 text-gray-500 hover:bg-gray-200 hover:text-gray-700 dark:text-slate-400 dark:hover:bg-slate-600 dark:hover:text-slate-100\"\n onClick={onRemove}\n title=\"Remove filter\"\n type=\"button\"\n >\n <Icon name=\"Xmark\" size={14} />\n </button>\n </div>\n );\n}\n\nexport function FilterBar({\n columns,\n filters,\n onFiltersChange,\n}: FilterBarProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const handleAddFilter = useCallback(() => {\n const newClause: FilterClause = {\n id: `filter-${Date.now()}-${Math.random()}`,\n column: columns[0]?.name ?? \"\",\n operator: \"=\",\n value: \"\",\n };\n\n if (!filters) {\n onFiltersChange({\n clauses: [newClause],\n connectors: [],\n });\n } else {\n onFiltersChange({\n clauses: [...filters.clauses, newClause],\n connectors: [\n ...filters.connectors,\n filters.clauses.length > 0 ? \"AND\" : (\"AND\" as const),\n ],\n });\n }\n setIsExpanded(true);\n }, [columns, filters, onFiltersChange]);\n\n const handleUpdateClause = useCallback(\n (index: number, clause: FilterClause) => {\n if (!filters) return;\n\n const newClauses = [...filters.clauses];\n newClauses[index] = clause;\n\n onFiltersChange({\n ...filters,\n clauses: newClauses,\n });\n },\n [filters, onFiltersChange],\n );\n\n const handleRemoveClause = useCallback(\n (index: number) => {\n if (!filters) return;\n\n const newClauses = filters.clauses.filter((_, i) => i !== index);\n const newConnectors = filters.connectors.filter(\n (_, i) => i !== index - 1,\n );\n\n if (newClauses.length === 0) {\n onFiltersChange(undefined);\n } else {\n onFiltersChange({\n clauses: newClauses,\n connectors: newConnectors,\n });\n }\n },\n [filters, onFiltersChange],\n );\n\n const handleConnectorChange = useCallback(\n (index: number, connector: \"AND\" | \"OR\") => {\n if (!filters) return;\n\n const newConnectors = [...filters.connectors];\n newConnectors[index] = connector;\n\n onFiltersChange({\n ...filters,\n connectors: newConnectors,\n });\n },\n [filters, onFiltersChange],\n );\n\n const hasFilters = filters && filters.clauses.length > 0;\n\n return (\n <div className=\"flex shrink-0 flex-col gap-2 rounded-lg border border-gray-300 bg-gray-50 p-2 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <div className=\"flex items-center justify-between\">\n <button\n className=\"flex items-center gap-1 text-xs text-gray-700 hover:text-gray-900 dark:text-slate-200 dark:hover:text-slate-50\"\n onClick={() => setIsExpanded(!isExpanded)}\n type=\"button\"\n >\n <Icon\n className={twMerge(\n \"transition-transform\",\n isExpanded && \"rotate-90\",\n )}\n name=\"ChevronDown\"\n size={12}\n />\n <span>Filters</span>\n {hasFilters && (\n <span className=\"rounded-sm bg-blue-100 px-1.5 py-0.5 text-xs text-blue-700 dark:bg-blue-800 dark:text-blue-100\">\n {filters.clauses.length}\n </span>\n )}\n </button>\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-2 py-1 text-xs text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={handleAddFilter}\n type=\"button\"\n >\n <Icon name=\"Plus\" size={12} />\n Add Filter\n </button>\n </div>\n\n {isExpanded && hasFilters && (\n <div className=\"flex flex-col gap-2\">\n {filters.clauses.map((clause, index) => (\n <FilterClauseComponent\n key={clause.id}\n clause={clause}\n columns={columns}\n connector={\n index > 0 ? (filters.connectors[index - 1] ?? \"AND\") : \"AND\"\n }\n onConnectorChange={(connector) =>\n handleConnectorChange(index - 1, connector)\n }\n onRemove={() => handleRemoveClause(index)}\n onUpdate={(updatedClause) =>\n handleUpdateClause(index, updatedClause)\n }\n showConnector={index > 0}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { FilterBar } from \"./filter-bar.js\";\n\nexport type ColumnInfo = {\n readonly name: string;\n readonly dataType: string;\n readonly isNullable: boolean;\n};\n\nexport type SortDirection = \"asc\" | \"desc\";\n\nexport type SortOptions = {\n readonly column: string;\n readonly direction: SortDirection;\n};\n\nexport type FilterOperator =\n | \"=\"\n | \"!=\"\n | \">\"\n | \"<\"\n | \">=\"\n | \"<=\"\n | \"LIKE\"\n | \"ILIKE\"\n | \"IS NULL\"\n | \"IS NOT NULL\";\n\nexport type FilterClause = {\n readonly id: string;\n readonly column: string;\n readonly operator: FilterOperator;\n readonly value: string;\n};\n\nexport type FilterGroup = {\n readonly clauses: FilterClause[];\n readonly connectors: (\"AND\" | \"OR\")[]; // connectors[i] connects clauses[i] and clauses[i+1]\n};\n\nexport type PaginationState = {\n readonly offset: number;\n readonly limit: number;\n readonly total: number | null;\n};\n\nexport type TableViewProps = {\n readonly columns: ColumnInfo[];\n readonly rows: Record<string, unknown>[];\n readonly pagination: PaginationState;\n readonly onPageChange: (offset: number) => void;\n readonly onSort?: (sort: SortOptions) => void;\n readonly currentSort?: SortOptions;\n readonly loading?: boolean;\n readonly filters?: FilterGroup;\n readonly onFiltersChange?: (filters: FilterGroup | undefined) => void;\n /** Callback to get all rows as CSV. If provided, \"Copy All\" copies all pages. */\n readonly onCopyAll?: () => Promise<string>;\n};\n\nfunction formatCellValue(value: unknown): string {\n if (value === null) return \"NULL\";\n if (value === undefined) return \"\";\n if (typeof value === \"object\") return JSON.stringify(value);\n if (typeof value === \"function\") return \"[function]\";\n if (typeof value === \"symbol\") return value.toString();\n return String(value as string | number | boolean | bigint);\n}\n\nfunction escapeCsvValue(value: string): string {\n // If the value contains comma, newline, or double quote, wrap it in quotes and escape quotes\n if (value.includes(\",\") || value.includes(\"\\n\") || value.includes('\"')) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n }\n return value;\n}\n\nfunction rowToCsv(row: Record<string, unknown>, columns: ColumnInfo[]): string {\n return columns\n .map((column) => {\n const value = formatCellValue(row[column.name]);\n return escapeCsvValue(value);\n })\n .join(\",\");\n}\n\nexport function rowsToCsv(\n rows: Record<string, unknown>[],\n columns: ColumnInfo[],\n): string {\n const header = columns.map((col) => escapeCsvValue(col.name)).join(\",\");\n const dataRows = rows.map((row) => rowToCsv(row, columns));\n return [header, ...dataRows].join(\"\\n\");\n}\n\nasync function copyToClipboard(text: string): Promise<void> {\n await navigator.clipboard.writeText(text);\n}\n\nfunction SortIcon({\n direction,\n active,\n}: {\n readonly direction: SortDirection;\n readonly active: boolean;\n}) {\n if (!active) {\n return (\n <Icon\n className=\"opacity-0 group-hover:opacity-50\"\n name=\"CaretSort\"\n size={12}\n />\n );\n }\n\n return (\n <Icon\n className={direction === \"asc\" ? \"rotate-180\" : undefined}\n name=\"TriangleDown\"\n size={12}\n />\n );\n}\n\nexport function TableView({\n columns,\n rows,\n pagination,\n onPageChange,\n onSort,\n currentSort,\n loading = false,\n filters,\n onFiltersChange,\n onCopyAll,\n}: TableViewProps) {\n const { offset, limit, total } = pagination;\n\n const currentPage = Math.floor(offset / limit);\n const totalPages = total !== null ? Math.ceil(total / limit) : 0;\n const startItem = total === 0 ? 0 : offset + 1;\n const endItem =\n total !== null ? Math.min(offset + limit, total) : offset + rows.length;\n\n const goToPage = (page: number) => {\n onPageChange(page * limit);\n };\n\n const handleSort = (columnName: string) => {\n if (!onSort) return;\n\n const newDirection: SortDirection =\n currentSort?.column === columnName && currentSort.direction === \"asc\"\n ? \"desc\"\n : \"asc\";\n\n onSort({ column: columnName, direction: newDirection });\n };\n\n const getVisiblePages = (): number[] => {\n const maxVisible = 3;\n\n if (totalPages <= maxVisible) {\n return Array.from({ length: totalPages }, (_, i) => i);\n }\n\n const start = Math.max(\n 0,\n Math.min(currentPage - 1, totalPages - maxVisible),\n );\n const end = Math.min(totalPages - 1, start + maxVisible - 1);\n\n const pages: number[] = [];\n for (let i = start; i <= end; i++) {\n pages.push(i);\n }\n\n return pages;\n };\n\n const visiblePages = getVisiblePages();\n const [copying, setCopying] = useState(false);\n const [copiedRowIndex, setCopiedRowIndex] = useState<number | null>(null);\n\n const handleCopyAll = async () => {\n if (rows.length === 0) return;\n setCopying(true);\n try {\n // If onCopyAll is provided, use it to get all rows; otherwise copy visible rows\n const csv = onCopyAll ? await onCopyAll() : rowsToCsv(rows, columns);\n await copyToClipboard(csv);\n setTimeout(() => setCopying(false), 1000);\n } catch (err) {\n console.error(\"Failed to copy to clipboard:\", err);\n setCopying(false);\n }\n };\n\n const handleCopyRow = async (rowIndex: number) => {\n if (rowIndex < 0 || rowIndex >= rows.length) return;\n setCopiedRowIndex(rowIndex);\n try {\n const csv = rowToCsv(rows[rowIndex], columns);\n await copyToClipboard(csv);\n setTimeout(() => setCopiedRowIndex(null), 1000);\n } catch (err) {\n console.error(\"Failed to copy to clipboard:\", err);\n setCopiedRowIndex(null);\n }\n };\n\n return (\n <div className=\"flex h-full flex-col gap-2\">\n {onFiltersChange && (\n <FilterBar\n columns={columns}\n filters={filters}\n onFiltersChange={onFiltersChange}\n />\n )}\n <div className=\"flex shrink-0 items-center justify-between text-sm\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-gray-700 dark:text-slate-200\">\n {loading\n ? \"Loading...\"\n : total !== null\n ? `Showing ${startItem.toLocaleString()}-${endItem.toLocaleString()} of ${total.toLocaleString()}`\n : `Showing ${rows.length.toLocaleString()} rows`}\n </span>\n {rows.length > 0 && (\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-2 py-1 text-xs text-gray-700 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={loading || copying}\n onClick={() => void handleCopyAll()}\n title=\"Copy all rows as CSV\"\n type=\"button\"\n >\n <Icon name={copying ? \"Check\" : \"Copy\"} size={14} />\n {copying ? \"Copied!\" : \"Copy All\"}\n </button>\n )}\n </div>\n\n {total !== null && total > limit && (\n <div className=\"flex gap-1\">\n <button\n className=\"rounded-sm border border-gray-300 bg-gray-50 px-2 py-1 text-xs text-gray-700 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={currentPage === 0}\n onClick={() => goToPage(0)}\n type=\"button\"\n >\n First\n </button>\n <button\n className=\"rounded-sm border border-gray-300 bg-gray-50 px-2 py-1 text-xs text-gray-700 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={currentPage === 0}\n onClick={() => goToPage(currentPage - 1)}\n type=\"button\"\n >\n <Icon className=\"rotate-90\" name=\"ChevronDown\" size={14} />\n </button>\n\n {visiblePages[0] > 0 && (\n <span className=\"flex items-center px-1 text-xs text-gray-500 dark:text-slate-400\">\n ...\n </span>\n )}\n\n {visiblePages.map((page) => (\n <button\n key={page}\n className={twMerge(\n \"min-w-8 rounded-sm border px-2 py-1 text-xs\",\n page === currentPage\n ? \"border-blue-500 bg-blue-50 text-blue-700 dark:border-blue-400 dark:bg-blue-900 dark:text-blue-100\"\n : \"border-gray-300 bg-gray-50 text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\",\n )}\n onClick={() => goToPage(page)}\n type=\"button\"\n >\n {page + 1}\n </button>\n ))}\n\n {visiblePages[visiblePages.length - 1] < totalPages - 1 && (\n <span className=\"flex items-center px-1 text-xs text-gray-500 dark:text-slate-400\">\n ...\n </span>\n )}\n\n <button\n className=\"rounded-sm border border-gray-300 bg-gray-50 px-2 py-1 text-xs text-gray-700 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={currentPage >= totalPages - 1}\n onClick={() => goToPage(currentPage + 1)}\n type=\"button\"\n >\n <Icon className=\"-rotate-90\" name=\"ChevronDown\" size={14} />\n </button>\n <button\n className=\"rounded-sm border border-gray-300 bg-gray-50 px-2 py-1 text-xs text-gray-700 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={currentPage >= totalPages - 1}\n onClick={() => goToPage(totalPages - 1)}\n type=\"button\"\n >\n Last\n </button>\n </div>\n )}\n </div>\n\n <div\n className={twMerge(\n \"max-h-full overflow-auto rounded-lg border border-gray-300 transition-opacity dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n \"scrollbar-thin scrollbar-thumb-rounded-md scrollbar-track-transparent\",\n \"scrollbar-thumb-gray-300 dark:scrollbar-thumb-slate-600\",\n loading && \"pointer-events-none opacity-50\",\n )}\n >\n <table className=\"w-full border-collapse\">\n <thead className=\"sticky top-0 bg-gray-100 dark:bg-slate-700\">\n <tr>\n <th className=\"w-12 p-2 text-center text-xs font-medium text-gray-700 dark:text-slate-200\">\n <span className=\"sr-only\">Copy</span>\n </th>\n {columns.map((column, index) => {\n const isActive = currentSort?.column === column.name;\n const sortDirection = isActive ? currentSort.direction : \"asc\";\n\n return (\n <th\n key={column.name}\n className={twMerge(\n \"group px-3 py-2 text-left text-xs font-medium text-gray-700 dark:text-slate-200\",\n index > 0 &&\n \"border-l border-gray-300 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n onSort &&\n \"cursor-pointer hover:bg-gray-200 hover:text-gray-900 dark:hover:bg-slate-600 dark:hover:text-slate-100\",\n )}\n onClick={() => onSort && handleSort(column.name)}\n >\n <div className=\"flex items-center gap-1\">\n <span className=\"truncate\">{column.name}</span>\n {onSort && (\n <SortIcon active={isActive} direction={sortDirection} />\n )}\n </div>\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {rows.length === 0 ? (\n <tr>\n <td\n className=\"px-3 py-8 text-center text-sm text-gray-500 dark:text-slate-400\"\n colSpan={columns.length + 1}\n >\n No data\n </td>\n </tr>\n ) : (\n rows.map((row, rowIndex) => (\n <tr\n key={rowIndex}\n className=\"odd:bg-white even:bg-gray-50 hover:bg-blue-50 dark:odd:bg-slate-800 dark:even:bg-slate-800 dark:hover:bg-blue-900\"\n >\n <td className=\"p-2 text-center\">\n <button\n className=\"flex items-center justify-center rounded-sm p-1 text-gray-500 hover:bg-gray-200 hover:text-gray-700 dark:text-slate-400 dark:hover:bg-slate-600 dark:hover:text-slate-100\"\n onClick={() => void handleCopyRow(rowIndex)}\n title=\"Copy row as CSV\"\n type=\"button\"\n >\n <Icon\n name={copiedRowIndex === rowIndex ? \"Check\" : \"Copy\"}\n size={14}\n />\n </button>\n </td>\n {columns.map((column, colIndex) => (\n <td\n key={column.name}\n className={twMerge(\n \"px-3 py-2 text-xs text-gray-900 dark:text-slate-50\",\n colIndex > 0 &&\n \"border-l border-gray-300 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n )}\n >\n <span\n className={twMerge(\n \"block truncate\",\n row[column.name] === null &&\n \"text-gray-400 italic dark:text-slate-500\",\n )}\n title={formatCellValue(row[column.name])}\n >\n {formatCellValue(row[column.name])}\n </span>\n </td>\n ))}\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n </div>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { ConnectConfirmationModal } from \"../modal/confirmation-modal.js\";\nimport {\n SchemaTreeSidebar,\n type TableInfo,\n} from \"./components/schema-tree-sidebar.js\";\nimport {\n TableView,\n rowsToCsv,\n type ColumnInfo,\n type FilterGroup,\n type PaginationState,\n type SortOptions,\n} from \"./components/table-view.js\";\n\n// Re-export types\nexport type { TableInfo } from \"./components/schema-tree-sidebar.js\";\nexport type {\n ColumnInfo,\n FilterClause,\n FilterGroup,\n SortOptions,\n} from \"./components/table-view.js\";\n\nexport type GetTableRowsOptions = {\n readonly schema?: string;\n readonly limit: number;\n readonly offset: number;\n readonly sort?: SortOptions;\n readonly filters?: FilterGroup;\n};\n\nexport type TablePage = {\n readonly columns: string[];\n readonly rows: Record<string, unknown>[];\n readonly total: number | null;\n};\nexport interface DbClient {\n readonly kind: string;\n listTables(schema?: string): Promise<string[]>;\n getTableSchema(table: string, schema?: string): Promise<ColumnInfo[]>;\n getTableRows(table: string, options: GetTableRowsOptions): Promise<TablePage>;\n}\n\nexport type PgVersionControl = {\n readonly currentPgVersion: number | null;\n readonly supportedPgVersions: readonly number[];\n readonly onResetToPgVersion: (major: number) => void | Promise<void>;\n};\n\n/** Props for the main DBExplorer component */\nexport type DBExplorerProps = {\n readonly schema: string;\n readonly getTables: () => Promise<TableInfo[]>;\n readonly getTableRows: (\n table: string,\n options: GetTableRowsOptions,\n ) => Promise<TablePage>;\n readonly getDefaultSort?: (table: string) => SortOptions | undefined;\n readonly pageSize?: number;\n readonly onImportDb?: (sqlContent: string) => void | Promise<void>;\n readonly onExportDb?: () => void | Promise<void>;\n readonly pgVersionControl?: PgVersionControl;\n};\n\nconst DEFAULT_PAGE_SIZE = 50;\n\nexport function DBExplorer({\n schema,\n getTables,\n getTableRows,\n getDefaultSort,\n pageSize = DEFAULT_PAGE_SIZE,\n onImportDb,\n onExportDb,\n pgVersionControl,\n}: DBExplorerProps) {\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [tables, setTables] = useState<TableInfo[]>([]);\n const [tablesLoading, setTablesLoading] = useState(true);\n const [selectedTable, setSelectedTable] = useState<string | undefined>();\n const [tableData, setTableData] = useState<TablePage | null>(null);\n const [pagination, setPagination] = useState<PaginationState>({\n offset: 0,\n limit: pageSize,\n total: null,\n });\n const [sort, setSort] = useState<SortOptions | undefined>();\n const [filters, setFilters] = useState<FilterGroup | undefined>();\n const [loading, setLoading] = useState(false);\n const [pendingImport, setPendingImport] = useState<string | null>(null);\n const [pendingResetMajor, setPendingResetMajor] = useState<number | null>(\n null,\n );\n const [resetting, setResetting] = useState(false);\n\n const columns = tables.find((t) => t.name === selectedTable)?.columns ?? [];\n\n const loadTableData = useCallback(async () => {\n if (!selectedTable) return;\n\n setLoading(true);\n const data = await getTableRows(selectedTable, {\n schema,\n limit: pagination.limit,\n offset: pagination.offset,\n sort,\n filters,\n });\n setTableData(data);\n setPagination((prev) => ({ ...prev, total: data.total }));\n setLoading(false);\n }, [\n selectedTable,\n schema,\n pagination.limit,\n pagination.offset,\n sort,\n filters,\n getTableRows,\n ]);\n\n const handleCopyAll = useCallback(async (): Promise<string> => {\n if (!selectedTable) return \"\";\n\n // Fetch all rows by using total as limit (or a large number if unknown)\n const limit = pagination.total ?? 1000000;\n const data = await getTableRows(selectedTable, {\n schema,\n limit,\n offset: 0,\n sort,\n filters,\n });\n\n return rowsToCsv(data.rows, columns);\n }, [\n selectedTable,\n schema,\n pagination.total,\n sort,\n filters,\n getTableRows,\n columns,\n ]);\n\n const loadTables = useCallback(async () => {\n setTablesLoading(true);\n const data = await getTables();\n setTables(data);\n setTablesLoading(false);\n return data;\n }, [getTables]);\n\n const handleRefresh = useCallback(async () => {\n const newTables = await loadTables();\n\n // Clear selection if selected table no longer exists\n if (selectedTable && !newTables.some((t) => t.name === selectedTable)) {\n setSelectedTable(undefined);\n setTableData(null);\n return;\n }\n\n // Reload current table data if a table is selected\n if (selectedTable) {\n await loadTableData();\n }\n }, [loadTables, selectedTable, loadTableData]);\n\n // Load tables on mount\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n void loadTables();\n }, [loadTables]);\n\n useEffect(() => {\n if (selectedTable) {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n void loadTableData();\n }\n }, [selectedTable, pagination.offset, sort, filters, loadTableData]);\n\n const handleSelectTable = (table: string) => {\n if (table === selectedTable) return;\n\n setSelectedTable(table);\n setPagination((prev) => ({ ...prev, offset: 0, total: null }));\n setSort(getDefaultSort?.(table));\n setFilters(undefined);\n setTableData(null);\n };\n\n const handlePageChange = (offset: number) => {\n setPagination((prev) => ({ ...prev, offset }));\n };\n\n const handleSort = (newSort: SortOptions) => {\n setSort(newSort);\n setPagination((prev) => ({ ...prev, offset: 0 }));\n };\n\n const handleImportClick = () => {\n fileInputRef.current?.click();\n };\n\n const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n\n void file.text().then((content) => {\n setPendingImport(content);\n });\n\n e.target.value = \"\";\n };\n\n const handleImportConfirm = async () => {\n if (pendingImport) {\n // Clear selection before import to prevent stale queries\n setSelectedTable(undefined);\n setTableData(null);\n\n await onImportDb?.(pendingImport);\n setPendingImport(null);\n await loadTables();\n }\n };\n\n const handleImportCancel = () => {\n setPendingImport(null);\n };\n\n const handleExportClick = () => {\n void onExportDb?.();\n };\n\n const resetTargetMajor = pgVersionControl\n ? (pgVersionControl.supportedPgVersions.find(\n (m) => m !== pgVersionControl.currentPgVersion,\n ) ?? null)\n : null;\n\n const handleResetConfirm = async () => {\n if (pendingResetMajor === null || !pgVersionControl) return;\n setResetting(true);\n try {\n await pgVersionControl.onResetToPgVersion(pendingResetMajor);\n } finally {\n setResetting(false);\n setPendingResetMajor(null);\n }\n };\n\n return (\n <div className=\"flex h-full\">\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".sql,.txt,text/plain\"\n className=\"hidden\"\n onChange={handleFileChange}\n />\n\n <ConnectConfirmationModal\n open={!!pendingImport}\n onOpenChange={(open) => !open && setPendingImport(null)}\n header=\"Replace Database?\"\n body=\"This will delete all existing data and replace it with the imported file. This action cannot be undone.\"\n cancelLabel=\"Cancel\"\n continueLabel=\"Replace Data\"\n onCancel={handleImportCancel}\n onContinue={() => void handleImportConfirm()}\n />\n\n <ConnectConfirmationModal\n open={pendingResetMajor !== null}\n onOpenChange={(open) => !open && setPendingResetMajor(null)}\n header={`Reset to Postgres ${pendingResetMajor ?? \"\"}?`}\n body={`This will permanently delete all local reactor data and recreate an empty database under Postgres ${pendingResetMajor ?? \"\"}. The page will reload.`}\n cancelLabel=\"Cancel\"\n continueLabel={`Reset to PG${pendingResetMajor ?? \"\"}`}\n onCancel={() => setPendingResetMajor(null)}\n onContinue={() => void handleResetConfirm()}\n />\n\n <div className=\"flex w-64 shrink-0 flex-col border-r border-gray-200 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <div className=\"flex-1 overflow-auto\">\n <SchemaTreeSidebar\n schema={schema}\n tables={tables}\n selectedTable={selectedTable}\n onSelectTable={handleSelectTable}\n onRefresh={handleRefresh}\n loading={tablesLoading || loading}\n />\n </div>\n\n {(onImportDb || onExportDb || pgVersionControl) && (\n <div className=\"flex shrink-0 flex-col gap-2 border-t border-gray-200 p-2 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {onImportDb && (\n <button\n className=\"rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={handleImportClick}\n type=\"button\"\n >\n Import DB\n </button>\n )}\n {onExportDb && (\n <button\n className=\"rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={handleExportClick}\n type=\"button\"\n >\n Export DB\n </button>\n )}\n {pgVersionControl && (\n <div className=\"flex flex-col gap-1 border-t border-gray-200 pt-2 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <div className=\"flex items-center justify-between text-xs text-gray-700 dark:text-slate-200\">\n <span>Postgres version</span>\n <span className=\"font-semibold text-gray-900 dark:text-slate-50\">\n {pgVersionControl.currentPgVersion === null\n ? \"—\"\n : `PG${pgVersionControl.currentPgVersion}`}\n </span>\n </div>\n {resetTargetMajor !== null && (\n <button\n className=\"rounded-sm border border-red-300 bg-red-50 px-3 py-1.5 text-sm text-red-700 hover:bg-red-100 disabled:opacity-50 dark:border-red-600 dark:bg-red-900 dark:text-red-100 dark:hover:bg-red-800\"\n onClick={() => setPendingResetMajor(resetTargetMajor)}\n disabled={resetting}\n type=\"button\"\n >\n {resetting\n ? `Resetting to PG${resetTargetMajor}…`\n : `Reset to PG${resetTargetMajor}`}\n </button>\n )}\n </div>\n )}\n </div>\n )}\n </div>\n\n <div className=\"flex-1 overflow-auto p-4\">\n {!selectedTable ? (\n <div className=\"text-sm text-gray-500 dark:text-slate-400\">\n Select a table to view data\n </div>\n ) : !tableData && loading ? (\n <div className=\"text-sm text-gray-500 dark:text-slate-400\">\n Loading...\n </div>\n ) : tableData ? (\n <TableView\n columns={columns}\n rows={tableData.rows}\n pagination={pagination}\n onPageChange={handlePageChange}\n onSort={handleSort}\n currentSort={sort}\n loading={loading}\n filters={filters}\n onFiltersChange={(newFilters) => {\n setFilters(newFilters);\n setPagination((prev) => ({ ...prev, offset: 0 }));\n }}\n onCopyAll={handleCopyAll}\n />\n ) : null}\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\n\nexport type DebugInspectorProps = {\n readonly supportedPgVersions: readonly number[];\n readonly currentPgVersion: number | null;\n readonly onResetToPgVersion: (major: number) => Promise<void>;\n};\n\ntype Status = \"idle\" | \"running\" | \"error\";\n\nexport function DebugInspector({\n supportedPgVersions,\n currentPgVersion,\n onResetToPgVersion,\n}: DebugInspectorProps) {\n const [status, setStatus] = useState<Status>(\"idle\");\n const [pendingMajor, setPendingMajor] = useState<number | null>(null);\n const [confirmMajor, setConfirmMajor] = useState<number | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const handleReset = async (major: number) => {\n setError(null);\n setConfirmMajor(null);\n setPendingMajor(major);\n setStatus(\"running\");\n try {\n await onResetToPgVersion(major);\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n setStatus(\"error\");\n setPendingMajor(null);\n }\n };\n\n const running = status === \"running\";\n\n return (\n <div className=\"flex h-full flex-col gap-4 overflow-auto p-4\">\n <div>\n <h2 className=\"text-lg font-semibold text-gray-900 dark:text-slate-50\">\n PGlite data dir\n </h2>\n <p className=\"mt-1 text-sm text-gray-700 dark:text-slate-200\">\n Kill the reactor, delete the local IndexedDB, initialize a fresh\n Postgres cluster at the chosen major version, then reload. Useful for\n testing version-detection and migration flows.\n </p>\n <div className=\"mt-2 inline-flex items-center gap-2 rounded-sm bg-gray-100 px-3 py-1 text-sm dark:bg-slate-700\">\n <span className=\"text-gray-700 dark:text-slate-200\">\n Current version:\n </span>\n <span className=\"font-semibold text-gray-900 dark:text-slate-50\">\n {currentPgVersion === null\n ? \"None (no data dir)\"\n : `Postgres ${currentPgVersion}`}\n </span>\n </div>\n </div>\n\n <div className=\"flex flex-wrap gap-2\">\n {supportedPgVersions.map((major) => {\n const isPending = pendingMajor === major && running;\n return (\n <button\n key={major}\n type=\"button\"\n disabled={running}\n onClick={() => setConfirmMajor(major)}\n className=\"flex items-center gap-1 rounded-sm border border-red-300 bg-red-50 px-3 py-1.5 text-sm text-red-700 hover:bg-red-100 disabled:opacity-50 dark:border-red-600 dark:bg-red-900 dark:text-red-100 dark:hover:bg-red-800\"\n >\n {isPending ? `Resetting to PG${major}…` : `Reset to PG${major}`}\n </button>\n );\n })}\n </div>\n\n {confirmMajor !== null && (\n <div className=\"flex shrink-0 items-center gap-3 rounded-sm border border-yellow-400 bg-yellow-50 px-3 py-2 dark:border-yellow-500 dark:bg-yellow-900\">\n <span className=\"text-sm text-yellow-900 dark:text-yellow-100\">\n This will permanently delete all local reactor data and recreate an\n empty database under Postgres {confirmMajor}. The page will reload.\n </span>\n <button\n type=\"button\"\n onClick={() => void handleReset(confirmMajor)}\n className=\"rounded-sm bg-yellow-600 px-3 py-1 text-sm text-white hover:bg-yellow-700 dark:bg-yellow-300 dark:text-slate-900 dark:hover:bg-yellow-200\"\n >\n Confirm reset to PG{confirmMajor}\n </button>\n <button\n type=\"button\"\n onClick={() => setConfirmMajor(null)}\n className=\"rounded-sm border border-gray-300 bg-gray-50 px-3 py-1 text-sm text-gray-700 hover:bg-gray-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-800\"\n >\n Cancel\n </button>\n </div>\n )}\n\n {error && (\n <div className=\"rounded-sm border border-red-300 bg-red-50 px-3 py-2 text-sm text-red-800 dark:border-red-600 dark:bg-red-900 dark:text-red-100\">\n {error}\n </div>\n )}\n </div>\n );\n}\n","import { useEffect, useRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\n// Each brick: its id, drop delay (ms), fall delay (ms)\n// Drop order: bottom → top. Fall order: bottom → top (same).\nconst SEQUENCE = [\n { id: \"b3\", dropDelay: 0, fallDelay: 0 },\n { id: \"b4\", dropDelay: 100, fallDelay: 80 },\n { id: \"b7\", dropDelay: 280, fallDelay: 240 },\n { id: \"b5\", dropDelay: 380, fallDelay: 320 },\n { id: \"b8\", dropDelay: 560, fallDelay: 480 },\n { id: \"b6\", dropDelay: 660, fallDelay: 560 },\n { id: \"b9\", dropDelay: 840, fallDelay: 720 },\n { id: \"b2\", dropDelay: 940, fallDelay: 800 },\n { id: \"b10\", dropDelay: 1120, fallDelay: 960 },\n { id: \"b1\", dropDelay: 1220, fallDelay: 1040 },\n];\n\nconst ANIM_DUR = 460; // ms — both drop and fall duration\nconst HOLD = 800; // ms logo stays complete before falling\nconst LAST_DROP = 1220;\nconst LAST_FALL = 1040;\nconst LOOP_TOTAL = LAST_DROP + ANIM_DUR + HOLD + LAST_FALL + ANIM_DUR + 400;\n\nconst DROP_STYLE = `brickDrop ${ANIM_DUR}ms cubic-bezier(0.28, 1.08, 0.58, 1) forwards`;\nconst FALL_STYLE = `brickFall ${ANIM_DUR}ms cubic-bezier(0.28, 1.08, 0.58, 1) forwards`;\n\n// SVG path data keyed by brick id\nconst PATHS: Record<string, string> = {\n b1: \"M22.4861 7.36555C22.7622 7.36554 22.9861 7.14169 22.9861 6.86556L22.9863 -5.98095e-06C16.584 0.265497 10.8298 3.03817 6.679 7.36592L22.4861 7.36555Z\",\n b2: \"M15.9859 17.2641C15.9859 17.5403 15.762 17.7641 15.4859 17.7641L0.812049 17.7646C1.63552 14.6865 3.05564 11.8512 4.93889 9.39228L15.486 9.39189C15.7621 9.39188 15.986 9.61575 15.986 9.8919L15.9859 17.2641Z\",\n b3: \"M41.3219 40.5904C37.1727 44.9165 31.4185 47.6892 25.0147 47.9563L25.0148 41.0908C25.0148 40.8146 25.2387 40.5908 25.5148 40.5908L41.3219 40.5904Z\",\n b4: \"M22.9867 47.9547C16.5845 47.6895 10.8289 44.9156 6.67982 40.5896L22.4869 40.5892C22.763 40.5892 22.9869 40.8131 22.9869 41.0893L22.9867 47.9547Z\",\n b5: \"M16.7309 30.6891C16.7309 30.413 16.9548 30.1892 17.2309 30.1892L47.1889 30.1885C46.3654 33.2666 44.9469 36.1002 43.0621 38.5608L17.2308 38.5614C16.9546 38.5614 16.7307 38.3376 16.7307 38.0614L16.7309 30.6891Z\",\n b6: \"M36.1809 20.2901C36.1809 20.014 36.4048 19.7901 36.6809 19.7901L47.6394 19.7899C47.879 21.1488 48.0044 22.5479 48.0044 23.976C48.0043 25.404 47.8788 26.8032 47.6392 28.1621L36.6821 28.1608C36.406 28.1608 36.1822 27.937 36.1822 27.661L36.1809 23.721V20.2901Z\",\n b7: \"M15.0193 38.0631C15.0193 38.3392 14.7954 38.5631 14.5193 38.5631L4.93982 38.5633C3.05508 36.1028 1.63671 33.2692 0.813384 30.1912L14.5195 30.1908C14.7956 30.1908 15.0195 30.4147 15.0195 30.6908L15.0193 38.0631Z\",\n b8: \"M0.364936 19.791L33.613 19.7902C33.8892 19.7902 34.1131 20.014 34.1131 20.2902L34.1129 27.6625C34.1129 27.9386 33.889 28.1624 33.6129 28.1624L0.364728 28.1632C0.12514 26.8043 -0.00024171 25.4052 -0.000207992 23.9771C-0.000174275 22.549 0.125283 21.1499 0.364936 19.791Z\",\n b9: \"M18.0156 9.8918C18.0156 9.61566 18.2394 9.39181 18.5155 9.39181L43.0627 9.39138C44.9475 11.8519 46.3659 14.6855 47.1892 17.7635L18.5154 17.7641C18.2392 17.7641 18.0154 17.5402 18.0154 17.2641L18.0156 9.8918Z\",\n b10: \"M25.0158 -2.51999e-05C31.418 0.265176 37.1737 3.03916 41.3227 7.36511L25.5156 7.36547C25.2395 7.36547 25.0156 7.14161 25.0156 6.86546L25.0158 -2.51999e-05Z\",\n};\n\nexport function LogoAnimation({ size = 48, className = \"\" }) {\n const refsMap = useRef<Record<string, (SVGPathElement | null)[] | undefined>>(\n {},\n ); // id → array of path DOM nodes\n const timers = useRef<NodeJS.Timeout[]>([]);\n\n function getEls(id: string) {\n return refsMap.current[id] ?? [];\n }\n\n function clearTimers() {\n timers.current.forEach(clearTimeout);\n timers.current = [];\n }\n\n function schedule(fn: () => void, delay: number) {\n timers.current.push(setTimeout(fn, delay));\n }\n\n function resetAll() {\n Object.values(refsMap.current)\n .flat()\n .forEach((el) => {\n if (!el) return;\n el.style.animation = \"none\";\n el.style.opacity = \"0\";\n });\n }\n\n useEffect(() => {\n function runDrop(id: string, delay: number) {\n schedule(() => {\n getEls(id).forEach((el) => {\n if (el === null) return;\n el.style.animation = \"none\";\n el.style.opacity = \"\";\n el.style.animation = DROP_STYLE;\n });\n }, delay);\n }\n\n function runFall(id: string, delay: number) {\n schedule(() => {\n getEls(id).forEach((el) => {\n if (!el) return;\n el.style.animation = \"none\";\n el.style.animation = FALL_STYLE;\n });\n }, delay);\n }\n function startLoop() {\n clearTimers();\n resetAll();\n\n SEQUENCE.forEach(({ id, dropDelay }) => runDrop(id, dropDelay));\n\n const fallStart = LAST_DROP + ANIM_DUR + HOLD;\n SEQUENCE.forEach(({ id, fallDelay }) =>\n runFall(id, fallStart + fallDelay),\n );\n\n schedule(startLoop, LOOP_TOTAL);\n }\n startLoop();\n return () => clearTimers();\n }, []);\n\n // Register a path ref by brick id\n function refFor(id: string) {\n return (el: SVGPathElement | null) => {\n if (!refsMap.current[id]) refsMap.current[id] = [];\n if (el && !refsMap.current[id].includes(el)) {\n refsMap.current[id].push(el);\n }\n };\n }\n\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"-1 -2 50 52\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={twMerge(\"text-gray-900 dark:text-slate-50\", className)}\n aria-label=\"Animated logo\"\n >\n {SEQUENCE.map(({ id }) => (\n <path\n key={id}\n ref={refFor(id)}\n d={PATHS[id]}\n fill=\"currentColor\"\n style={{ opacity: 0 }}\n />\n ))}\n </svg>\n );\n}\n","import type { DivProps } from \"#design-system\";\nimport { LogoAnimation } from \"../logo-animation.js\";\n\ntype DefaultEditorLoaderProps = DivProps & {\n readonly message?: string;\n};\n\nexport function DefaultEditorLoader(props: DefaultEditorLoaderProps) {\n const { message = \"Loading editor\", ...divProps } = props;\n return (\n <div\n className=\"grid h-full place-items-center text-gray-800 dark:text-slate-100\"\n {...divProps}\n >\n <div className=\"-mt-20 grid place-items-center\">\n <h3 className=\"mb-4 text-xl\">{message}</h3>\n <LogoAnimation />\n </div>\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport type { ReactNode } from \"react\";\nimport { twJoin, twMerge } from \"tailwind-merge\";\n\ntype DisclosureProps = {\n title: ReactNode;\n isOpen: boolean;\n onOpenChange: () => void;\n children: ReactNode;\n containerClassName?: string;\n toggleClassName?: string;\n contentClassName?: string;\n};\nexport function Disclosure(props: DisclosureProps) {\n const {\n title,\n isOpen,\n onOpenChange,\n children,\n containerClassName,\n toggleClassName,\n contentClassName,\n } = props;\n return (\n <div className={twMerge(containerClassName)}>\n <div\n className={twMerge(\n \"flex cursor-pointer justify-between text-gray-500 dark:text-slate-400\",\n toggleClassName,\n )}\n onClick={onOpenChange}\n >\n <h2 className=\"font-semibold text-inherit\">{title}</h2>\n <Icon\n className={twJoin(\"transition\", isOpen ? \"\" : \"-rotate-90\")}\n size={16}\n name=\"ChevronDown\"\n />\n </div>\n <div\n className={twMerge(\n \"max-h-0 overflow-hidden transition-[max-height] duration-300 ease-in-out\",\n isOpen && \"max-h-screen\",\n contentClassName,\n )}\n >\n {children}\n </div>\n </div>\n );\n}\n","import type { DivProps } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function Divider(props: DivProps) {\n return (\n <div\n {...props}\n className={twMerge(\n \"h-px bg-gray-200 dark:bg-slate-600 dark:text-slate-100\",\n props.className,\n )}\n />\n );\n}\n","import type { ReactNode } from \"react\";\n\nexport type TabContentProps = {\n readonly label: ReactNode;\n readonly description: ReactNode;\n readonly children: ReactNode;\n readonly disabled?: boolean;\n};\nexport function TabContent(props: TabContentProps) {\n const { label: _label, children } = props;\n\n return <div className=\"h-full\">{children}</div>;\n}\n","import { Content, List, Root, Trigger } from \"@radix-ui/react-tabs\";\nimport React from \"react\";\nimport type { TabContentProps } from \"./tab-content.js\";\n\nexport function Tabs({\n children,\n defaultValue,\n}: {\n children: React.ReactNode;\n defaultValue: string;\n}) {\n return (\n <Root\n defaultValue={defaultValue}\n className=\"flex min-h-0 flex-1 flex-col gap-2\"\n >\n <div className=\"flex w-full shrink-0 justify-between\">\n <List className=\"flex w-full gap-x-2 rounded-xl p-1 text-sm font-semibold text-gray-700 outline-none dark:text-slate-200\">\n {React.Children.map(children, (child, _i) => {\n if (!React.isValidElement(child)) return;\n const { label, disabled } = child.props as TabContentProps;\n return (\n <Trigger\n className=\"flex min-h-7 flex-1 items-center justify-center rounded-lg border border-gray-100 bg-gray-50 py-2 text-gray-900 transition duration-300 data-disabled:cursor-not-allowed data-disabled:text-gray-400 data-[state='active']:bg-gray-100 data-[state='active']:text-gray-900 dark:border-slate-600 dark:bg-slate-600 dark:text-slate-200 dark:data-disabled:text-slate-500 dark:data-[state='active']:bg-slate-500 dark:data-[state='active']:text-slate-100\"\n key={label as string}\n value={label as string}\n disabled={disabled ?? false}\n >\n {label as string}\n </Trigger>\n );\n })}\n </List>\n </div>\n <div className=\"mt-3 min-h-0 flex-1 rounded-md bg-gray-50 dark:bg-slate-800\">\n {React.Children.map(children, (child, i) => {\n if (!React.isValidElement(child)) return;\n const { label } = child.props as TabContentProps;\n return (\n <Content className=\"h-full\" value={label as string} key={i}>\n {child}\n </Content>\n );\n })}\n </div>\n </Root>\n );\n}\n","import { JsonViewer } from \"#design-system/ui/components/json-viewer/json-viewer.js\";\nimport { useMemo } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { TabContent } from \"../tabs/tab-content.js\";\nimport { Tabs } from \"../tabs/tabs.js\";\n\ninterface DocumentStateViewerProps {\n state: Record<string, unknown>;\n ignoredScopes?: string[];\n defaultScope?: string;\n className?: string;\n}\n\nfunction formatScopeLabel(text: string) {\n if (!text) return \"\"; // Handle empty strings or null\n return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();\n}\n\nexport function DocumentStateViewer({\n state,\n ignoredScopes = [\"auth\", \"document\"],\n defaultScope,\n className,\n}: DocumentStateViewerProps) {\n const scopes = useMemo(\n () => Object.keys(state).filter((scope) => !ignoredScopes.includes(scope)),\n [state, ignoredScopes],\n );\n\n const initialScope = defaultScope || scopes.at(0) || \"global\";\n\n if (scopes.length === 0) {\n return (\n <div className=\"text-sm text-gray-500 dark:text-slate-400\">\n No state data\n </div>\n );\n }\n\n return (\n <Tabs defaultValue={formatScopeLabel(initialScope)}>\n {scopes.map((scope) => (\n <TabContent\n key={scope}\n label={formatScopeLabel(scope)}\n description={scope}\n >\n <div\n className={twMerge(\n \"-mt-2 rounded-md border border-gray-300 bg-gray-50 p-3 font-mono text-sm dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n className,\n )}\n >\n <JsonViewer data={state[scope] as object} />\n </div>\n </TabContent>\n ))}\n </Tabs>\n );\n}\n","import type { TooltipProps } from \"@radix-ui/react-tooltip\";\nimport {\n Content,\n Portal,\n Provider,\n Root,\n Trigger,\n} from \"@radix-ui/react-tooltip\";\nimport type { ReactNode } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\ntype Props = TooltipProps & {\n readonly className?: string;\n readonly content: ReactNode;\n readonly side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n readonly sideOffset?: number;\n};\n\nexport function ConnectTooltip(props: Props) {\n const {\n children,\n content,\n open,\n defaultOpen,\n onOpenChange,\n className,\n side = \"top\",\n sideOffset = 5,\n delayDuration,\n ...rest\n } = props;\n\n return (\n <Root\n defaultOpen={defaultOpen}\n delayDuration={delayDuration}\n onOpenChange={onOpenChange}\n open={open}\n >\n <Trigger asChild>{children}</Trigger>\n <Portal>\n <Content\n {...rest}\n side={side}\n sideOffset={sideOffset}\n className={twMerge(\n \"z-50 rounded-lg border border-gray-200 bg-gray-50 p-2 text-xs shadow-tooltip dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n className,\n )}\n >\n {content}\n </Content>\n </Portal>\n </Root>\n );\n}\n\nexport const ConnectTooltipProvider = Provider;\n","import { Icon } from \"#design-system\";\nimport { formatDistanceToNow } from \"date-fns\";\nimport { useEffect, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ConnectTooltip } from \"../../tooltip/tooltip.js\";\n\nexport interface HDividerProps {\n className?: string;\n timestampUtcMs?: string;\n title?: string;\n subtitle?: string;\n onClick?: () => void;\n isSelected?: boolean;\n}\n\nexport const HDivider = (props: HDividerProps) => {\n const {\n className,\n timestampUtcMs: timestamp,\n title,\n subtitle,\n onClick,\n isSelected = false,\n } = props;\n const [open, setOpen] = useState<boolean>(false);\n const hasContent = !!title || !!subtitle || !!timestamp;\n\n // Force update tooltips when props change\n useEffect(() => {\n // Force close and re-open if already open to refresh content\n if (open) {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setOpen(false);\n setTimeout(() => hasContent && setOpen(true), 50);\n }\n }, [title, subtitle, timestamp, hasContent]);\n\n const formatTimestamp = (isoString?: string) => {\n if (!isoString) return \"\";\n try {\n return formatDistanceToNow(new Date(isoString), { addSuffix: true });\n } catch {\n return isoString;\n }\n };\n\n const tooltipContent = (\n <div className=\"flex flex-col text-xs\">\n {!!title && <div>{title}</div>}\n {!!subtitle && (\n <div className=\"text-gray-300 dark:text-slate-600\">{subtitle}</div>\n )}\n {!!timestamp && <div>{formatTimestamp(timestamp)}</div>}\n </div>\n );\n\n const handleMouseEnter = () => {\n if (hasContent) {\n setOpen(true);\n }\n };\n\n const handleMouseLeave = () => {\n setOpen(false);\n };\n\n return (\n <div\n className=\"relative\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {isSelected && (\n <Icon\n name=\"TimelineCaret\"\n color=\"#4EA9FF\"\n size={10}\n className=\"absolute top-[-11px] z-40\"\n />\n )}\n <ConnectTooltip\n className=\"rounded-md bg-gray-900 text-white dark:bg-slate-50 dark:text-slate-900\"\n content={tooltipContent}\n open={open && hasContent}\n onOpenChange={setOpen}\n delayDuration={0}\n side=\"bottom\"\n sideOffset={5}\n >\n <div\n className={twMerge(\n \"mx-0.5 flex h-6.25 w-1.5 cursor-pointer flex-col items-center justify-center rounded-xs hover:bg-blue-300 dark:hover:bg-blue-600\",\n isSelected && \"bg-blue-300 dark:bg-blue-600\",\n className,\n )}\n onClick={onClick}\n data-title={title}\n data-subtitle={subtitle}\n data-timestamp={timestamp}\n >\n <div className=\"h-0.5 w-1 rounded-full bg-gray-500 dark:bg-slate-400\" />\n </div>\n </ConnectTooltip>\n </div>\n );\n};\n","import { Icon } from \"#design-system\";\nimport type { TimelineBarItem } from \"@powerhousedao/reactor-browser\";\nimport { format, parseISO } from \"date-fns\";\nimport { useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ConnectTooltip } from \"../../tooltip/tooltip.js\";\n\nexport interface TimelineBarProps extends Omit<\n TimelineBarItem,\n \"id\" | \"type\" | \"revision\" | \"startDate\" | \"endDate\"\n> {\n readonly className?: string;\n onClick?: () => void;\n isSelected?: boolean;\n}\n\nconst getBarHeight = (size = 0) => {\n switch (true) {\n case size <= 0:\n return \"h-[1px]\";\n case size === 1:\n return \"h-[3px]\";\n case size === 2:\n return \"h-[6px]\";\n case size === 3:\n return \"h-[9px]\";\n case size >= 4:\n return \"h-[12px]\";\n default:\n return \"h-[1px]\";\n }\n};\n\nconst formatTimestamp = (isoString?: string) => {\n if (!isoString) return \"\";\n try {\n const date = parseISO(isoString);\n return format(date, \"HH:mm, dd, MMMM\");\n } catch {\n return isoString;\n }\n};\n\nexport const TimelineBar: React.FC<TimelineBarProps> = ({\n onClick,\n className,\n timestampUtcMs: timestamp,\n additions,\n deletions,\n addSize = 0,\n delSize = 0,\n isSelected = false,\n}) => {\n const [open, setOpen] = useState<boolean>(false);\n const noChanges = addSize === 0 && delSize === 0;\n\n const addBarHeight = getBarHeight(addSize);\n const delBarHeight = getBarHeight(delSize);\n\n const tooltipContent = (\n <div className=\"flex flex-col text-xs\">\n <div>{formatTimestamp(timestamp)}</div>\n <div className=\"text-green-900 dark:text-green-100\">{`${additions} additions +`}</div>\n <div className=\"text-red-700 dark:text-red-100\">{`${deletions} deletions -`}</div>\n </div>\n );\n\n const handleMouseEnter = () => {\n if (!noChanges) {\n setOpen(true);\n }\n };\n\n const handleMouseLeave = () => {\n setOpen(false);\n };\n\n return (\n <div\n className=\"relative\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {isSelected && (\n <Icon\n name=\"TimelineCaret\"\n color=\"#4EA9FF\"\n size={10}\n className=\"absolute top-[-11px] left-[-2px] z-40\"\n />\n )}\n {noChanges ? (\n <div\n className={twMerge(\n \"flex h-[25px] w-1.5 cursor-pointer flex-col items-center justify-center rounded-[2px] hover:bg-blue-300 dark:hover:bg-blue-600\",\n className,\n )}\n data-timestamp={timestamp}\n onClick={onClick}\n >\n <div className=\"size-[3px] rounded-full bg-gray-500 dark:bg-slate-400\" />\n </div>\n ) : (\n <ConnectTooltip\n className=\"rounded-md bg-gray-900 text-white dark:bg-slate-50 dark:text-slate-900\"\n content={tooltipContent}\n open={open}\n onOpenChange={setOpen}\n delayDuration={0}\n side=\"bottom\"\n sideOffset={5}\n >\n <div\n className={twMerge(\n \"flex h-[25px] w-1.5 cursor-pointer flex-col items-center justify-center rounded-[2px] hover:bg-blue-300 dark:hover:bg-blue-600\",\n className,\n isSelected && \"bg-blue-300 dark:bg-blue-600\",\n )}\n data-timestamp={timestamp}\n onClick={onClick}\n >\n <div className=\"flex h-3 w-0.5 items-end\">\n <div\n className={twMerge(\n \"h-3 w-0.5 rounded-t-full bg-green-600 dark:bg-green-300\",\n addBarHeight,\n )}\n ></div>\n </div>\n <div className=\"flex h-3 w-0.5 items-start\">\n <div\n className={twMerge(\n \"h-3 w-0.5 rounded-b-full bg-red-600 dark:bg-red-300\",\n delBarHeight,\n )}\n ></div>\n </div>\n </div>\n </ConnectTooltip>\n )}\n </div>\n );\n};\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { ConnectTooltipProvider } from \"../tooltip/tooltip.js\";\nimport { HDivider } from \"./components/h-divider.js\";\nimport { TimelineBar } from \"./components/timeline-bar.js\";\n\nexport type TimelineBarItem = {\n id: string;\n type: \"bar\";\n addSize?: 0 | 1 | 2 | 3 | 4;\n delSize?: 0 | 1 | 2 | 3 | 4;\n timestampUtcMs?: string;\n additions?: number;\n deletions?: number;\n revision?: number;\n startDate?: Date;\n endDate?: Date;\n};\n\nexport type TimelineDividerItem = {\n id: string;\n type: \"divider\";\n timestampUtcMs?: string;\n title?: string;\n subtitle?: string;\n revision?: number;\n startDate?: Date;\n endDate?: Date;\n};\n\nexport type TimelineItem = TimelineBarItem | TimelineDividerItem;\n\nexport interface DocumentTimelineProps {\n onItemClick?: (item: TimelineItem | null) => void;\n timeline?: Array<TimelineItem>;\n}\n\nconst defaultTimeLineItem: TimelineBarItem = {\n id: \"default\",\n type: \"bar\",\n addSize: 0,\n delSize: 0,\n};\n\nexport const DocumentTimeline = (props: DocumentTimelineProps) => {\n const { timeline = [], onItemClick } = props;\n const [selectedItem, setSelectedItem] = useState<null | string>(null);\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n\n const handleClick = (item: TimelineItem) => {\n if (item.id === selectedItem || item.id === defaultTimeLineItem.id) {\n onItemClick?.(null);\n setSelectedItem(null);\n } else {\n onItemClick?.(item);\n setSelectedItem(item.id);\n }\n };\n\n const mergedTimelineItems = [...timeline, defaultTimeLineItem];\n const [unselectedItems, selectedItems] = useMemo(() => {\n const indexSelected = mergedTimelineItems.findIndex(\n (item) => item.id === selectedItem,\n );\n\n return indexSelected === -1\n ? [mergedTimelineItems, []]\n : [\n mergedTimelineItems.slice(0, indexSelected),\n mergedTimelineItems.slice(indexSelected),\n ];\n }, [mergedTimelineItems, selectedItem]);\n\n const renderTimelineItems = useCallback(\n (items: Array<TimelineBarItem | TimelineDividerItem>) => {\n return items.map((item) => {\n if (item.type === \"divider\") {\n const { timestampUtcMs, title, subtitle } = item;\n return (\n <HDivider\n key={item.id}\n timestampUtcMs={timestampUtcMs}\n title={title}\n subtitle={subtitle}\n onClick={() => handleClick(item)}\n isSelected={item.id === selectedItem}\n />\n );\n }\n\n return (\n <TimelineBar\n key={item.id}\n timestampUtcMs={item.timestampUtcMs}\n addSize={item.addSize}\n delSize={item.delSize}\n additions={item.additions}\n deletions={item.deletions}\n isSelected={item.id === selectedItem}\n onClick={() => handleClick(item)}\n />\n );\n });\n },\n [handleClick, selectedItem],\n );\n\n const unselectedContent = useMemo(\n () => renderTimelineItems(unselectedItems),\n [unselectedItems, renderTimelineItems],\n );\n\n const selectedContent = useMemo(\n () => renderTimelineItems(selectedItems),\n [selectedItems, renderTimelineItems],\n );\n\n // Scroll to the end by default\n useEffect(() => {\n if (scrollContainerRef.current) {\n scrollContainerRef.current.scrollLeft =\n scrollContainerRef.current.scrollWidth;\n }\n }, []);\n\n return (\n <ConnectTooltipProvider delayDuration={0} skipDelayDuration={0}>\n <div className=\"relative h-[36px] w-full\">\n <div className=\"absolute left-0 z-20 h-[17px] w-[6px] bg-gray-50 dark:bg-slate-800\">\n <div className=\"mt-[11px] h-[6px] w-[6px] rounded-tl-md bg-gray-50 dark:bg-slate-800\" />\n </div>\n\n <div className=\"absolute top-[11px] right-0 z-20 h-[6px] w-[6px] bg-gray-50 dark:bg-slate-800\">\n <div className=\"h-[6px] w-[6px] rounded-tr-md bg-gray-50 dark:bg-slate-800\" />\n </div>\n <div className=\"absolute inset-x-0 bottom-0 h-[25px] rounded-md bg-gray-50 dark:bg-slate-800\" />\n\n <div className=\"absolute inset-x-0 bottom-0 h-[36px]\">\n <div\n ref={scrollContainerRef}\n className=\"h-full overflow-x-auto rounded-md\"\n >\n <div className=\"ml-auto flex h-[36px] w-max items-end px-2 pb-0\">\n <div className=\"flex\">{unselectedContent}</div>\n <div className=\"flex rounded-sm bg-blue-200 dark:bg-blue-700\">\n {selectedContent}\n </div>\n </div>\n </div>\n </div>\n <div className=\"pointer-events-none absolute bottom-0 left-0 z-10 h-[25px] w-2 rounded-l-md bg-gray-50 dark:bg-slate-800\" />\n <div className=\"pointer-events-none absolute right-0 bottom-0 z-10 h-[25px] w-2 rounded-r-md bg-gray-50 dark:bg-slate-800\" />\n </div>\n </ConnectTooltipProvider>\n );\n};\n","import type { ComponentProps } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Default outer container for `DocumentToolbar`.\n *\n * This component provides the toolbar's base layout and visual styling while\n * still accepting standard `div` props. Pass a custom container to\n * `DocumentToolbar` when you need to replace this wrapper.\n */\nexport function ToolbarContainer(props: ComponentProps<\"div\">) {\n const { children, className, ...rest } = props;\n\n return (\n <div\n {...rest}\n className={twMerge(\n \"flex h-12 w-full items-center justify-between rounded-xl border border-gray-200 bg-gray-50 px-4 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\n/**\n * Default container for a group of toolbar controls.\n *\n * `DocumentToolbar` renders one controls container per toolbar slot. This\n * component provides the default horizontal layout for the controls in that\n * slot while still accepting standard `div` props.\n */\nexport function ToolbarControlsContainer(props: ComponentProps<\"div\">) {\n const { children, className, ...rest } = props;\n\n return (\n <div className={twMerge(\"flex items-center gap-x-2\", className)} {...rest}>\n {children}\n </div>\n );\n}\n","import { useDocumentById } from \"@powerhousedao/reactor-browser\";\nimport {\n redo,\n undo,\n type PHDocument,\n} from \"@powerhousedao/shared/document-model\";\nimport {\n defaultTo,\n filter,\n hasAtLeast,\n isTruthy,\n merge,\n pipe,\n prop,\n values,\n} from \"remeda\";\n\n/**\n * Checks whether a document has at least one non-zero revision count.\n *\n * Revision scopes are dynamic document-model keys, so this checks the values of\n * the document's revision object instead of relying on a fixed list of scope\n * names.\n */\nfunction hasRevisions(document: PHDocument | undefined) {\n return pipe(\n prop(document, \"header\", \"revision\"),\n defaultTo({}),\n values(),\n filter(isTruthy),\n hasAtLeast(1),\n );\n}\n\n/**\n * Returns undo state and an undo dispatcher for a document.\n *\n * `canUndo` is true when the document has at least one non-zero revision count\n * across any revision scope.\n */\nexport function useUndo(documentId: string | undefined) {\n const [document, dispatch] = useDocumentById(documentId);\n const canUndo = hasRevisions(document);\n\n return {\n canUndo,\n undo: () => dispatch(undo()),\n };\n}\n\n/**\n * Returns redo state and a redo dispatcher for a document.\n *\n * `canRedo` is true when the document clipboard contains at least one operation\n * that can be reapplied.\n */\nexport function useRedo(documentId: string | undefined) {\n const [document, dispatch] = useDocumentById(documentId);\n const canRedo = hasAtLeast(document?.clipboard ?? [], 1);\n\n return {\n canRedo,\n redo: () => dispatch(redo()),\n };\n}\n\n/**\n * Returns combined undo and redo state for a document.\n */\nexport function useDocumentUndoRedo(documentId?: string) {\n const undoProps = useUndo(documentId);\n const redoProps = useRedo(documentId);\n return merge(undoProps, redoProps);\n}\n","import {\n setSelectedNode,\n showRevisionHistory,\n useDownloadDocument,\n useGetSwitchboardLink,\n useNodeParentFolderById,\n} from \"@powerhousedao/reactor-browser\";\nimport type { PHDocument } from \"@powerhousedao/shared/document-model\";\nimport type { ComponentProps } from \"react\";\nimport { isDefined } from \"remeda\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Icon } from \"../../../powerhouse/components/icon/icon.js\";\nimport type { ToolbarButtonClickHandler, ToolbarButtonProps } from \"./types.js\";\nimport { useRedo, useUndo } from \"./use-document-undo-redo.js\";\n\n/**\n * Base button component used by the built-in toolbar controls.\n *\n * This component provides the default toolbar button styling and disabled-state\n * behavior while accepting standard `button` props.\n */\nexport function ToolbarButton(props: ComponentProps<\"button\">) {\n const { className, children, disabled, ...rest } = props;\n return (\n <button\n {...rest}\n disabled={disabled}\n className={twMerge(\n \"grid size-fit place-items-center rounded-lg border border-gray-200 bg-gray-50 p-1 text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n disabled\n ? \"cursor-not-allowed text-gray-500 dark:text-slate-400\"\n : \"cursor-pointer active:opacity-70\",\n className,\n )}\n >\n {children}\n </button>\n );\n}\n\n/**\n * Toolbar control for undoing the latest document revision.\n *\n * The button is disabled when there are no revisions available to undo.\n * Provide `children` to replace the default icon, or `onClick` to override the\n * default undo behavior.\n */\nexport function ToolbarUndoButton(props: ToolbarButtonProps) {\n const {\n className,\n onClick: onClickOverride,\n document,\n children = <Icon name=\"ArrowCouterclockwise\" size={16} />,\n } = props;\n const { undo, canUndo } = useUndo(document?.header.id);\n const disabled = !canUndo;\n const onClick = makeOnClick(document, onClickOverride, undo);\n\n return (\n <ToolbarButton\n data-testid=\"toolbar-undo-button\"\n aria-label=\"Undo\"\n className={className}\n disabled={disabled}\n onClick={onClick}\n >\n {children}\n </ToolbarButton>\n );\n}\n\n/**\n * Toolbar control for redoing the latest undone document revision.\n *\n * The button is disabled when there are no revisions available to redo.\n * Provide `children` to replace the default icon, or `onClick` to override the\n * default redo behavior.\n */\nexport function ToolbarRedoButton(props: ToolbarButtonProps) {\n const {\n className,\n onClick: onClickOverride,\n document,\n children = (\n <Icon name=\"ArrowCouterclockwise\" className=\"-scale-x-100\" size={16} />\n ),\n } = props;\n const { redo, canRedo } = useRedo(document?.header.id);\n const onClick = makeOnClick(document, onClickOverride, redo);\n const disabled = !canRedo;\n\n return (\n <ToolbarButton\n data-testid=\"toolbar-redo-button\"\n aria-label=\"Redo\"\n className={className}\n disabled={disabled}\n onClick={onClick}\n >\n {children}\n </ToolbarButton>\n );\n}\n\n/**\n * Toolbar control for downloading the current document.\n *\n * Provide `children` to replace the default label, or `onClick` to override the\n * default download behavior.\n */\nexport function ToolbarDownloadButton(props: ToolbarButtonProps) {\n const {\n className,\n onClick: onClickOverride,\n document,\n children = <span className=\"px-1 text-xs\">Download</span>,\n } = props;\n const downloadDocument = useDownloadDocument(document?.header.id);\n const onClick = makeOnClick(document, onClickOverride, downloadDocument);\n\n return (\n <ToolbarButton\n data-testid=\"toolbar-download-button\"\n aria-label=\"Download\"\n className={className}\n onClick={onClick}\n >\n {children}\n </ToolbarButton>\n );\n}\n\n/**\n * Toolbar control for opening the current document in Switchboard.\n *\n * Provide `children` to replace the default icon, or `onClick` to override the\n * default behavior.\n */\nexport function ToolbarSwitchboardButton(props: ToolbarButtonProps) {\n const {\n className,\n onClick: onClickOverride,\n document,\n children = <Icon name=\"Drive\" size={16} />,\n } = props;\n const getSwitchboardLink = useGetSwitchboardLink(document);\n\n const onClick = makeOnClick(document, onClickOverride, () => {\n getSwitchboardLink?.()\n .then((url) => window.open(url, \"_blank\"))\n .catch((error) =>\n console.error(\"Error opening switchboard link:\", error),\n );\n });\n\n return (\n <ToolbarButton\n data-testid=\"toolbar-switchboard-button\"\n aria-label=\"Open link in Switchboard\"\n className={className}\n onClick={onClick}\n >\n {children}\n </ToolbarButton>\n );\n}\n\n/**\n * Toolbar control for showing the current document's revision history.\n *\n * Provide `children` to replace the default icon, or `onClick` to override the\n * default revision-history behavior.\n */\nexport function ToolbarHistoryButton(props: ToolbarButtonProps) {\n const {\n className,\n onClick: onClickOverride,\n document,\n children = <Icon name=\"History\" size={16} />,\n } = props;\n const onClick = makeOnClick(document, onClickOverride, showRevisionHistory);\n\n return (\n <ToolbarButton\n data-testid=\"toolbar-history-button\"\n aria-label=\"Open document revision history\"\n className={className}\n onClick={onClick}\n >\n {children}\n </ToolbarButton>\n );\n}\n\n/**\n * Toolbar control for closing the current document view.\n *\n * By default, this selects the current document's parent folder. Provide\n * `children` to replace the default icon, or `onClick` to override the default\n * close behavior.\n */\nexport function ToolbarCloseButton(props: ToolbarButtonProps) {\n const {\n className,\n onClick: onClickOverride,\n document,\n children = <Icon name=\"XmarkLight\" size={16} />,\n } = props;\n const parentFolder = useNodeParentFolderById(document?.header.id);\n const onClick = makeOnClick(document, onClickOverride, () =>\n setSelectedNode(parentFolder),\n );\n\n return (\n <ToolbarButton\n data-testid=\"toolbar-close-button\"\n aria-label=\"Close document\"\n className={className}\n onClick={onClick}\n >\n {children}\n </ToolbarButton>\n );\n}\n\n/**\n * Creates a toolbar button click handler.\n *\n * If an override is provided, it is called with the current document. Otherwise,\n * the built-in handler is called with the current document.\n */\nfunction makeOnClick(\n document: PHDocument | undefined,\n onClickOverride: ToolbarButtonClickHandler | undefined,\n defaultOnClick: ToolbarButtonClickHandler,\n) {\n if (isDefined(onClickOverride)) return () => onClickOverride(document);\n return () => defaultOnClick(document);\n}\n","import { twMerge } from \"tailwind-merge\";\nimport { NodeInput } from \"../node-input/node-input.js\";\n\n/**\n * Text input styled for use inside a toolbar.\n *\n * This wraps `NodeInput` with toolbar-specific text styling. Use it for inline\n * toolbar editing flows where the user can submit a value or cancel editing.\n */\nexport function ToolbarInput(props: {\n /**\n * Initial value to show in the input.\n */\n defaultValue?: string;\n /**\n * Additional CSS class names to apply to the input.\n */\n className?: string;\n /**\n * Accessible label for the input.\n */\n \"aria-label\"?: string;\n /**\n * Called when the user submits the input value.\n */\n onSubmit: (value: string) => void;\n /**\n * Called when the user cancels editing.\n */\n onCancel: () => void;\n}) {\n const {\n defaultValue,\n className,\n onSubmit,\n onCancel,\n \"aria-label\": ariaLabel,\n } = props;\n return (\n <NodeInput\n defaultValue={defaultValue}\n className={twMerge(\n \"text-center text-sm font-medium text-gray-500 dark:text-slate-400\",\n className,\n )}\n aria-label={ariaLabel}\n onCancel={onCancel}\n onSubmit={onSubmit}\n />\n );\n}\n","import { useNodeActions, useNodeById } from \"@powerhousedao/reactor-browser\";\nimport type { PHDocument } from \"@powerhousedao/shared/document-model\";\nimport { useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ToolbarInput } from \"./toolbar-input.js\";\n\n/**\n * Toolbar control for displaying and renaming the current document.\n *\n * By default, the component renders the document name as a clickable heading.\n * When clicked, it switches to an inline input. Submitting the input renames\n * both the node and the corresponding drive node entry.\n */\nexport function ToolbarName(props: {\n document?: PHDocument | undefined;\n inputClassName?: string;\n titleClassName?: string;\n}) {\n const { document, inputClassName, titleClassName } = props;\n const [isEditing, setIsEditing] = useState(false);\n const node = useNodeById(document?.header.id);\n const { onRenameNode, onRenameDriveNodes } = useNodeActions();\n\n const documentName = document?.header.name;\n const documentId = document?.header.id;\n\n const activateEditing = () => setIsEditing(true);\n const cancelEditing = () => setIsEditing(false);\n\n const onSubmit = (newName: string) => {\n cancelEditing();\n if (!documentId || !node) return;\n\n Promise.all([\n onRenameNode(newName, node),\n onRenameDriveNodes(newName, documentId),\n ]).catch(console.error);\n };\n\n if (!documentName) return null;\n\n if (isEditing)\n return (\n <ToolbarInput\n className={inputClassName}\n onSubmit={onSubmit}\n onCancel={cancelEditing}\n defaultValue={documentName}\n aria-label=\"Document name\"\n />\n );\n\n return (\n <h1\n className={twMerge(\n \"cursor-pointer text-sm font-medium text-gray-500 hover:text-gray-700 dark:text-slate-400 dark:hover:text-slate-200\",\n titleClassName,\n )}\n onClick={activateEditing}\n title={\"Click to edit\"}\n >\n {documentName}\n </h1>\n );\n}\n","import { keys } from \"remeda\";\nimport {\n ToolbarCloseButton,\n ToolbarDownloadButton,\n ToolbarHistoryButton,\n ToolbarRedoButton,\n ToolbarSwitchboardButton,\n ToolbarUndoButton,\n} from \"./toolbar-button.js\";\nimport { ToolbarName } from \"./toolbar-name.js\";\nimport type { DefaultToolbarControlComponents } from \"./types.js\";\n\n/**\n * Default slot layout for the built-in document toolbar controls.\n *\n * The toolbar is divided into three control groups:\n *\n * - `first`: primary document actions.\n * - `second`: document identity/display controls.\n * - `third`: secondary document actions.\n */\nexport const defaultControlSlots = {\n first: [\"undo\", \"redo\", \"download\"],\n second: [\"name\"],\n third: [\"history\", \"switchboard\", \"close\"],\n} as const;\n\n/**\n * Ordered list of toolbar slot names.\n */\nexport const controlSlots = keys(defaultControlSlots);\n\n/**\n * Ordered list of all built-in document toolbar control names.\n *\n * The order is derived from `defaultControlSlots`.\n */\nexport const documentToolbarControls = [\n ...defaultControlSlots.first,\n ...defaultControlSlots.second,\n ...defaultControlSlots.third,\n] as const;\n\n/**\n * Default component implementation for each built-in toolbar control.\n *\n * These components are used unless a matching entry is provided through\n * `componentOverrides`.\n */\nexport const defaultControlComponents: DefaultToolbarControlComponents = {\n undo: ToolbarUndoButton,\n redo: ToolbarRedoButton,\n download: ToolbarDownloadButton,\n name: ToolbarName,\n switchboard: ToolbarSwitchboardButton,\n history: ToolbarHistoryButton,\n close: ToolbarCloseButton,\n};\n","import type { PHDocument } from \"@powerhousedao/shared/document-model\";\nimport {\n defaultTo,\n filter,\n hasAtLeast,\n isArray,\n isDefined,\n isIncludedIn,\n map,\n pipe,\n prop,\n} from \"remeda\";\nimport {\n defaultControlComponents,\n defaultControlSlots,\n documentToolbarControls,\n} from \"./constants.js\";\nimport type {\n ControlPosition,\n ControlSlot,\n CustomToolbarControl,\n CustomToolbarControlList,\n CustomToolbarControls,\n DocumentToolbarControlName,\n ToolbarControlComponents,\n} from \"./types.js\";\n\n/**\n * Creates a predicate for checking whether a built-in toolbar control should render.\n *\n * A control renders when it is included in `enabledControls` and absent from\n * `disabledControls`. When `enabledControls` is omitted, all built-in controls\n * are considered enabled. When a control appears in both lists,\n * `disabledControls` takes precedence.\n */\nexport function makeIsEnabledChecker(args: {\n enabledControls: DocumentToolbarControlName[] | undefined;\n disabledControls: DocumentToolbarControlName[] | undefined;\n}) {\n const { enabledControls = documentToolbarControls, disabledControls = [] } =\n args;\n\n return (control: DocumentToolbarControlName) =>\n isIncludedIn(control, enabledControls) &&\n !isIncludedIn(control, disabledControls);\n}\n\n/**\n * Creates a getter for rendering the built-in toolbar controls in a slot.\n *\n * The returned function resolves the controls assigned to a slot, filters them\n * through the enabled/disabled control lists, applies any component overrides,\n * and renders each control with the current document.\n */\nexport function makeToolbarControlsRenderer(args: {\n document: PHDocument | undefined;\n enabledControls?: DocumentToolbarControlName[];\n disabledControls?: DocumentToolbarControlName[];\n componentOverrides?: ToolbarControlComponents;\n}) {\n const { document, enabledControls, disabledControls, componentOverrides } =\n args;\n\n const checkIsEnabled = makeIsEnabledChecker({\n enabledControls,\n disabledControls,\n });\n\n const renderComponent = (control: DocumentToolbarControlName) =>\n pipe(\n prop(componentOverrides, control),\n defaultTo(prop(defaultControlComponents, control)),\n (Component) => <Component document={document} key={control} />,\n );\n\n return (slot: ControlSlot) =>\n pipe(\n prop(defaultControlSlots, slot),\n filter(checkIsEnabled),\n map(renderComponent),\n );\n}\n\n/**\n * Checks whether a custom control should render in the requested position.\n *\n * Controls without an explicit position are treated as `\"start\"`.\n */\nfunction isControlInPosition(\n control: Pick<CustomToolbarControl, \"position\">,\n position: ControlPosition,\n) {\n return defaultTo(control.position, \"start\") === position;\n}\n\n/**\n * Creates a getter for rendering custom controls in a slot and position.\n *\n * The returned function resolves the custom control or controls assigned to a\n * slot, then renders only the controls that belong in the requested position.\n */\nexport function makeCustomControlsRenderer(args: {\n document: PHDocument | undefined;\n customControls: CustomToolbarControls | undefined;\n}) {\n const { document, customControls = {} } = args;\n\n return (slot: ControlSlot, pos: ControlPosition) => {\n const controlOrControlList = prop(customControls, slot);\n\n if (!isDefined(controlOrControlList)) return null;\n\n if (isArray(controlOrControlList))\n return renderCustomControlList(controlOrControlList, pos, document);\n return renderCustomControl(controlOrControlList, pos, document);\n };\n}\n\n/**\n * Renders a single custom control when it belongs in the requested position.\n */\nfunction renderCustomControl(\n control: CustomToolbarControl,\n pos: ControlPosition,\n document: PHDocument | undefined,\n) {\n if (!isControlInPosition(control, pos)) return null;\n\n const Component = control.component;\n return <Component document={document} />;\n}\n\n/**\n * Renders a list of custom controls for the requested position.\n *\n * Returns `null` when no controls in the list belong in that position.\n */\nfunction renderCustomControlList(\n controls: CustomToolbarControlList,\n pos: ControlPosition,\n document: PHDocument | undefined,\n) {\n const controlsInPosition = filter(controls, (control) =>\n isControlInPosition(control, pos),\n );\n\n if (!hasAtLeast(controlsInPosition, 1)) return null;\n\n return (\n <>\n {map(controlsInPosition, ({ component: Component, key }) => (\n <Component key={key} document={document} />\n ))}\n </>\n );\n}\n","import { useSelectedDocumentSafe } from \"@powerhousedao/reactor-browser\";\nimport { map } from \"remeda\";\nimport { controlSlots } from \"./constants.js\";\nimport { ToolbarContainer, ToolbarControlsContainer } from \"./containers.js\";\nimport type {\n ControlsContainerSlotProps,\n DocumentToolbarProps,\n} from \"./types.js\";\nimport {\n makeCustomControlsRenderer,\n makeToolbarControlsRenderer,\n} from \"./utils.js\";\n\n/**\n * Renders a document toolbar.\n *\n * By default, the toolbar renders the built-in document controls grouped into\n * toolbar slots. The controls operate on the provided `document`, or on the\n * currently selected document when no document is provided.\n *\n * Use `enabledControls` and `disabledControls` to control which built-in\n * controls are shown. Use `componentOverrides` to replace individual built-in\n * controls while keeping the default toolbar layout. Use `customControls` to\n * insert additional controls before or after the built-in controls in a slot.\n *\n * To take over the toolbar contents completely, pass `children`.\n */\nexport function DocumentToolbar(props: DocumentToolbarProps) {\n const [selectedDocument] = useSelectedDocumentSafe();\n const {\n toolbarClassName,\n document = selectedDocument,\n toolbarContainer: Container = ToolbarContainer,\n } = props;\n\n if (\"children\" in props) {\n return <Container className={toolbarClassName}>{props.children}</Container>;\n }\n\n return (\n <Container className={toolbarClassName}>\n {map(controlSlots, (slot) => (\n <ControlsContainerSlot\n {...props}\n document={document}\n slot={slot}\n key={slot}\n />\n ))}\n </Container>\n );\n}\n\n/**\n * Renders one toolbar controls slot.\n *\n * Custom controls with position `\"start\"` are rendered before the built-in\n * controls for the slot. Custom controls with position `\"end\"` are rendered\n * after them.\n */\nfunction ControlsContainerSlot(props: ControlsContainerSlotProps) {\n const {\n slot,\n document,\n controlsContainerClassName,\n enabledControls,\n disabledControls,\n componentOverrides,\n customControls,\n controlsContainer: ControlsContainer = ToolbarControlsContainer,\n } = props;\n\n const renderToolbarControls = makeToolbarControlsRenderer({\n document,\n enabledControls,\n disabledControls,\n componentOverrides,\n });\n\n const renderCustomControls = makeCustomControlsRenderer({\n document,\n customControls,\n });\n\n return (\n <ControlsContainer className={controlsContainerClassName}>\n {renderCustomControls(slot, \"start\")}\n {renderToolbarControls(slot)}\n {renderCustomControls(slot, \"end\")}\n </ControlsContainer>\n );\n}\n","import { Icon, Modal } from \"#design-system\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { ModalButton } from \"./modal-button.js\";\n\ntype ModalProps = ComponentPropsWithoutRef<typeof Modal>;\n\nexport type ConnectReplaceDuplicateModalProps = {\n readonly open?: boolean;\n readonly onOpenChange?: (open: boolean) => void;\n readonly title?: string;\n readonly fileName?: string;\n readonly message?: string;\n readonly duplicateLabel?: string;\n readonly onDuplicate: () => void;\n readonly overlayProps?: ModalProps[\"overlayProps\"];\n readonly contentProps?: ModalProps[\"contentProps\"];\n};\n\nexport function ConnectReplaceDuplicateModal(\n props: ConnectReplaceDuplicateModalProps,\n) {\n const {\n open,\n onOpenChange,\n title = \"Document Already Exists\",\n fileName,\n message,\n duplicateLabel = \"Create Copy\",\n onDuplicate,\n overlayProps,\n contentProps,\n } = props;\n\n const defaultMessage = fileName\n ? `A document named \"${fileName}\" already exists in this location. Would you like to replace it or create a copy?`\n : \"A document with the same name already exists in this location. Would you like to replace it or create a copy?\";\n\n return (\n <Modal\n open={open}\n onOpenChange={onOpenChange}\n overlayProps={overlayProps}\n contentProps={contentProps}\n >\n <div className=\"w-[450px] p-6\">\n <div className=\"flex items-center justify-between pb-2\">\n <div className=\"text-2xl font-bold text-gray-900 dark:text-slate-100\">\n {title}\n </div>\n <button\n type=\"button\"\n className=\"flex size-6 items-center justify-center rounded-md outline-none hover:bg-gray-100 dark:hover:bg-slate-700\"\n onClick={() => onOpenChange?.(false)}\n >\n <Icon name=\"XmarkLight\" size={24} />\n </button>\n </div>\n <div className=\"my-6 rounded-md bg-gray-50 p-4 text-center text-gray-900 dark:bg-slate-700 dark:text-slate-100\">\n {message || defaultMessage}\n </div>\n <div className=\"mt-8 flex\">\n <ModalButton variant=\"confirm\" onClick={onDuplicate}>\n {duplicateLabel}\n </ModalButton>\n </div>\n </div>\n </Modal>\n );\n}\n","import type { UploadFileItemStatus } from \"../upload-file-item.js\";\n\ntype ErrorDetailsProps = {\n readonly status: UploadFileItemStatus;\n readonly errorDetails?: string;\n};\n\nexport function UploadFileItemErrorDetails(props: ErrorDetailsProps) {\n const { status, errorDetails } = props;\n\n if (\n !(\n (status === \"failed\" || status === \"unsupported-document-type\") &&\n errorDetails\n )\n )\n return null;\n\n return (\n <div className=\"text-xs leading-[18px] wrap-break-word text-gray-500 dark:text-slate-400\">\n {errorDetails}\n </div>\n );\n}\n","import type { IconName } from \"#design-system\";\nimport { Icon } from \"#design-system\";\nimport type { DocumentTypeIcon } from \"@powerhousedao/reactor-browser\";\nimport type { ComponentPropsWithoutRef } from \"react\";\ntype HeaderProps = ComponentPropsWithoutRef<\"div\"> & {\n readonly fileName: string;\n readonly fileSize: string;\n readonly documentType?: DocumentTypeIcon;\n readonly onClose?: () => void;\n};\n\nfunction getDocumentIcon(documentType?: DocumentTypeIcon): IconName {\n switch (documentType) {\n case \"analytics-processor\":\n return \"AnalyticsProcessorModule\";\n case \"relational-processor\":\n return \"RelationalProcessorModule\";\n case \"codegen-processor\":\n return \"CodegenProcessorModule\";\n case \"app\":\n return \"AppModule\";\n case \"document-model\":\n return \"DocumentModelModule\";\n case \"editor\":\n return \"EditorModule\";\n case \"package\":\n return \"PackageModule\";\n case \"subgraph\":\n return \"SubgraphModule\";\n default:\n return \"PowerhouseDocumentModule\";\n }\n}\n\nexport function UploadFileItemHeader(props: HeaderProps) {\n const { fileName, fileSize, documentType, onClose, ...delegatedProps } =\n props;\n\n return (\n <div className=\"flex items-center gap-2\" {...delegatedProps}>\n <div className=\"flex h-9 w-7 shrink-0 items-center justify-center\">\n <Icon\n name={getDocumentIcon(documentType)}\n size={48}\n className=\"text-gray-700 dark:text-slate-200\"\n />\n </div>\n\n <div className=\"flex flex-1 flex-col gap-0.5\">\n <div className=\"text-xs leading-[18px] font-medium text-gray-900 dark:text-slate-50\">\n {fileName}\n </div>\n <div className=\"text-xs leading-[18px] font-medium text-gray-500 dark:text-slate-400\">\n {fileSize}\n </div>\n </div>\n\n {onClose && (\n <div className=\"flex h-9 w-[18px] shrink-0 items-start justify-center\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"flex h-[18px] w-[18px] items-center justify-center text-gray-700 hover:text-gray-800 dark:text-slate-200 dark:hover:text-slate-100\"\n aria-label=\"Close\"\n >\n <Icon name=\"XmarkLight\" size={18} />\n </button>\n </div>\n )}\n </div>\n );\n}\n","import type { UploadFileItemStatus } from \"../upload-file-item.js\";\n\ntype ProgressBarProps = {\n readonly status: UploadFileItemStatus;\n readonly progress?: number;\n};\n\nexport function UploadFileItemProgressBar(props: ProgressBarProps) {\n const { status, progress = 0 } = props;\n\n if (status !== \"uploading\") return null;\n\n const clamped = Math.min(100, Math.max(0, progress));\n\n return (\n <div className=\"h-2 w-full overflow-hidden rounded-sm bg-gray-200 dark:bg-slate-600 dark:text-slate-100\">\n <div\n className=\"h-full bg-blue-900 transition-all duration-300 ease-out dark:bg-blue-50\"\n style={{ width: `${clamped}%` }}\n />\n </div>\n );\n}\n","import { twMerge } from \"tailwind-merge\";\nimport type { UploadFileItemStatus } from \"../upload-file-item.js\";\n\ntype StatusRowProps = {\n readonly status: UploadFileItemStatus;\n readonly progress?: number;\n readonly onOpenDocument?: () => void;\n readonly onFindResolution?: () => void;\n};\n\nfunction getStatusText(status: UploadFileItemStatus): string {\n switch (status) {\n case \"success\":\n return \"Upload successful\";\n case \"failed\":\n return \"Upload failed\";\n case \"unsupported-document-type\":\n return \"Document not supported by this drive\";\n case \"pending\":\n return \"Pending resolution\";\n case \"conflict\":\n return \"Pending Resolution\";\n case \"uploading\":\n return \"Uploading...\";\n default:\n return \"\";\n }\n}\n\nfunction getStatusColor(status: UploadFileItemStatus): string {\n switch (status) {\n case \"success\":\n return \"text-green-700 dark:text-green-100\";\n case \"failed\":\n case \"unsupported-document-type\":\n case \"pending\":\n case \"conflict\":\n return \"text-red-900 dark:text-red-400\";\n case \"uploading\":\n return \"text-gray-900 dark:text-slate-50\";\n default:\n return \"text-gray-900 dark:text-slate-50\";\n }\n}\n\nfunction shouldShowCTA(\n status: UploadFileItemStatus,\n onOpenDocument?: () => void,\n onFindResolution?: () => void,\n): boolean {\n return (\n (status === \"success\" && Boolean(onOpenDocument)) ||\n (status === \"pending\" && Boolean(onFindResolution)) ||\n (status === \"conflict\" && Boolean(onFindResolution))\n );\n}\n\nfunction getCTAText(status: UploadFileItemStatus): string {\n if (status === \"success\") return \"Open Document\";\n if (status === \"pending\") return \"Find resolution\";\n if (status === \"conflict\") return \"Find resolution\";\n return \"\";\n}\n\nexport function UploadFileItemStatusRow(props: StatusRowProps) {\n const { status, progress = 0, onOpenDocument, onFindResolution } = props;\n\n const handleCTAClick = () => {\n if (status === \"success\" && onOpenDocument) onOpenDocument();\n else if (\n (status === \"pending\" || status === \"conflict\") &&\n onFindResolution\n )\n onFindResolution();\n };\n\n return (\n <div className=\"flex items-center justify-between gap-2\">\n <div\n className={twMerge(\"text-xs leading-[18px]\", getStatusColor(status))}\n >\n {getStatusText(status)}\n </div>\n\n {status === \"uploading\" && (\n <div className=\"text-xs leading-[18px] font-medium text-gray-900 dark:text-slate-50\">\n {Math.round(progress)}%\n </div>\n )}\n\n {shouldShowCTA(status, onOpenDocument, onFindResolution) && (\n <button\n type=\"button\"\n onClick={handleCTAClick}\n className=\"text-xs leading-[18px] text-blue-900 hover:opacity-80 dark:text-blue-100\"\n >\n {getCTAText(status)}\n </button>\n )}\n </div>\n );\n}\n","import type { DocumentTypeIcon } from \"@powerhousedao/reactor-browser\";\nimport { type ComponentPropsWithoutRef, forwardRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { UploadFileItemErrorDetails } from \"./components/error-details.js\";\nimport { UploadFileItemHeader } from \"./components/header.js\";\nimport { UploadFileItemProgressBar } from \"./components/progress-bar.js\";\nimport { UploadFileItemStatusRow } from \"./components/status-row.js\";\n\nexport type UploadFileItemStatus =\n | \"success\"\n | \"failed\"\n | \"pending\"\n | \"uploading\"\n | \"conflict\"\n | \"unsupported-document-type\";\n\nexport type UploadFileItemProps = ComponentPropsWithoutRef<\"div\"> & {\n readonly fileName: string;\n readonly fileSize: string;\n readonly status: UploadFileItemStatus;\n readonly documentType?: DocumentTypeIcon;\n readonly progress?: number;\n readonly errorDetails?: string;\n readonly onClose?: () => void;\n readonly onOpenDocument?: () => void;\n readonly onFindResolution?: () => void;\n};\n\nexport const UploadFileItem = forwardRef<HTMLDivElement, UploadFileItemProps>(\n function UploadFileItem(props, ref) {\n const {\n fileName,\n fileSize,\n status,\n documentType,\n progress = 0,\n errorDetails,\n onClose,\n onOpenDocument,\n onFindResolution,\n className,\n ...delegatedProps\n } = props;\n\n return (\n <div\n ref={ref}\n className={twMerge(\n \"flex w-full flex-col gap-0.5 rounded-md border border-gray-100 bg-gray-50 p-2 shadow-sidebar dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n className,\n )}\n {...delegatedProps}\n >\n <UploadFileItemHeader\n fileName={fileName}\n fileSize={fileSize}\n documentType={documentType}\n onClose={onClose}\n />\n\n <div className=\"flex flex-col gap-1\">\n <UploadFileItemStatusRow\n status={status}\n progress={progress}\n onOpenDocument={onOpenDocument}\n onFindResolution={onFindResolution}\n />\n <UploadFileItemProgressBar status={status} progress={progress} />\n <UploadFileItemErrorDetails\n status={status}\n errorDetails={errorDetails}\n />\n </div>\n </div>\n );\n },\n);\n","export function getUploadListTitle(\n count: number,\n explicitTitle?: string,\n): string {\n if (explicitTitle) return explicitTitle;\n return `Uploading ${count} document${count === 1 ? \"\" : \"s\"}`;\n}\n","import { Icon } from \"#design-system\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { useMemo, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport {\n type UploadFileItemProps,\n UploadFileItem,\n} from \"../upload-file-item/upload-file-item.js\";\nimport { getUploadListTitle } from \"./utils.js\";\n\nexport type UploadFileListProps = ComponentPropsWithoutRef<\"div\"> & {\n readonly items: ReadonlyArray<UploadFileItemProps>;\n readonly title?: string;\n readonly defaultCollapsed?: boolean;\n readonly onClose?: () => void;\n};\n\nexport function UploadFileList(props: UploadFileListProps) {\n const {\n items,\n title,\n defaultCollapsed = false,\n onClose,\n className,\n ...delegatedProps\n } = props;\n\n const [isCollapsed, setIsCollapsed] = useState<boolean>(defaultCollapsed);\n\n const computedTitle = useMemo(\n () => getUploadListTitle(items.length, title),\n [items.length, title],\n );\n\n return (\n <div\n className={twMerge(\n \"w-89.5 rounded-md border border-gray-100 bg-gray-50 p-4 shadow-charcoal dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n className,\n )}\n {...delegatedProps}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <button\n type=\"button\"\n aria-expanded={!isCollapsed}\n aria-label={isCollapsed ? \"Expand list\" : \"Collapse list\"}\n onClick={() => setIsCollapsed((v) => !v)}\n className=\"min-w-0 flex-1 text-left text-sm/4 font-medium text-gray-900 hover:opacity-80 dark:text-slate-50\"\n >\n {computedTitle}\n </button>\n\n <div className=\"flex shrink-0 items-center gap-4\">\n {/* Collapse / Expand Toggle */}\n <button\n type=\"button\"\n aria-label={isCollapsed ? \"Expand\" : \"Collapse\"}\n onClick={() => setIsCollapsed((v) => !v)}\n className=\"text-gray-900 hover:opacity-80 dark:text-slate-50\"\n >\n <span\n className={twMerge(\n \"inline-block size-4 transition-transform select-none\",\n isCollapsed ? \"-rotate-90\" : \"rotate-0\",\n )}\n >\n <Icon name=\"CaretDown\" size={16} aria-hidden=\"true\" />\n </span>\n </button>\n\n {/* Close Button */}\n {onClose && (\n <button\n type=\"button\"\n aria-label=\"Close\"\n onClick={onClose}\n className=\"text-gray-900 hover:opacity-80 dark:text-slate-50\"\n >\n <span className=\"inline-block size-4 select-none\">\n <Icon name=\"XmarkLight\" size={16} aria-hidden=\"true\" />\n </span>\n </button>\n )}\n </div>\n </div>\n\n {/* Body (collapsible) */}\n {!isCollapsed && (\n <div className=\"mt-4 flex max-h-[404px] flex-col gap-4 overflow-x-visible overflow-y-auto p-2\">\n {items.map((item, idx) => (\n <UploadFileItem key={`${item.fileName}-${idx}`} {...item} />\n ))}\n </div>\n )}\n </div>\n );\n}\n","import type {\n ConflictResolution,\n DocumentTypeIcon,\n FileUploadProgress,\n} from \"@powerhousedao/reactor-browser\";\nimport type { Node } from \"@powerhousedao/shared/document-drive\";\nimport type { UploadFileItemProps } from \"../upload-file-item/upload-file-item.js\";\n\n// Upload tracking types\nexport type UploadTracker = {\n id: string;\n fileName: string;\n fileSize: string;\n status:\n | \"pending\"\n | \"uploading\"\n | \"success\"\n | \"failed\"\n | \"conflict\"\n | \"unsupported-document-type\";\n progress: number;\n errorDetails?: string;\n fileNode?: Node;\n documentType?: DocumentTypeIcon;\n // Store upload context for re-processing conflicts\n file?: File;\n parentNode?: Node;\n duplicateType?: \"id\" | \"name\";\n};\n\nexport type OnAddFileWithProgress = (\n file: File,\n parent: Node | undefined,\n onProgress?: (progress: FileUploadProgress) => void,\n resolveConflict?: ConflictResolution,\n) => Promise<Node | undefined> | Node | undefined;\n\n// Utility functions\nexport function generateId(): string {\n return `upload_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n}\n\nexport function formatFileSize(bytes: number): string {\n if (bytes === 0) return \"0 Bytes\";\n const k = 1024;\n const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\n}\n\nexport function mapProgressStageToStatus(\n stage: FileUploadProgress[\"stage\"],\n): UploadTracker[\"status\"] {\n switch (stage) {\n case \"loading\":\n case \"initializing\":\n return \"pending\";\n case \"uploading\":\n return \"uploading\";\n case \"complete\":\n return \"success\";\n case \"failed\":\n return \"failed\";\n case \"conflict\":\n return \"conflict\";\n case \"unsupported-document-type\":\n return \"unsupported-document-type\";\n default:\n return \"pending\";\n }\n}\n\nexport function mapUploadsToFileItems(\n uploadsArray: (UploadTracker | undefined)[],\n removeUpload: (uploadId: string) => void,\n setSelectedNodeFn?: (nodeOrNodeSlug: Node | string | undefined) => void,\n onConflictResolution?: (uploadId: string) => void,\n): UploadFileItemProps[] {\n return uploadsArray\n .filter(\n (upload): upload is NonNullable<typeof upload> => upload !== undefined,\n )\n .map((upload) => ({\n fileName: upload.fileName,\n fileSize: upload.fileSize,\n status: upload.status,\n progress: upload.progress,\n errorDetails: upload.errorDetails,\n documentType: upload.documentType,\n onClose: () => {\n removeUpload(upload.id);\n },\n onOpenDocument:\n upload.status === \"success\"\n ? () => {\n if (upload.fileNode && setSelectedNodeFn) {\n setSelectedNodeFn(upload.fileNode);\n } else {\n console.error(\n \"Opening document for upload:\",\n upload.id,\n \"- fileNode not available or setSelectedNode not provided\",\n );\n }\n }\n : undefined,\n onFindResolution:\n upload.status === \"failed\"\n ? () => {\n console.log(\"Finding resolution for upload:\", upload.id);\n }\n : upload.status === \"conflict\"\n ? () => {\n console.log(\n \"Finding conflict resolution for upload:\",\n upload.id,\n );\n onConflictResolution?.(upload.id);\n }\n : undefined,\n }));\n}\n","import type { Node } from \"@powerhousedao/shared/document-drive\";\nimport { type ComponentPropsWithoutRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { UploadFileList } from \"../upload-file-list/upload-file-list.js\";\nimport { mapUploadsToFileItems, type UploadTracker } from \"./utils.js\";\n\nexport type UploadFileListContainerProps = ComponentPropsWithoutRef<\"div\"> & {\n readonly uploadsArray: (UploadTracker | undefined)[];\n readonly uploadsCount: number;\n readonly removeUpload: (uploadId: string) => void;\n readonly clearAllUploads: () => void;\n readonly setSelectedNode?: (\n nodeOrNodeSlug: Node | string | undefined,\n ) => void;\n readonly onClose?: () => void;\n readonly onConflictResolution?: (uploadId: string) => void;\n};\n\nexport function UploadFileListContainer(props: UploadFileListContainerProps) {\n const {\n uploadsArray,\n uploadsCount,\n removeUpload,\n clearAllUploads,\n setSelectedNode,\n onClose,\n onConflictResolution,\n className,\n ...delegatedProps\n } = props;\n\n // Don't render if there are no uploads\n if (uploadsCount === 0) return null;\n\n const items = mapUploadsToFileItems(\n uploadsArray,\n removeUpload,\n setSelectedNode,\n onConflictResolution,\n );\n\n const handleClose = onClose ?? clearAllUploads;\n\n return (\n <div\n className={twMerge(\"fixed right-4 bottom-4 z-1001\", className)}\n {...delegatedProps}\n >\n <UploadFileList items={items} onClose={handleClose} />\n </div>\n );\n}\n","import type {\n ConflictResolution,\n FileUploadProgress,\n} from \"@powerhousedao/reactor-browser\";\nimport type { Node } from \"@powerhousedao/shared/document-drive\";\nimport { useCallback, useEffect, useReducer } from \"react\";\nimport {\n type OnAddFileWithProgress,\n type UploadTracker,\n formatFileSize,\n generateId,\n mapProgressStageToStatus,\n} from \"./utils.js\";\n\n// State type\ntype UploadsState = {\n [uploadId: string]: UploadTracker | undefined;\n};\n\n// Action types\ntype UploadAction =\n | {\n type: \"ADD_UPLOAD\";\n payload: {\n id: string;\n fileName: string;\n fileSize: string;\n };\n }\n | {\n type: \"UPDATE_PROGRESS\";\n payload: {\n id: string;\n progress: FileUploadProgress;\n };\n }\n | {\n type: \"SET_FILE_NODE\";\n payload: {\n id: string;\n fileNode?: Node;\n };\n }\n | {\n type: \"SET_ERROR\";\n payload: {\n id: string;\n error: string;\n };\n }\n | {\n type: \"REMOVE_UPLOAD\";\n payload: {\n id: string;\n };\n }\n | {\n type: \"CLEAR_ALL_UPLOADS\";\n }\n | {\n type: \"SET_CONFLICT_DATA\";\n payload: {\n id: string;\n file: File;\n parentNode?: Node;\n };\n }\n | {\n type: \"CLEAR_CONFLICTED_UPLOADS\";\n };\n\n// Reducer function\nfunction uploadsReducer(\n state: UploadsState,\n action: UploadAction,\n): UploadsState {\n switch (action.type) {\n case \"ADD_UPLOAD\":\n return {\n ...state,\n [action.payload.id]: {\n id: action.payload.id,\n fileName: action.payload.fileName,\n fileSize: action.payload.fileSize,\n status: \"pending\",\n progress: 0,\n fileNode: undefined,\n },\n };\n\n case \"UPDATE_PROGRESS\": {\n const currentUpload = state[action.payload.id];\n if (!currentUpload) return state;\n\n return {\n ...state,\n [action.payload.id]: {\n ...currentUpload,\n status: mapProgressStageToStatus(action.payload.progress.stage),\n progress: action.payload.progress.progress,\n errorDetails: action.payload.progress.error,\n // Update documentType if provided\n ...(action.payload.progress.documentType && {\n documentType: action.payload.progress.documentType,\n }),\n // Update duplicateType if provided (for conflicts)\n ...(action.payload.progress.duplicateType && {\n duplicateType: action.payload.progress.duplicateType,\n }),\n // Update fileNode if provided (for deferred uploads after discovery)\n ...(action.payload.progress.fileNode && {\n fileNode: action.payload.progress.fileNode,\n }),\n },\n };\n }\n\n case \"SET_FILE_NODE\": {\n const uploadToUpdate = state[action.payload.id];\n if (!uploadToUpdate) return state;\n\n return {\n ...state,\n [action.payload.id]: {\n ...uploadToUpdate,\n fileNode: action.payload.fileNode,\n },\n };\n }\n\n case \"SET_ERROR\": {\n const failedUpload = state[action.payload.id];\n if (!failedUpload) return state;\n\n return {\n ...state,\n [action.payload.id]: {\n ...failedUpload,\n status: failedUpload.status || \"failed\",\n errorDetails: action.payload.error,\n },\n };\n }\n\n case \"REMOVE_UPLOAD\": {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { [action.payload.id]: removed, ...rest } = state;\n return rest;\n }\n\n case \"CLEAR_ALL_UPLOADS\": {\n return {};\n }\n\n case \"SET_CONFLICT_DATA\": {\n const conflictUpload = state[action.payload.id];\n if (!conflictUpload) return state;\n\n return {\n ...state,\n [action.payload.id]: {\n ...conflictUpload,\n file: action.payload.file,\n parentNode: action.payload.parentNode,\n },\n };\n }\n\n case \"CLEAR_CONFLICTED_UPLOADS\": {\n // Filter out all uploads with status \"conflict\"\n const filteredUploads: UploadsState = {};\n for (const [id, upload] of Object.entries(state)) {\n if (upload && upload.status !== \"conflict\") {\n filteredUploads[id] = upload;\n }\n }\n return filteredUploads;\n }\n\n default:\n return state;\n }\n}\n\n// Hook\nexport function useUploadTracker(useLocalStorage = false, driveId?: string) {\n const getInitialState = useCallback((): UploadsState => {\n if (useLocalStorage && driveId) {\n try {\n const stored = localStorage.getItem(`uploadTracker_${driveId}`);\n if (stored) {\n const parsed = JSON.parse(stored) as UploadsState;\n return parsed;\n }\n return {};\n } catch (error) {\n console.error(\n \"Failed to load upload tracker from localStorage:\",\n error,\n );\n return {};\n }\n }\n return {};\n }, [useLocalStorage, driveId]);\n\n const [uploads, dispatch] = useReducer(uploadsReducer, getInitialState());\n\n // Save to localStorage whenever uploads change\n useEffect(() => {\n if (useLocalStorage && driveId) {\n try {\n localStorage.setItem(\n `uploadTracker_${driveId}`,\n JSON.stringify(uploads),\n );\n } catch (error) {\n console.error(\"Failed to save upload tracker to localStorage:\", error);\n }\n }\n }, [uploads, useLocalStorage, driveId]);\n\n const createUploadHandler = useCallback(\n (onAddFile?: OnAddFileWithProgress) => {\n if (!onAddFile) return undefined;\n\n return async (file: File, parent: Node | undefined) => {\n const fileId = generateId();\n\n // Add upload to tracking\n dispatch({\n type: \"ADD_UPLOAD\",\n payload: {\n id: fileId,\n fileName: file.name,\n fileSize: formatFileSize(file.size),\n },\n });\n\n // Create progress callback for this specific file\n const progressCallback = (progress: FileUploadProgress) => {\n dispatch({\n type: \"UPDATE_PROGRESS\",\n payload: {\n id: fileId,\n progress,\n },\n });\n\n // Store file and parent data when conflict is detected\n if (progress.stage === \"conflict\") {\n dispatch({\n type: \"SET_CONFLICT_DATA\",\n payload: {\n id: fileId,\n file,\n parentNode: parent,\n },\n });\n }\n };\n\n try {\n // Call the original onAddFile with our progress callback\n const fileNode = await onAddFile(file, parent, progressCallback);\n\n // Store the FileNode\n dispatch({\n type: \"SET_FILE_NODE\",\n payload: {\n id: fileId,\n fileNode: fileNode || undefined,\n },\n });\n } catch (error) {\n dispatch({\n type: \"SET_ERROR\",\n payload: {\n id: fileId,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n });\n }\n };\n },\n [],\n );\n\n const removeUpload = useCallback((uploadId: string) => {\n dispatch({\n type: \"REMOVE_UPLOAD\",\n payload: {\n id: uploadId,\n },\n });\n }, []);\n\n const clearAllUploads = useCallback(() => {\n dispatch({\n type: \"CLEAR_ALL_UPLOADS\",\n });\n }, []);\n\n const clearConflictedUploads = useCallback(() => {\n dispatch({\n type: \"CLEAR_CONFLICTED_UPLOADS\",\n });\n }, []);\n\n const getUploadsArray = useCallback(() => {\n return Object.values(uploads);\n }, [uploads]);\n\n const getUploadsCount = useCallback(() => {\n return Object.keys(uploads).length;\n }, [uploads]);\n\n const resolveConflict = useCallback(\n (\n uploadId: string,\n resolution: ConflictResolution,\n onAddFile?: OnAddFileWithProgress,\n ) => {\n const upload = uploads[uploadId];\n if (!upload?.file || !onAddFile) {\n console.error(\n \"Cannot resolve conflict: missing upload data or onAddFile function\",\n );\n return;\n }\n\n // Re-call onAddFile with the conflict resolution\n const progressCallback = (progress: FileUploadProgress) => {\n dispatch({\n type: \"UPDATE_PROGRESS\",\n payload: {\n id: uploadId,\n progress,\n },\n });\n };\n\n const result = onAddFile(\n upload.file,\n upload.parentNode,\n progressCallback,\n resolution,\n );\n\n // Handle both Promise and direct return values\n Promise.resolve(result)\n .then((fileNode: Node | undefined) => {\n if (fileNode) {\n dispatch({\n type: \"SET_FILE_NODE\",\n payload: {\n id: uploadId,\n fileNode,\n },\n });\n }\n })\n .catch((error: unknown) => {\n dispatch({\n type: \"SET_ERROR\",\n payload: {\n id: uploadId,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n });\n });\n },\n [uploads],\n );\n\n return {\n uploads,\n uploadsArray: getUploadsArray(),\n uploadsCount: getUploadsCount(),\n createUploadHandler,\n removeUpload,\n clearAllUploads,\n clearConflictedUploads,\n resolveConflict,\n };\n}\n","import { Icon } from \"#design-system\";\nimport { setSelectedNode, useDropFile } from \"@powerhousedao/reactor-browser\";\nimport type { Node } from \"@powerhousedao/shared/document-drive\";\nimport {\n type ComponentPropsWithoutRef,\n type ReactNode,\n useEffect,\n useState,\n} from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ConnectReplaceDuplicateModal } from \"../modal/replace-duplicate-modal.js\";\nimport { UploadFileListContainer } from \"./upload-file-list-container.js\";\nimport { useUploadTracker } from \"./use-upload-tracker.js\";\nimport { type OnAddFileWithProgress } from \"./utils.js\";\n\nexport type DropZoneProps = ComponentPropsWithoutRef<\"div\"> & {\n readonly title?: string;\n readonly subtitle?: string;\n readonly node?: Node;\n readonly enable?: boolean;\n readonly children?: ReactNode;\n readonly onAddFile?: OnAddFileWithProgress;\n readonly useLocalStorage?: boolean;\n readonly driveId?: string;\n readonly acceptedFileExtensions?: string[];\n};\n\nexport function DropZone(props: DropZoneProps) {\n const {\n title = \"Drag your documents\",\n subtitle = \"to drop them in the currently selected folder.\",\n node: _node,\n enable = true,\n children,\n onAddFile,\n useLocalStorage = false,\n driveId,\n acceptedFileExtensions: _acceptedFileExtensions = [\".zip\", \".phd\", \".phdm\"],\n className,\n ...delegatedProps\n } = props;\n\n // Modal state for conflict resolution\n const [modalOpen, setModalOpen] = useState(false);\n const [conflictUploadId, setConflictUploadId] = useState<string | null>(null);\n\n // Upload tracking with the new hook\n const {\n uploadsArray,\n uploadsCount,\n createUploadHandler,\n clearAllUploads,\n clearConflictedUploads,\n removeUpload,\n resolveConflict,\n } = useUploadTracker(useLocalStorage, driveId);\n\n // Clear conflicted uploads on mount\n useEffect(() => {\n clearConflictedUploads();\n }, []);\n\n // Create the upload handler from the hook\n const handleAddFile = createUploadHandler(onAddFile) ?? (async () => {});\n\n // Handle conflict resolution modal\n const handleConflictResolution = (uploadId: string) => {\n setConflictUploadId(uploadId);\n setModalOpen(true);\n };\n\n const handleDuplicate = () => {\n if (conflictUploadId && onAddFile) {\n resolveConflict(conflictUploadId, \"duplicate\", onAddFile);\n }\n setModalOpen(false);\n setConflictUploadId(null);\n };\n\n const handleModalClose = () => {\n setModalOpen(false);\n setConflictUploadId(null);\n };\n\n const { isDropTarget, ...dropProps } = useDropFile(handleAddFile);\n\n return (\n <div\n className={twMerge(\"relative\", className)}\n {...(enable ? dropProps : {})}\n {...delegatedProps}\n >\n {children}\n\n {enable && isDropTarget && (\n <div className=\"pointer-events-none fixed inset-0 z-1000 flex min-h-screen w-screen items-center justify-center bg-gray-900/50 dark:bg-slate-900/50\">\n <div className=\"rounded-3xl bg-gray-50 p-6 shadow-charcoal dark:bg-slate-800\">\n <div className=\"relative flex h-32.5 w-100 flex-col items-center justify-start overflow-visible rounded-lg border border-dashed border-gray-900 px-4 py-6\">\n <div className=\"text-center text-base/5 text-gray-500 dark:text-slate-400\">\n {title}\n </div>\n <div className=\"text-center text-base/5 text-gray-500 dark:text-slate-400\">\n {subtitle}\n </div>\n\n <span className=\"pointer-events-none absolute -bottom-16 left-1/2 z-10 -translate-x-1/2\">\n <Icon name=\"DocumentIcons\" size={144} aria-hidden=\"true\" />\n </span>\n </div>\n </div>\n </div>\n )}\n\n {/* Upload File List - positioned at bottom right */}\n <UploadFileListContainer\n uploadsArray={uploadsArray}\n uploadsCount={uploadsCount}\n removeUpload={removeUpload}\n clearAllUploads={clearAllUploads}\n setSelectedNode={setSelectedNode}\n onConflictResolution={handleConflictResolution}\n />\n\n {/* Conflict Resolution Modal */}\n <ConnectReplaceDuplicateModal\n open={modalOpen}\n onOpenChange={handleModalClose}\n fileName={\n conflictUploadId\n ? uploadsArray.find((u) => u?.id === conflictUploadId)?.fileName\n : undefined\n }\n onDuplicate={handleDuplicate}\n />\n </div>\n );\n}\n","import {\n useIsDragAndDropEnabled,\n useOnDropFile,\n useSelectedDriveId,\n} from \"@powerhousedao/reactor-browser\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { DropZone } from \"./drop-zone.js\";\nimport type { OnAddFileWithProgress } from \"./utils.js\";\n\nexport function DropZoneWrapper({\n children,\n ...props\n}: { children: React.ReactNode } & ComponentPropsWithoutRef<\"div\">) {\n const isDragAndDropEnabled = useIsDragAndDropEnabled();\n const selectedDriveId = useSelectedDriveId();\n\n const onDropFile = useOnDropFile();\n\n const onAddFile: OnAddFileWithProgress = async (\n file,\n parent,\n onProgress,\n resolveConflict,\n ) => {\n return await onDropFile(file, onProgress, resolveConflict);\n };\n\n if (!isDragAndDropEnabled || !selectedDriveId) {\n return <>{children}</>;\n }\n\n return (\n <DropZone\n onAddFile={onAddFile}\n driveId={selectedDriveId}\n useLocalStorage={true}\n {...props}\n >\n {children}\n </DropZone>\n );\n}\n","import {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"#design-system\";\nimport type { ReactNode } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport type ConnectDropdownMenuItem<TItemId extends string> = {\n id: TItemId;\n label: ReactNode;\n icon?: React.JSX.Element;\n className?: string;\n};\n\nexport interface ConnectDropdownMenuProps<TItemId extends string> {\n readonly children: ReactNode;\n readonly items: ConnectDropdownMenuItem<TItemId>[];\n readonly open?: boolean;\n readonly onItemClick: (id: TItemId) => void;\n readonly onOpenChange?: (open: boolean) => void;\n readonly menuClassName?: string;\n}\n\nexport function ConnectDropdownMenu<TItemId extends string>(\n props: ConnectDropdownMenuProps<TItemId>,\n) {\n const { children, items, open, onItemClick, onOpenChange, menuClassName } =\n props;\n\n return (\n <DropdownMenu onOpenChange={onOpenChange} open={open}>\n <DropdownMenuTrigger asChild className=\"outline-none\">\n {children}\n </DropdownMenuTrigger>\n <DropdownMenuContent\n className={twMerge(\n \"cursor-pointer rounded-2xl border border-gray-200 bg-gray-50 text-sm font-medium text-gray-500 shadow-lg dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n menuClassName,\n )}\n >\n {items.map(({ id, label, icon, className }) => (\n <DropdownMenuItem\n className={twMerge(\n \"flex items-center px-5 py-2 outline-none first-of-type:rounded-t-2xl first-of-type:pt-3 last-of-type:rounded-b-2xl last-of-type:pb-3 hover:bg-gray-50 dark:hover:bg-slate-800\",\n className,\n )}\n key={id}\n onClick={(e) => e.stopPropagation()}\n onSelect={() => onItemClick(id)}\n >\n {icon ? <span className=\"mr-2 inline-block\">{icon}</span> : null}\n {label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n","import { Icon } from \"#design-system\";\n\nexport type EditorActionButtonsProps = {\n readonly onSwitchboardLinkClick?: (() => void) | undefined;\n readonly onDownloadDocument?: (() => void) | undefined;\n readonly onClose: () => void;\n readonly onShowRevisionHistory?: (() => void) | undefined;\n readonly onShowTimeline?: (() => void) | undefined;\n};\n\nexport function EditorActionButtons(props: EditorActionButtonsProps) {\n const {\n onSwitchboardLinkClick,\n onDownloadDocument: _onDownloadDocument,\n onClose,\n onShowRevisionHistory,\n onShowTimeline,\n } = props;\n\n return (\n <div className=\"flex items-center gap-x-2\">\n {onSwitchboardLinkClick && (\n <button\n className=\"grid size-8 place-items-center rounded-lg border border-gray-200 bg-gray-50 text-gray-900 disabled:cursor-not-allowed disabled:text-gray-500 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:disabled:text-slate-400\"\n onClick={onSwitchboardLinkClick}\n disabled={!onSwitchboardLinkClick}\n >\n <Icon name=\"Drive\" size={16} />\n </button>\n )}\n {onShowRevisionHistory && (\n <button\n className=\"grid size-8 place-items-center rounded-lg border border-gray-200 bg-gray-50 text-gray-900 disabled:cursor-not-allowed disabled:text-gray-500 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:disabled:text-slate-400\"\n onClick={onShowRevisionHistory}\n disabled={!onShowRevisionHistory}\n >\n <Icon name=\"History\" size={16} />\n </button>\n )}\n {onShowTimeline && (\n <button\n className=\"grid size-8 place-items-center rounded-lg border border-gray-200 bg-gray-50 text-gray-900 disabled:cursor-not-allowed disabled:text-gray-500 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:disabled:text-slate-400\"\n onClick={onShowTimeline}\n disabled={!onShowTimeline}\n >\n <Icon name=\"Timeline\" size={16} />\n </button>\n )}\n <button\n className=\"grid size-8 place-items-center rounded-lg border border-gray-200 bg-gray-50 text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\"\n onClick={onClose}\n >\n <Icon name=\"XmarkLight\" size={16} />\n </button>\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport type EditorUndoRedoButtonsProps = {\n readonly canUndo: boolean;\n readonly canRedo: boolean;\n readonly undo: () => void;\n readonly redo: () => void;\n};\nexport function EditorUndoRedoButtons(props: EditorUndoRedoButtonsProps) {\n const { canUndo, canRedo, undo, redo } = props;\n const buttonStyles =\n \"w-8 h-8 rounded-lg flex justify-center items-center rounded border border-gray-200 bg-gray-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\";\n return (\n <div className=\"flex gap-x-2 text-gray-500 dark:text-slate-400\">\n <button className={buttonStyles} disabled={!canUndo} onClick={undo}>\n <Icon\n className={twMerge(\n \"-scale-x-100\",\n canUndo\n ? \"text-gray-900 active:opacity-50 dark:text-slate-50\"\n : \"text-gray-500 dark:text-slate-400\",\n )}\n name=\"RedoArrow\"\n size={18}\n />\n </button>\n <button className={buttonStyles} disabled={!canRedo} onClick={redo}>\n <Icon\n className={twMerge(\n canRedo\n ? \"text-gray-900 active:opacity-50 dark:text-slate-50\"\n : \"text-gray-500 dark:text-slate-400\",\n )}\n name=\"RedoArrow\"\n size={18}\n />\n </button>\n </div>\n );\n}\n","\"data:image/png;base64,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\"","import ImgPowerhouse from \"#assets/powerhouse-rounded.png\";\nimport type { CSSProperties } from \"react\";\n\ntype Props = {\n readonly address: `0x${string}`;\n readonly chainId?: number;\n readonly avatarUrl?: string;\n readonly size?: CSSProperties[\"width\"];\n};\nexport function ENSAvatar(props: Props) {\n const { avatarUrl = ImgPowerhouse, size = \"14px\" } = props;\n const style = {\n width: size,\n height: size,\n };\n\n return (\n <img\n alt=\"ENS Avatar\"\n className=\"flex-none rounded-full object-contain\"\n src={avatarUrl}\n style={style}\n />\n );\n}\n","import { Icon } from \"../../powerhouse/components/icon/icon.js\";\n\nexport const defaultDriveOptions = [\n \"NEW_FOLDER\",\n \"RENAME\",\n \"SETTINGS\",\n] as const;\n\nexport const defaultNodeOptions = [\"RENAME\", \"DELETE\", \"DUPLICATE\"] as const;\n\nexport const normalNodeOptions = [\n \"DUPLICATE\",\n \"RENAME\",\n \"DELETE\",\n \"SETTINGS\",\n] as const;\n\nexport const debugNodeOptions = [\n \"ADD_TRIGGER\",\n \"REMOVE_TRIGGER\",\n \"ADD_INVALID_TRIGGER\",\n] as const;\n\nexport const nodeOptions = [...normalNodeOptions, ...debugNodeOptions] as const;\n\nexport const sharingTypeOptions = [\n {\n value: \"LOCAL\",\n icon: <Icon name=\"Lock\" size={16} />,\n description: \"Only available to you\",\n },\n {\n value: \"CLOUD\",\n icon: <Icon name=\"People\" size={16} />,\n description: \"Only available to people in this drive\",\n },\n {\n value: \"PUBLIC\",\n icon: <Icon name=\"Globe\" size={16} />,\n description: \"Available to everyone\",\n disabled: true,\n },\n] as const;\n\nexport const locationInfoByLocation = {\n CLOUD: {\n title: \"Secure cloud\",\n description: \"End to end encryption between members.\",\n icon: <Icon name=\"Lock\" size={16} />,\n },\n LOCAL: {\n title: \"Local\",\n description: \"Private and only available to you.\",\n icon: <Icon name=\"Hdd\" size={16} />,\n },\n SWITCHBOARD: {\n title: \"Switchboard\",\n description: \"Public and available to everyone.\",\n icon: <Icon name=\"Drive\" size={16} />,\n },\n} as const;\n\nexport const debugNodeOptionsMap = {\n ADD_TRIGGER: {\n label: \"Add Trigger\",\n icon: (\n <Icon\n className=\"text-orange-900 dark:text-orange-100\"\n name=\"Plus\"\n size={16}\n />\n ),\n },\n REMOVE_TRIGGER: {\n label: \"Remove Trigger\",\n icon: (\n <Icon\n className=\"text-orange-900 dark:text-orange-100\"\n name=\"Xmark\"\n size={16}\n />\n ),\n },\n ADD_INVALID_TRIGGER: {\n label: \"Add Trigger\",\n icon: (\n <Icon\n className=\"text-orange-900 dark:text-orange-100\"\n name=\"Exclamation\"\n size={16}\n />\n ),\n },\n} as const;\n\nexport const folderNodeDropdownOptions = {\n DUPLICATE: {\n label: \"Duplicate\",\n icon: <Icon name=\"FilesEarmark\" size={16} />,\n },\n RENAME: {\n label: \"Rename\",\n icon: <Icon name=\"Pencil\" size={16} />,\n },\n DELETE: {\n label: \"Delete\",\n icon: <Icon name=\"Trash\" size={16} />,\n className: \"text-red-900 dark:text-red-400\",\n },\n} as const;\n\nexport const fileNodeDropdownOptions = {\n DOWNLOAD: {\n label: \"Download\",\n icon: <Icon name=\"DownloadFile\" size={16} />,\n },\n ...folderNodeDropdownOptions,\n};\n","export const SYNCING = \"SYNCING\";\nexport const SUCCESS = \"SUCCESS\";\nexport const CONFLICT = \"CONFLICT\";\nexport const MISSING = \"MISSING\";\nexport const ERROR = \"ERROR\";\nexport const INITIAL_SYNC = \"INITIAL_SYNC\";\n\nexport const syncStatuses = [\n INITIAL_SYNC,\n SYNCING,\n SUCCESS,\n CONFLICT,\n MISSING,\n ERROR,\n] as const;\n","import type { IconName, SyncStatus } from \"#design-system\";\nimport { Icon } from \"#design-system\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport {\n CONFLICT,\n ERROR,\n INITIAL_SYNC,\n MISSING,\n SUCCESS,\n SYNCING,\n} from \"../../constants/syncing.js\";\n\nconst syncIcons: Record<SyncStatus, IconName> = {\n SYNCING: \"Syncing\",\n SUCCESS: \"Synced\",\n CONFLICT: \"Error\",\n MISSING: \"Circle\",\n ERROR: \"Error\",\n INITIAL_SYNC: \"Syncing\",\n};\n\nexport type SyncStatusIconProps = Omit<\n ComponentPropsWithoutRef<typeof Icon>,\n \"name\"\n> & {\n syncStatus: SyncStatus;\n overrideSyncIcons?: Partial<Record<SyncStatus, IconName>>;\n};\nexport function SyncStatusIcon(props: SyncStatusIconProps) {\n const { syncStatus, className, overrideSyncIcons = {}, ...iconProps } = props;\n\n const icons = { ...syncIcons, ...overrideSyncIcons };\n\n const syncStatusIcons = {\n [INITIAL_SYNC]: (\n <Icon\n size={16}\n {...iconProps}\n className={twMerge(\"text-blue-900 dark:text-blue-100\", className)}\n name={icons[INITIAL_SYNC]}\n />\n ),\n [SYNCING]: (\n <Icon\n size={16}\n {...iconProps}\n className={twMerge(\"text-blue-900 dark:text-blue-100\", className)}\n name={icons[SYNCING]}\n />\n ),\n [SUCCESS]: (\n <Icon\n size={16}\n {...iconProps}\n className={twMerge(\"text-green-900 dark:text-green-100\", className)}\n name={icons[SUCCESS]}\n />\n ),\n [CONFLICT]: (\n <Icon\n size={16}\n {...iconProps}\n className={twMerge(\"text-orange-900 dark:text-orange-100\", className)}\n name={icons[CONFLICT]}\n />\n ),\n [MISSING]: (\n <Icon\n size={16}\n {...iconProps}\n className={twMerge(\"text-red-900 dark:text-red-400\", className)}\n name={icons[MISSING]}\n />\n ),\n [ERROR]: (\n <Icon\n size={16}\n {...iconProps}\n className={twMerge(\"text-red-900 dark:text-red-400\", className)}\n name={icons[ERROR]}\n />\n ),\n } as const;\n\n return syncStatusIcons[syncStatus];\n}\n","import { Icon } from \"#design-system\";\nimport {\n getSyncStatusSync,\n setSelectedNode,\n showDeleteNodeModal,\n useDownloadDocument,\n useDragNode,\n useNodeActions,\n useSelectedDriveSafe,\n useUserPermissions,\n} from \"@powerhousedao/reactor-browser\";\nimport type {\n DocumentDriveDocument,\n FileNode,\n SharingType,\n} from \"@powerhousedao/shared/document-drive\";\nimport { useState } from \"react\";\nimport { addProp, entries, map, pipe } from \"remeda\";\nimport { twMerge } from \"tailwind-merge\";\nimport { fileNodeDropdownOptions } from \"../../constants/options.js\";\nimport { ConnectDropdownMenu } from \"../dropdown-menu/dropdown-menu.js\";\nimport { NodeInput } from \"../node-input/node-input.js\";\nimport { SyncStatusIcon } from \"../status-icon/sync-status-icon.js\";\n\nfunction getDriveSharingType(drive: DocumentDriveDocument): SharingType {\n if (typeof drive !== \"object\") return \"LOCAL\";\n const isReadDrive = \"readContext\" in drive;\n const { sharingType: _sharingType } = !isReadDrive\n ? drive.state.local\n : { sharingType: \"PUBLIC\" };\n const __sharingType = _sharingType?.toUpperCase();\n const validTypes: string[] = [\"LOCAL\", \"CLOUD\", \"PUBLIC\"];\n return !__sharingType ||\n __sharingType === \"PRIVATE\" ||\n !validTypes.includes(__sharingType)\n ? \"LOCAL\"\n : (__sharingType as SharingType);\n}\n\ntype Props = {\n fileNode: FileNode;\n className?: string;\n customDocumentIconSrc?: string;\n};\n\nexport function FileItem(props: Props) {\n const { fileNode, className, customDocumentIconSrc } = props;\n const [mode, setMode] = useState<\"READ\" | \"WRITE\">(\"READ\");\n const [isDropdownMenuOpen, setIsDropdownMenuOpen] = useState(false);\n const [selectedDrive] = useSelectedDriveSafe();\n const sharingType = selectedDrive\n ? getDriveSharingType(selectedDrive)\n : \"LOCAL\";\n const { isDragging, ...dragProps } = useDragNode({\n srcId: fileNode.id,\n parentId: fileNode.parentFolder ?? undefined,\n });\n const { isAllowedToCreateDocuments } = useUserPermissions();\n const { onRenameNode, onRenameDriveNodes, onDuplicateNode } =\n useNodeActions();\n const downloadDocument = useDownloadDocument(fileNode.id);\n const isReadMode = mode === \"READ\";\n const syncStatus = getSyncStatusSync(fileNode.id, sharingType);\n\n const dropdownMenuHandlers = {\n DOWNLOAD: downloadDocument,\n DUPLICATE: () => onDuplicateNode(fileNode),\n RENAME: () => setMode(\"WRITE\"),\n DELETE: () => showDeleteNodeModal(fileNode),\n } as const;\n\n const dropdownMenuOptions = pipe(\n fileNodeDropdownOptions,\n entries(),\n map(([id, option]) => addProp(option, \"id\", id)),\n );\n\n function onSubmit(name: string) {\n Promise.all([\n onRenameNode(name, fileNode),\n onRenameDriveNodes(name, fileNode.id),\n ])\n .catch((error: unknown) => {\n console.error(error);\n })\n .finally(() => {\n setMode(\"READ\");\n });\n }\n\n function onCancel() {\n setMode(\"READ\");\n }\n\n function onDropdownMenuOptionClick(itemId: string) {\n const handler =\n dropdownMenuHandlers[itemId as keyof typeof dropdownMenuHandlers];\n if (!handler) {\n console.error(`No handler found for dropdown menu item: ${itemId}`);\n return;\n }\n void handler();\n setIsDropdownMenuOpen(false);\n }\n\n const icon = customDocumentIconSrc ? (\n <img\n alt=\"file icon\"\n className=\"max-w-none\"\n height={34}\n src={customDocumentIconSrc}\n width={32}\n /* HTML img elements are draggable by default, so we\n * must disable it here so that only the container\n * can be dragged */\n draggable={false}\n />\n ) : (\n <DefaultFileIcon />\n );\n\n const iconNode = (\n <div className=\"relative\">\n {icon}\n {isReadMode && syncStatus && (\n <div className=\"absolute right-0 bottom-[-2px] size-3 rounded-full bg-gray-50 dark:bg-slate-800\">\n <div className=\"absolute top-[-2px] left-[-2px]\">\n <SyncStatusIcon\n overrideSyncIcons={{ SUCCESS: \"CheckCircleFill\" }}\n syncStatus={syncStatus}\n />\n </div>\n </div>\n )}\n </div>\n );\n\n const containerStyles = twMerge(\n \"group flex h-12 cursor-pointer items-center rounded-lg bg-gray-200 px-2 text-gray-700 select-none hover:text-gray-800 dark:bg-slate-600 dark:text-slate-100 dark:hover:text-slate-100\",\n isDragging ? \"opacity-60\" : \"\",\n className,\n );\n\n const content = isReadMode ? (\n <div className=\"flex w-52 items-center justify-between\">\n <div className=\"mr-2 truncate group-hover:mr-0\">\n <div className=\"max-h-6 truncate text-sm font-medium text-gray-700 group-hover:text-gray-800 dark:text-slate-200 dark:group-hover:text-slate-100\">\n {fileNode.name}\n </div>\n <div className=\"max-h-6 truncate text-xs font-medium text-gray-700 group-hover:text-gray-800 dark:text-slate-200 dark:group-hover:text-slate-100\">\n {fileNode.documentType}\n </div>\n </div>\n {isAllowedToCreateDocuments ? (\n <ConnectDropdownMenu\n items={dropdownMenuOptions}\n onItemClick={onDropdownMenuOptionClick}\n onOpenChange={setIsDropdownMenuOpen}\n open={isDropdownMenuOpen}\n >\n <button\n className={twMerge(\n \"hidden group-hover:block\",\n isDropdownMenuOpen && \"block\",\n )}\n onClick={(e) => {\n e.stopPropagation();\n setIsDropdownMenuOpen(true);\n }}\n >\n <Icon\n className=\"text-gray-700 dark:text-slate-200\"\n name=\"VerticalDots\"\n />\n </button>\n </ConnectDropdownMenu>\n ) : null}\n </div>\n ) : (\n <NodeInput\n className=\"ml-3 flex-1 font-medium\"\n defaultValue={fileNode.name}\n onCancel={onCancel}\n onSubmit={onSubmit}\n />\n );\n\n return (\n <div\n className=\"relative w-64\"\n onClick={isReadMode ? () => setSelectedNode(fileNode) : undefined}\n {...dragProps}\n >\n <div className={containerStyles}>\n <div className=\"flex items-center\">\n <div className=\"mr-1.5\">{iconNode}</div>\n {content}\n </div>\n </div>\n </div>\n );\n}\n\nfunction DefaultFileIcon() {\n return (\n <div className=\"text-white dark:text-slate-800\">\n <svg\n width=\"32\"\n height=\"40\"\n viewBox=\"0 0 32 40\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <g clipPath=\"url(#clip0_3725_503)\">\n <g filter=\"url(#filter0_di_3725_503)\">\n <path\n d=\"M0 6C0 2.68629 2.68629 0 6 0L24 0L32 8V34C32 37.3137 29.3137 40 26 40H6C2.68629 40 0 37.3137 0 34V6Z\"\n fill=\"#F3F5F7\"\n />\n <path\n d=\"M6 0.5H23.793L31.5 8.20703V34C31.5 37.0376 29.0376 39.5 26 39.5H6C2.96243 39.5 0.5 37.0376 0.5 34V6C0.5 2.96243 2.96243 0.5 6 0.5Z\"\n stroke=\"#FF6A55\"\n />\n </g>\n <path\n d=\"M18 12.583C18.1987 12.5831 18.3897 12.6623 18.5303 12.8027L21.8643 16.1357C22.0048 16.2762 22.0838 16.4673 22.084 16.666V25.333C22.084 25.8852 21.8639 26.415 21.4736 26.8057C21.083 27.1963 20.5524 27.4159 20 27.416H12C11.4476 27.4159 10.918 27.1963 10.5273 26.8057C10.1367 26.415 9.91699 25.8855 9.91699 25.333V14.666C9.91716 14.1137 10.1368 13.5839 10.5273 13.1934C10.9179 12.8029 11.4477 12.5831 12 12.583H18ZM12 14.083C11.8456 14.0831 11.6972 14.1448 11.5879 14.2539C11.4786 14.3631 11.4172 14.5115 11.417 14.666V25.333C11.417 25.4876 11.4786 25.6357 11.5879 25.7451C11.6972 25.8544 11.8454 25.9159 12 25.916H20C20.1546 25.9159 20.3038 25.8544 20.4131 25.7451C20.5221 25.6358 20.584 25.4874 20.584 25.333V18.084H18.666C18.1137 18.0838 17.5839 17.8642 17.1934 17.4736C16.8028 17.0831 16.5832 16.5533 16.583 16.001V14.083H12ZM16.8643 19.748C17.1877 19.4893 17.6602 19.5418 17.9189 19.8652L19.252 21.5322C19.471 21.8061 19.4709 22.1949 19.252 22.4688L17.9189 24.1357C17.6601 24.4589 17.1876 24.5116 16.8643 24.2529C16.5412 23.9943 16.489 23.5226 16.7471 23.1992L17.7061 22L16.7471 20.8027C16.4884 20.4794 16.5411 20.0069 16.8643 19.748ZM14.0811 19.8652C14.3398 19.5421 14.8114 19.4896 15.1348 19.748C15.4582 20.0068 15.5107 20.4793 15.252 20.8027L14.293 22L15.252 23.1992C15.5105 23.5227 15.4581 23.9942 15.1348 24.2529C14.8114 24.5113 14.3397 24.4589 14.0811 24.1357L12.7471 22.4688C12.5284 22.195 12.5284 21.806 12.7471 21.5322L14.0811 19.8652ZM18.083 16.001C18.0832 16.1555 18.1447 16.3038 18.2539 16.4131C18.3632 16.5223 18.5115 16.5838 18.666 16.584H20.1914L18.083 14.4756V16.001Z\"\n fill=\"#FF6A55\"\n />\n <path d=\"M23 0L32 9H27C24.7909 9 23 7.20914 23 5V0Z\" fill=\"#FF6A55\" />\n </g>\n <defs>\n <filter\n id=\"filter0_di_3725_503\"\n x=\"-4\"\n y=\"-1\"\n width=\"40\"\n height=\"49\"\n filterUnits=\"userSpaceOnUse\"\n colorInterpolationFilters=\"sRGB\"\n >\n <feFlood floodOpacity=\"0\" result=\"BackgroundImageFix\" />\n <feColorMatrix\n in=\"SourceAlpha\"\n type=\"matrix\"\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\"\n result=\"hardAlpha\"\n />\n <feMorphology\n radius=\"4\"\n operator=\"erode\"\n in=\"SourceAlpha\"\n result=\"effect1_dropShadow_3725_503\"\n />\n <feOffset dy=\"4\" />\n <feGaussianBlur stdDeviation=\"4\" />\n <feColorMatrix\n type=\"matrix\"\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.02 0\"\n />\n <feBlend\n mode=\"multiply\"\n in2=\"BackgroundImageFix\"\n result=\"effect1_dropShadow_3725_503\"\n />\n <feBlend\n mode=\"normal\"\n in=\"SourceGraphic\"\n in2=\"effect1_dropShadow_3725_503\"\n result=\"shape\"\n />\n <feColorMatrix\n in=\"SourceAlpha\"\n type=\"matrix\"\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\"\n result=\"hardAlpha\"\n />\n <feOffset dy=\"-1\" />\n <feGaussianBlur stdDeviation=\"0.5\" />\n <feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\" />\n <feColorMatrix\n type=\"matrix\"\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.04 0\"\n />\n <feBlend\n mode=\"multiply\"\n in2=\"shape\"\n result=\"effect2_innerShadow_3725_503\"\n />\n </filter>\n <clipPath id=\"clip0_3725_503\">\n <rect width=\"32\" height=\"40\" fill=\"currentColor\" />\n </clipPath>\n </defs>\n </svg>\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport {\n setSelectedNode,\n showDeleteNodeModal,\n useDragNode,\n useDropNode,\n useNodeActions,\n useUserPermissions,\n} from \"@powerhousedao/reactor-browser\";\nimport type { FolderNode } from \"@powerhousedao/shared/document-drive\";\nimport { useState } from \"react\";\nimport { addProp, entries, map, pipe } from \"remeda\";\nimport { twMerge } from \"tailwind-merge\";\nimport { folderNodeDropdownOptions } from \"../../constants/options.js\";\nimport { ConnectDropdownMenu } from \"../dropdown-menu/dropdown-menu.js\";\nimport { NodeInput } from \"../node-input/node-input.js\";\n\nexport function FolderItem(props: {\n folderNode: FolderNode;\n className?: string;\n}) {\n const { folderNode, className } = props;\n const { isAllowedToCreateDocuments } = useUserPermissions();\n const [mode, setMode] = useState<\"READ\" | \"WRITE\">(\"READ\");\n const [isDropdownMenuOpen, setIsDropdownMenuOpen] = useState(false);\n const { isDragging, ...dragProps } = useDragNode({\n srcId: folderNode.id,\n parentId: folderNode.parentFolder,\n });\n const { isDropTarget, ...dropProps } = useDropNode(folderNode.id);\n const { onRenameNode, onRenameDriveNodes, onDuplicateNode } =\n useNodeActions();\n const isReadMode = mode === \"READ\";\n function onCancel() {\n setMode(\"READ\");\n }\n\n function onSubmit(name: string) {\n Promise.all([\n onRenameNode(name, folderNode),\n onRenameDriveNodes(name, folderNode.id),\n ])\n .catch((error: unknown) => {\n console.error(error);\n })\n .finally(() => {\n setMode(\"READ\");\n });\n }\n\n const dropdownMenuHandlers = {\n DUPLICATE: () => onDuplicateNode(folderNode),\n RENAME: () => setMode(\"WRITE\"),\n DELETE: () => showDeleteNodeModal(folderNode),\n } as const;\n\n const dropdownMenuOptions = pipe(\n folderNodeDropdownOptions,\n entries(),\n map(([id, option]) => addProp(option, \"id\", id)),\n );\n\n function onDropdownMenuOptionClick(\n itemId: keyof typeof dropdownMenuHandlers,\n ) {\n const handler = dropdownMenuHandlers[itemId];\n if (!handler) {\n console.error(`No handler found for dropdown menu item: ${itemId}`);\n return;\n }\n void handler();\n setIsDropdownMenuOpen(false);\n }\n\n const content =\n isReadMode || !isAllowedToCreateDocuments ? (\n <div className=\"ml-3 max-h-6 truncate font-medium text-gray-700 group-hover:text-gray-800 dark:text-slate-200 dark:group-hover:text-slate-100\">\n {folderNode.name}\n </div>\n ) : (\n <NodeInput\n className=\"ml-3 font-medium\"\n defaultValue={folderNode.name}\n onCancel={onCancel}\n onSubmit={onSubmit}\n />\n );\n\n const containerStyles = twMerge(\n \"group flex h-12 cursor-pointer items-center rounded-lg bg-gray-200 px-2 select-none dark:bg-slate-600 dark:text-slate-100\",\n isDragging\n ? \"opacity-60\"\n : isDropTarget\n ? \"bg-blue-100 dark:bg-blue-800\"\n : \"\",\n className,\n );\n\n return (\n <div\n className=\"relative w-64\"\n onClick={isReadMode ? () => setSelectedNode(folderNode) : undefined}\n >\n <div {...dragProps} {...dropProps} className={containerStyles}>\n <div className=\"flex items-center overflow-hidden\">\n <div className=\"p-1\">\n <div className=\"relative text-gray-700 dark:text-slate-200\">\n <Icon name=\"FolderClose\" size={24} />\n </div>\n </div>\n {content}\n </div>\n {isReadMode && isAllowedToCreateDocuments ? (\n <ConnectDropdownMenu\n items={dropdownMenuOptions}\n onItemClick={onDropdownMenuOptionClick}\n onOpenChange={setIsDropdownMenuOpen}\n open={isDropdownMenuOpen}\n >\n <button\n className={twMerge(\n \"ml-auto hidden group-hover:block\",\n isDropdownMenuOpen && \"block\",\n )}\n onClick={(e) => {\n e.stopPropagation();\n setIsDropdownMenuOpen(true);\n }}\n >\n <Icon\n className=\"text-gray-700 dark:text-slate-200\"\n name=\"VerticalDots\"\n />\n </button>\n </ConnectDropdownMenu>\n ) : null}\n </div>\n </div>\n );\n}\n","import { twMerge } from \"tailwind-merge\";\n\ntype FooterLinkProps<E extends React.ElementType> = {\n readonly as?: E;\n} & React.ComponentPropsWithRef<E>;\n\nexport function FooterLink<E extends React.ElementType = \"a\">(\n props: FooterLinkProps<E>,\n) {\n const { as: Component = \"a\", className, ...restProps } = props;\n\n return (\n <Component\n className={twMerge(\n \"flex cursor-pointer items-center hover:underline\",\n typeof className === \"string\" && className,\n )}\n {...restProps}\n />\n );\n}\n","import { twMerge } from \"tailwind-merge\";\n\nexport const Footer: React.FC<React.HTMLAttributes<HTMLElement>> = ({\n children,\n className,\n ...props\n}) => {\n return (\n <footer\n className={twMerge(\n \"flex items-center gap-x-6 text-xs font-medium text-gray-300 dark:text-slate-600\",\n typeof className === \"string\" && className,\n )}\n {...props}\n >\n {children}\n </footer>\n );\n};\n","import type { ComponentPropsWithRef, ForwardedRef } from \"react\";\nimport { forwardRef } from \"react\";\nimport { twJoin, twMerge } from \"tailwind-merge\";\n\ntype InputProps = ComponentPropsWithRef<\"input\">;\ntype FormInputProps = Omit<InputProps, \"className\"> & {\n readonly icon?: React.JSX.Element;\n readonly errorMessage?: string;\n readonly isTouched?: boolean;\n readonly isDirty?: boolean;\n readonly type?: \"text\" | \"password\" | \"email\" | \"url\";\n readonly inputClassName?: string;\n readonly containerClassName?: string;\n readonly errorMessageClassName?: string;\n readonly hideErrors?: boolean;\n};\nexport const FormInput = forwardRef(function FormInput(\n props: FormInputProps,\n ref: ForwardedRef<HTMLInputElement>,\n) {\n const {\n icon,\n errorMessage,\n isDirty,\n containerClassName,\n inputClassName,\n errorMessageClassName,\n hideErrors = false,\n ...delegatedProps\n } = props;\n const type = props.type ?? \"text\";\n const isError = !!errorMessage;\n return (\n <div>\n <div\n className={twMerge(\n \"mb-1 flex gap-2 rounded-md border border-gray-200 bg-gray-50 p-3 text-gray-900 placeholder:text-gray-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:placeholder:text-slate-900\",\n isError && \"border-red-900 dark:border-red-50\",\n containerClassName,\n )}\n >\n {icon && (\n <span\n className={twJoin(\n (!isDirty || isError) && \"text-gray-200 dark:text-slate-200\",\n )}\n >\n {icon}\n </span>\n )}\n\n <input\n {...delegatedProps}\n className={twMerge(\n \"w-full bg-transparent font-semibold outline-none\",\n inputClassName,\n )}\n ref={ref}\n type={type}\n />\n </div>\n <p\n className={twMerge(\n \"hidden min-h-4 text-xs text-red-900 dark:text-red-400\",\n isError && \"block\",\n hideErrors && \"hidden\",\n errorMessageClassName,\n )}\n >\n {errorMessage}\n </p>\n </div>\n );\n});\n","import { Icon, type AppOptions } from \"#design-system\";\nimport type { ComponentPropsWithRef } from \"react\";\nimport type { Control, Path } from \"react-hook-form\";\nimport { Controller } from \"react-hook-form\";\nimport type { ConnectSelectItem } from \"../../select/select.js\";\nimport { ConnectSelect } from \"../../select/select.js\";\n\nexport function appToInputOption(app: AppOptions): ConnectSelectItem<string> {\n return {\n value: app.id,\n displayValue: app.name,\n icon: <Icon name=\"PowerhouseLogoSmall\" />,\n description: \"Built by Powerhouse\",\n };\n}\ntype AppFormInputProps<T extends AppOptions> = Omit<\n ComponentPropsWithRef<typeof ConnectSelect>,\n \"id\" | \"items\" | \"value\" | \"onChange\"\n> & {\n readonly control: Control<T>;\n readonly appOptions: T[];\n};\n\nexport function AppFormInput<T extends AppOptions>(\n props: AppFormInputProps<T>,\n) {\n const { control, appOptions, ...delegatedProps } = props;\n const items = appOptions.map(appToInputOption);\n\n return (\n <Controller\n control={control}\n name={\"id\" as Path<T>}\n render={({ field }) => (\n <ConnectSelect {...delegatedProps} {...field} id=\"id\" items={items} />\n )}\n />\n );\n}\n","import type { ComponentPropsWithRef, ForwardedRef } from \"react\";\nimport { forwardRef } from \"react\";\n\ntype ToggleProps = Omit<ComponentPropsWithRef<\"input\">, \"type\">;\n\nexport const Toggle = forwardRef(function Toggle(\n props: ToggleProps,\n ref: ForwardedRef<HTMLInputElement>,\n) {\n return (\n <label className=\"relative cursor-pointer items-center\" htmlFor={props.id}>\n <input\n className=\"peer sr-only\"\n ref={ref}\n type=\"checkbox\"\n value=\"\"\n {...props}\n />\n <div className=\"peer h-6 w-11 rounded-full bg-gray-500 peer-checked:bg-blue-900 peer-focus:outline-none after:absolute after:inset-s-0.5 after:top-0.5 after:size-5 after:rounded-full after:border after:border-none after:bg-gray-50 after:transition-all peer-checked:after:translate-x-full dark:bg-slate-400 dark:after:bg-slate-800\" />\n </label>\n );\n});\n","import type { ComponentPropsWithRef, ForwardedRef } from \"react\";\nimport { forwardRef } from \"react\";\nimport { Toggle } from \"../../toggle/toggle.js\";\n\ntype AvailableOfflineToggleProps = Omit<\n ComponentPropsWithRef<typeof Toggle>,\n \"id\"\n>;\n\nexport const AvailableOfflineToggle = forwardRef(\n function AvailableOfflineToggle(\n props: AvailableOfflineToggleProps,\n ref: ForwardedRef<HTMLInputElement>,\n ) {\n return (\n <div className=\"flex items-center rounded-md border border-gray-200 bg-gray-50 p-3 text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <div className=\"flex-1\">\n <label\n className=\"font-medium text-gray-900 dark:text-slate-50\"\n htmlFor=\"availableOffline\"\n >\n Make available offline\n </label>\n <p className=\"text-xs text-gray-700 dark:text-slate-200\">\n Check this options if you keep a local backup\n <br />\n available at all times.\n </p>\n </div>\n <Toggle id=\"availableOffline\" ref={ref} {...props} />\n </div>\n );\n },\n);\n","import type { ComponentPropsWithoutRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\ntype LabelProps = ComponentPropsWithoutRef<\"label\">;\n\nexport function Label(props: LabelProps) {\n const { children, className, ...labelProps } = props;\n return (\n <label\n {...labelProps}\n className={twMerge(\n \"block font-semibold text-gray-500 dark:text-slate-400\",\n className,\n )}\n >\n {children}\n </label>\n );\n}\n","import type { SharingType } from \"@powerhousedao/shared/document-drive\";\nimport type { ComponentPropsWithRef } from \"react\";\nimport type { Control, Path } from \"react-hook-form\";\nimport { Controller } from \"react-hook-form\";\nimport { ConnectSelect } from \"../../select/select.js\";\nimport { sharingTypeOptions } from \"../../../constants/options.js\";\n\ntype SharingTypeFormInputProps<T extends { sharingType: SharingType }> = Omit<\n ComponentPropsWithRef<typeof ConnectSelect>,\n \"id\" | \"items\" | \"value\" | \"onChange\"\n> & {\n readonly control: Control<T>;\n};\nexport function SharingTypeFormInput<T extends { sharingType: SharingType }>(\n props: SharingTypeFormInputProps<T>,\n) {\n const { control, ...delegatedProps } = props;\n\n return (\n <Controller\n control={control}\n name={\"sharingType\" as Path<T>}\n render={({ field }) => (\n <ConnectSelect\n {...delegatedProps}\n {...field}\n id=\"sharingType\"\n items={sharingTypeOptions}\n />\n )}\n />\n );\n}\n","import { PowerhouseButton, type AppOptions } from \"#design-system\";\nimport type { SubmitHandler } from \"react-hook-form\";\nimport { useForm } from \"react-hook-form\";\nimport { FormInput } from \"../form-input/form-input.js\";\nimport { AppFormInput } from \"./inputs/app-form-input.js\";\nimport { AvailableOfflineToggle } from \"./inputs/available-offline-toggle.js\";\nimport { Label } from \"./inputs/label.js\";\nimport { SharingTypeFormInput } from \"./inputs/sharing-type-form-input.js\";\n\ntype AddLocalDriveFormProps = {\n readonly onSubmit: CreateDriveFormSubmitHandler;\n readonly onCancel: () => void;\n readonly appOptions: AppOptions[];\n};\n\ntype CreateDriveFormSubmitHandler = SubmitHandler<AppOptions>;\n\nexport function AddLocalDriveForm(props: AddLocalDriveFormProps) {\n const {\n register,\n handleSubmit,\n control,\n formState: { errors },\n } = useForm<AppOptions>({\n defaultValues: {\n name: \"\",\n sharingType: \"LOCAL\",\n availableOffline: false,\n id: props.appOptions[0].id,\n },\n });\n\n return (\n <form\n name=\"add-local-drive\"\n onSubmit={(e) => void handleSubmit(props.onSubmit)(e)}\n className=\"flex flex-col gap-4\"\n >\n <div className=\"flex flex-col gap-4\">\n <div>\n <Label\n htmlFor=\"name\"\n className=\"text-sm font-medium text-gray-900 dark:text-slate-100\"\n >\n Drive Name\n </Label>\n <FormInput\n {...register(\"name\", {\n required: \"Drive name is required\",\n })}\n errorMessage={errors.name?.message}\n placeholder=\"Drive name\"\n />\n </div>\n <div>\n <Label\n htmlFor=\"driveApp\"\n className=\"text-sm font-medium text-gray-900 dark:text-slate-100\"\n >\n Drive App\n </Label>\n <AppFormInput control={control} appOptions={props.appOptions} />\n </div>\n <div>\n <Label\n htmlFor=\"sharingType\"\n className=\"text-sm font-medium text-gray-900 dark:text-slate-100\"\n >\n Location\n </Label>\n <SharingTypeFormInput control={control} />\n </div>\n <div>\n <AvailableOfflineToggle {...register(\"availableOffline\")} />\n </div>\n <PowerhouseButton className=\"mt-2 w-full\" type=\"submit\">\n Create new drive\n </PowerhouseButton>\n </div>\n </form>\n );\n}\n","import { Icon } from \"#design-system\";\n\ntype DriveNameProps = {\n readonly driveName: string;\n};\nexport function DriveName(props: DriveNameProps) {\n return (\n <div className=\"flex gap-2 rounded-xl bg-gray-100 p-3 font-semibold text-gray-500 dark:bg-slate-700 dark:text-slate-400\">\n <Icon className=\"text-gray-700 dark:text-slate-200\" name=\"Drive\" />\n {props.driveName}\n </div>\n );\n}\n","import type { DivProps, DriveLocation } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\nimport { locationInfoByLocation } from \"../../../constants/options.js\";\ntype LocationInfoProps = DivProps & {\n readonly location: DriveLocation;\n};\n\nexport function LocationInfo(props: LocationInfoProps) {\n const { location, className, ...divProps } = props;\n\n const locationInfo = locationInfoByLocation[location];\n return (\n <div\n {...divProps}\n className={twMerge(\n \"my-3 flex items-center gap-2 rounded-xl border border-gray-100 bg-gray-50 p-3 text-gray-900 shadow-sm dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n className,\n )}\n >\n {locationInfo.icon}\n <div>\n <p>{locationInfo.title}</p>\n <p className=\"text-xs text-gray-200 dark:text-slate-700\">\n {locationInfo.description}\n </p>\n </div>\n </div>\n );\n}\n","import { PowerhouseButton } from \"#design-system\";\nimport type { SharingType } from \"@powerhousedao/shared/document-drive\";\nimport { useEffect, useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { useDebounceValue } from \"usehooks-ts\";\nimport { Disclosure } from \"../disclosure/disclosure.js\";\nimport { Divider } from \"../divider/divider.js\";\nimport { FormInput } from \"../form-input/form-input.js\";\nimport { AvailableOfflineToggle } from \"./inputs/available-offline-toggle.js\";\nimport { DriveName } from \"./inputs/drive-name.js\";\nimport { LocationInfo } from \"./inputs/location-info.js\";\n\ntype RemoteDriveDetails = {\n id: string;\n name: string;\n sharingType: SharingType;\n location: \"SWITCHBOARD\";\n availableOffline: boolean;\n};\n\ntype Inputs = {\n availableOffline: boolean;\n};\n\nexport type AddRemoteDriveInput = RemoteDriveDetails & { url: string };\n\nexport type AddPublicDriveFormProps = {\n readonly sharingType: SharingType;\n readonly onSubmit: (data: AddRemoteDriveInput) => void;\n readonly onCancel: () => void;\n readonly requestPublicDrive: (\n url: string,\n ) => Promise<{ id: string; name: string }>;\n};\n\nexport function AddRemoteDriveForm(props: AddPublicDriveFormProps) {\n const { sharingType = \"PUBLIC\", requestPublicDrive } = props;\n const [remoteDriveDetails, setPublicDriveDetails] =\n useState<RemoteDriveDetails>();\n const [showLocationSettings, setShowLocationSettings] = useState(false);\n const [isUrlValid, setIsUrlValid] = useState(true);\n const [hasConfirmedUrl, setHasConfirmedUrl] = useState(false);\n const [errorMessage, setErrorMessage] = useState(\"\");\n const [url, setUrl] = useState(\"\");\n const [debouncedUrl, setDebouncedUrl] = useDebounceValue(url, 500);\n\n const { register, handleSubmit, setValue } = useForm<Inputs>({\n mode: \"onBlur\",\n defaultValues: {\n availableOffline: remoteDriveDetails?.availableOffline ?? false,\n },\n });\n\n useEffect(() => {\n setDebouncedUrl(url);\n }, [url]);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setHasConfirmedUrl(false);\n if (debouncedUrl === \"\") return;\n fetchPublicDrive().catch(console.error);\n\n async function fetchPublicDrive() {\n try {\n const { id, name } = await requestPublicDrive(debouncedUrl);\n setPublicDriveDetails({\n id,\n name,\n sharingType,\n location: \"SWITCHBOARD\",\n availableOffline: true,\n });\n setValue(\"availableOffline\", true);\n setIsUrlValid(true);\n setErrorMessage(\"\");\n } catch (error) {\n setPublicDriveDetails(undefined);\n setIsUrlValid(false);\n setErrorMessage((error as Error).message);\n }\n }\n }, [debouncedUrl, setValue, sharingType]);\n\n function onSubmit({ availableOffline }: Inputs) {\n if (!remoteDriveDetails) return;\n props.onSubmit({\n ...remoteDriveDetails,\n availableOffline,\n url: debouncedUrl,\n });\n }\n\n return (\n <form onSubmit={(e) => void handleSubmit(onSubmit)(e)}>\n {hasConfirmedUrl ? (\n <>\n <DriveName driveName={remoteDriveDetails?.name ?? \"New drive\"} />\n <Divider className=\"my-3\" />\n <Disclosure\n isOpen={showLocationSettings}\n onOpenChange={() => setShowLocationSettings(!showLocationSettings)}\n title=\"Location\"\n >\n <LocationInfo location=\"SWITCHBOARD\" />\n <AvailableOfflineToggle {...register(\"availableOffline\")} />\n </Disclosure>\n <PowerhouseButton className=\"mt-4 w-full\" color=\"dark\" type=\"submit\">\n Add new drive\n </PowerhouseButton>\n </>\n ) : (\n <>\n <FormInput\n errorMessage={errorMessage}\n onChange={(e) => setUrl(e.target.value)}\n placeholder=\"Drive URL\"\n required\n type=\"url\"\n value={url}\n />\n <PowerhouseButton\n className=\"mt-4 w-full py-2 text-base\"\n color=\"dark\"\n size=\"small\"\n disabled={!isUrlValid || url === \"\"}\n onClick={(e) => {\n e.preventDefault();\n setHasConfirmedUrl(true);\n }}\n type=\"button\"\n >\n Add drive\n </PowerhouseButton>\n </>\n )}\n </form>\n );\n}\n","import { useTheme } from \"@powerhousedao/reactor-browser\";\nimport { JsonView, type JsonViewProps } from \"@uiw/react-json-view\";\nimport { darkTheme } from \"@uiw/react-json-view/dark\";\nimport { lightTheme } from \"@uiw/react-json-view/light\";\nimport { isStrictEqual, isString } from \"remeda\";\nimport { Icon } from \"../../powerhouse/index.js\";\n\n/* Shows arbitrary JSON content in a nicely formatted viewer.\n * Takes all the same props as the JSON view React component.\n * Provides some quality of life improvements:\n *\n * allows expand and collapse of any / all of the rendered fields\n * Allows copy-paste of the whole object as well as individual fields, with a success indicator\n * Formats very long text fields so that they are first truncated, and then if expanded word wrap applies\n */\nexport function FormattedJsonViewer(props: JsonViewProps<object>) {\n const { theme } = useTheme();\n const style = theme === \"light\" ? lightTheme : darkTheme;\n return (\n <JsonView\n displayDataTypes={false}\n displayObjectSize={false}\n style={style}\n {...props}\n >\n <JsonView.Copied\n render={({ onClick, ...props }) => {\n if ((props as { \"data-copied\": boolean })[\"data-copied\"]) {\n return (\n <Icon\n {...props}\n className=\"inline-block text-green-800 dark:text-green-100\"\n name=\"FilesEarmark\"\n size={16}\n />\n );\n }\n return (\n <Icon\n {...props}\n onClick={onClick}\n className=\"inline-block cursor-pointer text-gray-700 dark:text-slate-200\"\n name=\"FilesEarmark\"\n size={16}\n />\n );\n }}\n />\n <JsonView.String\n render={({ children, ...rest }, { value, keyName }) => {\n // strings are truncated with ellipsis at 30 chars in this component by default\n const maxLength = 30;\n if (\n // if the children are a plain string, we know this is a text node\n isString(children) &&\n // the value should therefore also be a string\n isString(value) &&\n // when the content is truncated, the children will be the truncated content\n // and the value will be the original content\n // we know that the content is not truncated if the value and the children are the same\n isStrictEqual(children, value) &&\n // if the string is long then apply word wrap to avoid letting the parent component put everything\n // on one line\n value.length > maxLength\n ) {\n return (\n /* use inline grid so that this text is still aligned with the field name */\n <span {...rest} className=\"inline-grid\">\n <span\n // We must wrap anywhere because data can be of any length\n // do not use hyphens, show the raw content\n // apply one character of left padding and negative indent because of the string quotation mark\n className=\"pl-[1ch] indent-[-1ch] wrap-anywhere hyphens-none\"\n style={{\n // calculate the line width from the width of the key in the json\n maxWidth: `${60 - keyName.toString().length}ch`,\n }}\n >\n \"{children}\"\n </span>\n </span>\n );\n }\n return <span {...rest}>\"{children}\"</span>;\n }}\n />\n </JsonView>\n );\n}\n","type HomeBackgroundImageProps = {\n src?: string;\n};\n\nexport const HomeBackgroundImage = ({ src }: HomeBackgroundImageProps = {}) => {\n if (src) {\n return (\n <picture className=\"pointer-events-none absolute inset-8 z-0 size-[calc(100%-32px)] object-contain\">\n <img src={src} alt=\"background\" className=\"object-contain\" />\n </picture>\n );\n }\n\n return (\n <div className=\"pointer-events-none fixed top-0 z-0 size-full bg-gray-50 dark:bg-slate-800\">\n <svg\n width=\"1858\"\n height=\"1256\"\n viewBox=\"0 0 1858 1256\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <g clipPath=\"url(#clip0_4090_11134)\">\n <ellipse\n opacity=\"0.3\"\n cx=\"478.092\"\n cy=\"523.885\"\n rx=\"983.498\"\n ry=\"480.668\"\n transform=\"rotate(36.3289 478.092 523.885)\"\n fill=\"url(#paint0_radial_4090_11134)\"\n fillOpacity=\"0.3\"\n />\n <g opacity=\"0.3\">\n <ellipse\n cx=\"1385.68\"\n cy=\"503.347\"\n rx=\"759.956\"\n ry=\"331.584\"\n transform=\"rotate(36.3289 1385.68 503.347)\"\n fill=\"url(#paint1_radial_4090_11134)\"\n fillOpacity=\"0.2\"\n style={{ mixBlendMode: \"screen\" }}\n />\n </g>\n </g>\n <defs>\n <radialGradient\n id=\"paint0_radial_4090_11134\"\n cx=\"0\"\n cy=\"0\"\n r=\"1\"\n gradientUnits=\"userSpaceOnUse\"\n gradientTransform=\"translate(500.331 508.304) rotate(89.0086) scale(508.666 1077.08)\"\n >\n <stop stopColor=\"white\" stopOpacity=\"0\" />\n <stop stopColor=\"#FF3FAC\" />\n <stop offset=\"0.363434\" stopColor=\"#9D25FC\" stopOpacity=\"0.41\" />\n <stop offset=\"0.745192\" stopColor=\"#141718\" stopOpacity=\"0\" />\n </radialGradient>\n <radialGradient\n id=\"paint1_radial_4090_11134\"\n cx=\"0\"\n cy=\"0\"\n r=\"1\"\n gradientUnits=\"userSpaceOnUse\"\n gradientTransform=\"translate(1385.68 503.347) rotate(90) scale(331.584 759.956)\"\n >\n <stop stopColor=\"#0084FF\" />\n <stop offset=\"0.802885\" stopColor=\"#141718\" stopOpacity=\"0\" />\n </radialGradient>\n <clipPath id=\"clip0_4090_11134\">\n <rect width=\"1858\" height=\"1256\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n </div>\n );\n};\n","import { Icon } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\n\ntype HomeScreenItemProps = {\n readonly icon?: React.JSX.Element;\n readonly title: string;\n readonly description?: string;\n readonly containerClassName?: string;\n readonly shareable?: boolean;\n readonly onClick?: (event: React.MouseEvent<HTMLDivElement>) => void;\n};\nexport const HomeScreenItem = function HomeScreenItem(\n props: HomeScreenItemProps,\n) {\n const { icon, title, description, containerClassName, shareable, onClick } =\n props;\n return (\n <div\n className={twMerge(\n \"hover-bg-transparent relative flex h-24 w-40 cursor-pointer flex-col items-center justify-center overflow-hidden rounded-md p-2 text-center text-sm text-gray-900 dark:text-slate-50\",\n containerClassName,\n onClick && \"cursor-pointer\",\n )}\n onClick={onClick}\n >\n <div className=\"mx-auto pb-2\">\n {icon || (\n <div className=\"size-8 items-center justify-center rounded-lg bg-gray-900 pt-1 dark:bg-slate-50\">\n <span className=\"w-6 text-white dark:text-slate-900\">\n {title.slice(0, 1).toUpperCase()}\n </span>\n </div>\n )}\n </div>\n <div className=\"w-full max-w-full\">\n <h3 className=\"w-full max-w-full truncate px-2 text-gray-900 dark:text-slate-50\">\n {title}\n </h3>\n {description && (\n <p className=\"text-gray-500 dark:text-slate-400\">{description}</p>\n )}\n </div>\n {shareable && (\n <div className=\"absolute top-0 left-2 mb-2\">\n <Icon name=\"PeopleFill\" width={12} height={12} />\n </div>\n )}\n </div>\n );\n};\n","import { Icon } from \"#design-system\";\nimport { showPHModal } from \"@powerhousedao/reactor-browser\";\nimport { HomeScreenItem } from \"./home-screen-item.js\";\ntype HomeScreenAddDriveItemProps = {\n readonly containerClassName?: string;\n};\nexport const HomeScreenAddDriveItem = function HomeScreenAddDriveItem(\n props: HomeScreenAddDriveItemProps,\n) {\n const { containerClassName } = props;\n return (\n <HomeScreenItem\n title=\"Create New Drive\"\n icon={<Icon name=\"PlusSquare\" size={32} />}\n onClick={() => showPHModal({ type: \"addDrive\" })}\n containerClassName={containerClassName}\n />\n );\n};\n","import { twMerge } from \"tailwind-merge\";\nimport { HomeBackgroundImage } from \"./home-background-image.js\";\n\ntype HomeScreenProps = {\n readonly children: React.ReactNode;\n readonly containerClassName?: string;\n readonly homeBackground?: string | null;\n};\n\nexport const HomeScreen = function HomeScreen(props: HomeScreenProps) {\n const { children, containerClassName, homeBackground } = props;\n return (\n <div\n className={twMerge(\n \"relative container mx-auto flex h-full flex-col\",\n containerClassName,\n )}\n >\n <div className=\"m-8 flex flex-wrap justify-center gap-4 bg-gray-50 pt-12 dark:bg-slate-800\">\n <HomeBackgroundImage src={homeBackground ?? undefined} />\n {children}\n </div>\n </div>\n );\n};\n","import { Icon } from \"#design-system\";\nimport { useCallback, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\nimport type {\n RebuildResult,\n ValidationResult,\n} from \"@powerhousedao/reactor-browser\";\n\nexport type IntegrityInspectorProps = {\n readonly onValidate: (\n documentId: string,\n branch?: string,\n ) => Promise<ValidationResult>;\n readonly onRebuildKeyframes: (\n documentId: string,\n branch?: string,\n ) => Promise<RebuildResult>;\n readonly onRebuildSnapshots: (\n documentId: string,\n branch?: string,\n ) => Promise<RebuildResult>;\n};\n\ntype ActionStatus = \"idle\" | \"running\" | \"done\" | \"error\";\ntype ConfirmAction = \"keyframes\" | \"snapshots\" | null;\n\nexport function IntegrityInspector({\n onValidate,\n onRebuildKeyframes,\n onRebuildSnapshots,\n}: IntegrityInspectorProps) {\n const [documentId, setDocumentId] = useState(\"\");\n const [branch, setBranch] = useState(\"\");\n const [status, setStatus] = useState<ActionStatus>(\"idle\");\n const [validationResult, setValidationResult] =\n useState<ValidationResult | null>(null);\n const [rebuildResult, setRebuildResult] = useState<RebuildResult | null>(\n null,\n );\n const [error, setError] = useState<string | null>(null);\n const [confirmAction, setConfirmAction] = useState<ConfirmAction>(null);\n\n const clearResults = useCallback(() => {\n setValidationResult(null);\n setRebuildResult(null);\n setError(null);\n setConfirmAction(null);\n }, []);\n\n const handleValidate = useCallback(async () => {\n if (!documentId.trim()) return;\n clearResults();\n setStatus(\"running\");\n try {\n const result = await onValidate(\n documentId.trim(),\n branch.trim() || undefined,\n );\n setValidationResult(result);\n setStatus(\"done\");\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n setStatus(\"error\");\n }\n }, [documentId, branch, onValidate, clearResults]);\n\n const handleRebuildKeyframes = useCallback(async () => {\n if (!documentId.trim()) return;\n clearResults();\n setStatus(\"running\");\n try {\n const result = await onRebuildKeyframes(\n documentId.trim(),\n branch.trim() || undefined,\n );\n setRebuildResult(result);\n setStatus(\"done\");\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n setStatus(\"error\");\n }\n }, [documentId, branch, onRebuildKeyframes, clearResults]);\n\n const handleRebuildSnapshots = useCallback(async () => {\n if (!documentId.trim()) return;\n clearResults();\n setStatus(\"running\");\n try {\n const result = await onRebuildSnapshots(\n documentId.trim(),\n branch.trim() || undefined,\n );\n setRebuildResult(result);\n setStatus(\"done\");\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n setStatus(\"error\");\n }\n }, [documentId, branch, onRebuildSnapshots, clearResults]);\n\n return (\n <div className=\"flex h-full flex-col gap-3\">\n <div className=\"flex shrink-0 items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-gray-900 dark:text-slate-50\">\n Integrity Inspector\n </h2>\n </div>\n\n <div className=\"flex shrink-0 items-end gap-3\">\n <div className=\"flex flex-1 flex-col gap-1\">\n <label className=\"text-xs font-medium text-gray-700 dark:text-slate-200\">\n Document ID\n </label>\n <input\n className=\"rounded-sm border border-gray-300 px-3 py-1.5 text-sm outline-none focus:border-blue-400 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:focus:border-blue-500\"\n onChange={(e) => setDocumentId(e.target.value)}\n placeholder=\"Enter document ID\"\n type=\"text\"\n value={documentId}\n />\n </div>\n <div className=\"flex w-40 flex-col gap-1\">\n <label className=\"text-xs font-medium text-gray-700 dark:text-slate-200\">\n Branch (optional)\n </label>\n <input\n className=\"rounded-sm border border-gray-300 px-3 py-1.5 text-sm outline-none focus:border-blue-400 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:focus:border-blue-500\"\n onChange={(e) => setBranch(e.target.value)}\n placeholder=\"main\"\n type=\"text\"\n value={branch}\n />\n </div>\n <div className=\"flex gap-2\">\n <button\n className=\"flex items-center gap-1 rounded-sm border border-blue-300 bg-blue-50 px-3 py-1.5 text-sm text-blue-700 hover:bg-blue-100 disabled:opacity-50 dark:border-blue-600 dark:bg-blue-900 dark:text-blue-100 dark:hover:bg-blue-800\"\n disabled={\n !documentId.trim() ||\n status === \"running\" ||\n confirmAction !== null\n }\n onClick={() => void handleValidate()}\n type=\"button\"\n >\n <Icon name=\"Checkmark\" size={14} />\n Validate\n </button>\n <button\n className=\"flex items-center gap-1 rounded-sm border border-yellow-300 bg-yellow-50 px-3 py-1.5 text-sm text-yellow-700 hover:bg-yellow-100 disabled:opacity-50 dark:border-yellow-600 dark:bg-yellow-900 dark:text-yellow-100 dark:hover:bg-yellow-800\"\n disabled={\n !documentId.trim() ||\n status === \"running\" ||\n confirmAction !== null\n }\n onClick={() => setConfirmAction(\"keyframes\")}\n type=\"button\"\n >\n <Icon name=\"Reload\" size={14} />\n Rebuild Keyframes\n </button>\n <button\n className=\"flex items-center gap-1 rounded-sm border border-yellow-300 bg-yellow-50 px-3 py-1.5 text-sm text-yellow-700 hover:bg-yellow-100 disabled:opacity-50 dark:border-yellow-600 dark:bg-yellow-900 dark:text-yellow-100 dark:hover:bg-yellow-800\"\n disabled={\n !documentId.trim() ||\n status === \"running\" ||\n confirmAction !== null\n }\n onClick={() => setConfirmAction(\"snapshots\")}\n type=\"button\"\n >\n <Icon name=\"Reload\" size={14} />\n Rebuild Snapshots\n </button>\n </div>\n </div>\n\n {confirmAction && (\n <div className=\"flex shrink-0 items-center gap-3 rounded-sm border border-yellow-400 bg-yellow-50 px-3 py-2 dark:border-yellow-500 dark:bg-yellow-900\">\n <span className=\"text-sm text-yellow-800 dark:text-yellow-100\">\n {confirmAction === \"keyframes\"\n ? \"This will delete all keyframes for this document. Continue?\"\n : \"This will invalidate all cached snapshots for this document. Continue?\"}\n </span>\n <button\n className=\"rounded-sm bg-yellow-600 px-3 py-1 text-sm text-white hover:bg-yellow-700 dark:bg-yellow-300 dark:text-slate-900 dark:hover:bg-yellow-200\"\n onClick={() => {\n if (confirmAction === \"keyframes\") {\n void handleRebuildKeyframes();\n } else {\n void handleRebuildSnapshots();\n }\n }}\n type=\"button\"\n >\n Confirm\n </button>\n <button\n className=\"rounded-sm border border-gray-300 bg-gray-50 px-3 py-1 text-sm text-gray-700 hover:bg-gray-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-800\"\n onClick={() => setConfirmAction(null)}\n type=\"button\"\n >\n Cancel\n </button>\n </div>\n )}\n\n <div className=\"min-h-0 flex-1 overflow-auto rounded-lg border border-gray-300 p-4 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {status === \"idle\" && (\n <div className=\"flex h-full items-center justify-center text-sm text-gray-400 dark:text-slate-500\">\n Enter a document ID and run an action\n </div>\n )}\n\n {status === \"running\" && (\n <div className=\"flex h-full items-center justify-center text-sm text-gray-500 dark:text-slate-400\">\n Running...\n </div>\n )}\n\n {status === \"error\" && error && (\n <div className=\"rounded-sm bg-red-50 p-3 text-sm text-red-700 dark:bg-red-900 dark:text-red-100\">\n {error}\n </div>\n )}\n\n {status === \"done\" && validationResult && (\n <ValidationResultView result={validationResult} />\n )}\n\n {status === \"done\" && rebuildResult && (\n <RebuildResultView result={rebuildResult} />\n )}\n </div>\n </div>\n );\n}\n\nfunction ValidationResultView({ result }: { result: ValidationResult }) {\n const totalIssues =\n result.keyframeIssues.length + result.snapshotIssues.length;\n\n return (\n <div className=\"flex flex-col gap-3\">\n <div className=\"flex items-center gap-2\">\n <span\n className={twMerge(\n \"size-3 rounded-full\",\n result.isConsistent\n ? \"bg-green-500 dark:bg-green-400\"\n : \"bg-red-500 dark:bg-red-400\",\n )}\n />\n <span className=\"text-sm font-medium\">\n {result.isConsistent\n ? \"Document is consistent\"\n : `Found ${totalIssues} issue(s)`}\n </span>\n </div>\n\n <div className=\"text-xs text-gray-500 dark:text-slate-400\">\n Document: {result.documentId}\n </div>\n\n {result.keyframeIssues.length > 0 && (\n <div className=\"flex flex-col gap-1\">\n <h3 className=\"text-sm font-medium text-gray-700 dark:text-slate-200\">\n Keyframe Issues\n </h3>\n <table className=\"w-full border-collapse text-xs\">\n <thead>\n <tr className=\"bg-gray-100 dark:bg-slate-700\">\n <th className=\"px-2 py-1 text-left font-medium text-gray-700 dark:text-slate-200\">\n Scope\n </th>\n <th className=\"border-l border-gray-300 px-2 py-1 text-left font-medium text-gray-700 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n Branch\n </th>\n <th className=\"border-l border-gray-300 px-2 py-1 text-left font-medium text-gray-700 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n Revision\n </th>\n <th className=\"border-l border-gray-300 px-2 py-1 text-left font-medium text-gray-700 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n Keyframe Hash\n </th>\n <th className=\"border-l border-gray-300 px-2 py-1 text-left font-medium text-gray-700 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n Replayed Hash\n </th>\n </tr>\n </thead>\n <tbody>\n {result.keyframeIssues.map((issue, i) => (\n <tr\n key={`kf-${i}`}\n className=\"odd:bg-white even:bg-gray-50 dark:odd:bg-slate-800 dark:even:bg-slate-800\"\n >\n <td className=\"px-2 py-1\">{issue.scope}</td>\n <td className=\"border-l border-gray-300 px-2 py-1 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {issue.branch}\n </td>\n <td className=\"border-l border-gray-300 px-2 py-1 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {issue.revision}\n </td>\n <td className=\"border-l border-gray-300 px-2 py-1 font-mono dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {issue.keyframeHash}\n </td>\n <td className=\"border-l border-gray-300 px-2 py-1 font-mono dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {issue.replayedHash}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n\n {result.snapshotIssues.length > 0 && (\n <div className=\"flex flex-col gap-1\">\n <h3 className=\"text-sm font-medium text-gray-700 dark:text-slate-200\">\n Snapshot Issues\n </h3>\n <table className=\"w-full border-collapse text-xs\">\n <thead>\n <tr className=\"bg-gray-100 dark:bg-slate-700\">\n <th className=\"px-2 py-1 text-left font-medium text-gray-700 dark:text-slate-200\">\n Scope\n </th>\n <th className=\"border-l border-gray-300 px-2 py-1 text-left font-medium text-gray-700 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n Branch\n </th>\n <th className=\"border-l border-gray-300 px-2 py-1 text-left font-medium text-gray-700 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n Snapshot Hash\n </th>\n <th className=\"border-l border-gray-300 px-2 py-1 text-left font-medium text-gray-700 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n Replayed Hash\n </th>\n </tr>\n </thead>\n <tbody>\n {result.snapshotIssues.map((issue, i) => (\n <tr\n key={`snap-${i}`}\n className=\"odd:bg-white even:bg-gray-50 dark:odd:bg-slate-800 dark:even:bg-slate-800\"\n >\n <td className=\"px-2 py-1\">{issue.scope}</td>\n <td className=\"border-l border-gray-300 px-2 py-1 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {issue.branch}\n </td>\n <td className=\"border-l border-gray-300 px-2 py-1 font-mono dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {issue.snapshotHash}\n </td>\n <td className=\"border-l border-gray-300 px-2 py-1 font-mono dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {issue.replayedHash}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </div>\n );\n}\n\nfunction RebuildResultView({ result }: { result: RebuildResult }) {\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"size-3 rounded-full bg-green-500 dark:bg-green-400\" />\n <span className=\"text-sm font-medium\">Rebuild complete</span>\n </div>\n <div className=\"text-xs text-gray-500 dark:text-slate-400\">\n Document: {result.documentId}\n </div>\n {result.keyframesDeleted > 0 && (\n <div className=\"text-sm text-gray-700 dark:text-slate-200\">\n Keyframes deleted: {result.keyframesDeleted}\n </div>\n )}\n {result.scopesInvalidated > 0 && (\n <div className=\"text-sm text-gray-700 dark:text-slate-200\">\n Scopes invalidated: {result.scopesInvalidated}\n </div>\n )}\n </div>\n );\n}\n","import { twMerge } from \"tailwind-merge\";\nimport { LogoAnimation } from \"../logo-animation.js\";\n\nexport interface LoadingScreenProps {\n showLoadingScreen: boolean;\n loadingComponent?: React.ReactNode;\n size?: number;\n className?: string;\n}\n\nexport const LoadingScreen: React.FC<LoadingScreenProps> = (props) => {\n const { showLoadingScreen, loadingComponent, size, className } = props;\n\n if (loadingComponent && showLoadingScreen) {\n return loadingComponent;\n }\n\n return (\n <div\n className={twMerge(\n \"absolute inset-0 z-10 flex items-center justify-center bg-gray-50 dark:bg-slate-800\",\n !showLoadingScreen && \"hidden\",\n className,\n )}\n >\n <LogoAnimation size={size} />\n </div>\n );\n};\n","import type { AppOptions, DivProps } from \"#design-system\";\nimport { Modal } from \"#design-system\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { AddLocalDriveForm } from \"../../form/add-local-drive-form.js\";\nimport {\n type AddRemoteDriveInput,\n AddRemoteDriveForm,\n} from \"../../form/add-remote-drive-form.js\";\nimport { TabContent } from \"../../tabs/tab-content.js\";\nimport { Tabs } from \"../../tabs/tabs.js\";\n\ntype ModalProps = ComponentPropsWithoutRef<typeof Modal>;\nexport type AddDriveModalProps = {\n readonly open: boolean;\n readonly onOpenChange: (open: boolean) => void;\n readonly onAddRemoteDrive: (data: AddRemoteDriveInput) => void;\n readonly onAddLocalDrive: (data: AppOptions) => void;\n readonly modalProps?: ModalProps;\n readonly containerProps?: DivProps;\n readonly requestPublicDrive: (\n url: string,\n ) => Promise<{ id: string; name: string }>;\n readonly appOptions: AppOptions[];\n};\nexport function AddDriveModal(props: AddDriveModalProps) {\n function handleCancel() {\n onOpenChange(false);\n }\n const {\n open,\n onOpenChange,\n onAddRemoteDrive,\n onAddLocalDrive,\n requestPublicDrive,\n modalProps,\n containerProps,\n } = props;\n return (\n <Modal\n {...modalProps}\n overlayProps={{\n className: \"items-start pt-[15vh]\",\n }}\n onOpenChange={onOpenChange}\n open={open}\n >\n <div\n {...containerProps}\n className={twMerge(\n \"w-102 rounded-2xl bg-gray-50 p-6 dark:bg-slate-800\",\n containerProps?.className,\n )}\n >\n <Tabs defaultValue=\"Create Drive\">\n <TabContent label=\"Create Drive\" description=\"Create a new drive\">\n <AddLocalDriveForm\n onCancel={handleCancel}\n onSubmit={onAddLocalDrive}\n appOptions={props.appOptions}\n />\n </TabContent>\n <TabContent label=\"Add Drive\" description=\"Add a drive\">\n <AddRemoteDriveForm\n sharingType=\"PUBLIC\"\n onSubmit={onAddRemoteDrive}\n onCancel={handleCancel}\n requestPublicDrive={requestPublicDrive}\n />\n </TabContent>\n </Tabs>\n </div>\n </Modal>\n );\n}\n","import { Icon, Modal } from \"#design-system\";\nimport { isValidName } from \"@powerhousedao/shared/document-drive\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { useCallback, useState } from \"react\";\nimport { FormInput } from \"../form-input/form-input.js\";\nimport { ModalButton } from \"./modal-button.js\";\n\nexport type CreateDocumentModalProps = ComponentPropsWithoutRef<\n typeof Modal\n> & {\n readonly onContinue: (nodeName: string) => void;\n};\n\nconst CLOSE_ANIMATION_DURATION = 300;\n\nexport function CreateDocumentModal(props: CreateDocumentModalProps) {\n const { onOpenChange, onContinue, overlayProps, contentProps, ...restProps } =\n props;\n\n const [nodeName, setNodeName] = useState(\"\");\n const [isValid, setIsValid] = useState(false);\n\n const handleCancel = () => {\n onOpenChange?.(false);\n setTimeout(() => setNodeName(\"\"), CLOSE_ANIMATION_DURATION);\n };\n\n const handleCreate = useCallback(() => {\n if (!isValid) {\n return;\n }\n\n onContinue(nodeName);\n setTimeout(() => setNodeName(\"\"), CLOSE_ANIMATION_DURATION);\n }, [isValid, nodeName, onContinue]);\n\n const handleSubmit = useCallback(\n (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n handleCreate();\n },\n [handleCreate],\n );\n\n return (\n <Modal\n contentProps={contentProps}\n onOpenChange={onOpenChange}\n overlayProps={{\n ...overlayProps,\n className: overlayProps?.className,\n }}\n {...restProps}\n >\n <form\n name=\"create-document\"\n className=\"w-100 rounded-xl bg-gray-50 p-6 text-gray-300 dark:bg-slate-800 dark:text-slate-600\"\n onSubmit={handleSubmit}\n >\n <div className=\"pb-2 text-2xl font-bold text-gray-900 dark:text-slate-100\">\n Create a new document\n </div>\n <div className=\"my-6\">\n {!isValid && nodeName && (\n <div className=\"mb-2 text-red-500 dark:text-red-100\">\n Document name must not be empty or contain control characters.\n </div>\n )}\n <FormInput\n icon={<Icon name=\"BrickGlobe\" />}\n onChange={(e) => {\n const name = e.target.value;\n setNodeName(name);\n setIsValid(isValidName(name));\n }}\n placeholder=\"Document name\"\n required\n value={nodeName}\n />\n </div>\n <div className=\"mt-8 flex justify-between gap-3\">\n <ModalButton variant=\"cancel\" type=\"button\" onClick={handleCancel}>\n Cancel\n </ModalButton>\n <ModalButton variant=\"confirm\" type=\"submit\" disabled={!isValid}>\n Create\n </ModalButton>\n </div>\n </form>\n </Modal>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { useState } from \"react\";\nimport { FormInput } from \"../form-input/form-input.js\";\nimport type { ConfirmationModalProps } from \"./confirmation-modal.js\";\nimport { ConnectConfirmationModal } from \"./confirmation-modal.js\";\n\nexport interface ConnectDeleteDriveModalProps extends ConfirmationModalProps {\n readonly inputPlaceholder: string;\n readonly driveName: string;\n}\n\nexport const ConnectDeleteDriveModal: React.FC<ConnectDeleteDriveModalProps> = (\n props,\n) => {\n const { inputPlaceholder, body, driveName, ...confirmationModalProps } =\n props;\n\n const [inputName, setInputName] = useState(\"\");\n\n return (\n <ConnectConfirmationModal\n {...confirmationModalProps}\n continueDisabled={inputName !== driveName}\n body={\n <div>\n <div className=\"my-6 rounded-md bg-gray-50 p-4 text-center dark:bg-slate-800\">\n {body}\n </div>\n <div>\n <FormInput\n hideErrors\n icon={<Icon name=\"Lock\" />}\n onChange={(e) => setInputName(e.target.value)}\n placeholder={inputPlaceholder}\n value={inputName}\n />\n </div>\n </div>\n }\n ></ConnectConfirmationModal>\n );\n};\n","import {\n type ConfirmationModalProps,\n ConnectConfirmationModal,\n} from \"./confirmation-modal.js\";\n\nexport interface ConnectDeleteItemModalProps extends Omit<\n ConfirmationModalProps,\n \"onContinue\" | \"continueLabel\"\n> {\n readonly onDelete: () => void;\n readonly deleteLabel: string;\n}\n\nexport function ConnectDeleteItemModal(props: ConnectDeleteItemModalProps) {\n const { onDelete, deleteLabel, ...restProps } = props;\n\n return (\n <ConnectConfirmationModal\n {...restProps}\n continueLabel={deleteLabel}\n onContinue={onDelete}\n />\n );\n}\n","import { Icon } from \"#design-system\";\nimport type { ComponentPropsWithRef, ForwardedRef } from \"react\";\nimport { forwardRef } from \"react\";\nimport { FormInput } from \"../../form-input/form-input.js\";\n\ntype DriveNameInputProps = Omit<\n ComponentPropsWithRef<typeof FormInput>,\n \"icon\" | \"id\"\n> & {\n readonly icon?: React.JSX.Element;\n};\n\nexport const DriveNameInput = forwardRef(function DriveNameInput(\n props: DriveNameInputProps,\n ref: ForwardedRef<HTMLInputElement>,\n) {\n return (\n <FormInput\n {...props}\n icon={props.icon ?? <Icon name=\"Drive\" />}\n id=\"driveName\"\n placeholder=\"Drive name\"\n ref={ref}\n />\n );\n});\n","import { Icon, PowerhouseButton } from \"#design-system\";\nimport type { DocumentDriveDocument } from \"@powerhousedao/shared/document-drive\";\nimport { useState } from \"react\";\nimport { DriveNameInput } from \"./drive-name-input.js\";\n\nexport type DeleteDriveProps = {\n drive: DocumentDriveDocument;\n handleDeleteDrive: () => void;\n onCancel: () => void;\n};\n\nexport function DeleteDrive(props: DeleteDriveProps) {\n const { drive, handleDeleteDrive, onCancel } = props;\n const [driveNameInput, setDriveNameInput] = useState(\"\");\n\n const isAllowedToDelete = driveNameInput === drive.header.name;\n\n function deleteDrive() {\n if (isAllowedToDelete) {\n handleDeleteDrive();\n }\n }\n\n return (\n <div>\n <p className=\"mb-2 rounded-md bg-gray-50 p-4 text-center text-gray-200 dark:bg-slate-800 dark:text-slate-200\">\n Are you sure you want to delete this drive? All files and subfolders\n within it will be removed. Do you want to proceed?\n </p>\n <DriveNameInput\n icon={<Icon name=\"Lock\" />}\n onChange={(event) => setDriveNameInput(event.target.value)}\n placeholder=\"Enter drive name...\"\n value={driveNameInput}\n />\n <div className=\"flex gap-3\">\n <PowerhouseButton className=\"w-full\" color=\"light\" onClick={onCancel}>\n Cancel\n </PowerhouseButton>\n <PowerhouseButton\n className=\"w-full\"\n color=\"red\"\n disabled={!isAllowedToDelete}\n onClick={deleteDrive}\n >\n Delete\n </PowerhouseButton>\n </div>\n </div>\n );\n}\n","import { Icon, PowerhouseButton } from \"#design-system\";\nimport type { DriveSystemInfoState } from \"@powerhousedao/reactor-browser\";\nimport type { DocumentDriveDocument } from \"@powerhousedao/shared/document-drive\";\nimport type { SharingType } from \"@powerhousedao/shared/document-drive\";\nimport { useState } from \"react\";\nimport type { SubmitHandler } from \"react-hook-form\";\nimport { useForm } from \"react-hook-form\";\nimport { Disclosure } from \"../disclosure/disclosure.js\";\nimport { Divider } from \"../divider/divider.js\";\nimport { AvailableOfflineToggle } from \"./inputs/available-offline-toggle.js\";\nimport { DeleteDrive } from \"./inputs/delete-drive.js\";\nimport { DriveNameInput } from \"./inputs/drive-name-input.js\";\nimport { Label } from \"./inputs/label.js\";\nimport { LocationInfo } from \"./inputs/location-info.js\";\nimport { SharingTypeFormInput } from \"./inputs/sharing-type-form-input.js\";\n\ntype Inputs = {\n name: string;\n sharingType: SharingType;\n availableOffline: boolean;\n};\n\ntype DriveSettingsFormProps = {\n drive: DocumentDriveDocument;\n sharingType: SharingType;\n availableOffline: boolean;\n systemInfo: DriveSystemInfoState;\n onSubmit: DriveSettingsFormSubmitHandler;\n handleCancel: () => void;\n handleDeleteDrive: () => void;\n};\n\nexport type DriveSettingsFormSubmitHandler = SubmitHandler<Inputs>;\n\nexport function DriveSettingsForm(props: DriveSettingsFormProps) {\n const {\n drive,\n sharingType,\n availableOffline,\n systemInfo,\n onSubmit,\n handleDeleteDrive,\n } = props;\n const name = drive.header.name;\n\n const [showLocationSettings, setShowLocationSettings] = useState(false);\n const [showAbout, setShowAbout] = useState(false);\n const [showDangerZone, setShowDangerZone] = useState(false);\n const [showDeleteDrive, setShowDeleteDrive] = useState(false);\n\n const { register, handleSubmit, control } = useForm<Inputs>({\n mode: \"onBlur\",\n defaultValues: {\n name,\n sharingType,\n availableOffline,\n },\n });\n\n const location = sharingType === \"PUBLIC\" ? \"SWITCHBOARD\" : sharingType;\n\n return (\n <form onSubmit={(e) => void handleSubmit(onSubmit)(e)}>\n <DriveNameInput {...register(\"name\")} />\n <Divider className=\"my-4\" />\n <Label htmlFor=\"sharingType\">Sharing settings</Label>\n <SharingTypeFormInput control={control} />\n <Divider className=\"my-3\" />\n <Disclosure\n isOpen={showLocationSettings}\n onOpenChange={() => setShowLocationSettings(!showLocationSettings)}\n title=\"Location\"\n >\n <LocationInfo location={location} />\n <AvailableOfflineToggle {...register(\"availableOffline\")} />\n </Disclosure>\n <Divider className=\"my-3\" />\n <Disclosure\n isOpen={showAbout}\n onOpenChange={() => setShowAbout(!showAbout)}\n title=\"About this drive\"\n >\n {systemInfo.status === \"local\" && (\n <p className=\"py-2 text-sm text-gray-500 dark:text-slate-400\">\n Local drive — N/A\n </p>\n )}\n {systemInfo.status === \"loading\" && (\n <p className=\"py-2 text-sm text-gray-400 dark:text-slate-500\">\n Loading…\n </p>\n )}\n {systemInfo.status === \"error\" && (\n <p className=\"py-2 text-sm text-red-600 dark:text-red-100\">\n Could not load system info\n </p>\n )}\n {systemInfo.status === \"ready\" && (\n <div className=\"py-2 text-sm text-gray-700 dark:text-slate-200\">\n <div>\n <span className=\"font-medium\">Version:</span> {systemInfo.version}\n </div>\n <div>\n <span className=\"font-medium\">Git hash:</span>{\" \"}\n {systemInfo.gitHash}\n </div>\n </div>\n )}\n </Disclosure>\n <Divider className=\"my-3\" />\n <Disclosure\n isOpen={showDangerZone}\n onOpenChange={() => setShowDangerZone(!showDangerZone)}\n title=\"Danger zone\"\n >\n <button\n className=\"flex gap-2 py-3 font-semibold text-red-900 transition hover:brightness-125 dark:text-red-400\"\n onClick={() => setShowDeleteDrive(true)}\n type=\"button\"\n >\n <Icon name=\"Trash\" />\n Delete drive\n </button>\n </Disclosure>\n {showDeleteDrive && showDangerZone ? (\n <DeleteDrive\n drive={drive}\n handleDeleteDrive={handleDeleteDrive}\n onCancel={() => setShowDeleteDrive(false)}\n />\n ) : (\n <>\n <Divider className=\"my-3\" />\n <PowerhouseButton className=\"mb-4 w-full\" type=\"submit\">\n Confirm\n </PowerhouseButton>\n </>\n )}\n </form>\n );\n}\n","import type { DivProps } from \"#design-system\";\nimport { Icon, Modal } from \"#design-system\";\nimport type { DriveSystemInfoState } from \"@powerhousedao/reactor-browser\";\nimport type { DocumentDriveDocument } from \"@powerhousedao/shared/document-drive\";\nimport type { SharingType } from \"@powerhousedao/shared/document-drive\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Divider } from \"../divider/divider.js\";\nimport {\n type DriveSettingsFormSubmitHandler,\n DriveSettingsForm,\n} from \"../form/drive-settings-form.js\";\n\ntype ModalProps = ComponentPropsWithoutRef<typeof Modal>;\n\nexport type DriveSettingsModalProps = {\n drive: DocumentDriveDocument;\n sharingType: SharingType;\n availableOffline: boolean;\n systemInfo: DriveSystemInfoState;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onRenameDrive: (drive: DocumentDriveDocument, newName: string) => void;\n onDeleteDrive: (drive: DocumentDriveDocument) => void;\n onChangeSharingType: (\n drive: DocumentDriveDocument,\n newSharingType: SharingType,\n ) => void;\n onChangeAvailableOffline: (\n drive: DocumentDriveDocument,\n newAvailableOffline: boolean,\n ) => void;\n modalProps?: ModalProps;\n containerProps?: DivProps;\n};\nexport function DriveSettingsModal(props: DriveSettingsModalProps) {\n const {\n drive,\n open,\n sharingType,\n availableOffline,\n systemInfo,\n onOpenChange,\n onDeleteDrive,\n onRenameDrive,\n onChangeSharingType,\n onChangeAvailableOffline,\n modalProps,\n containerProps,\n } = props;\n\n const onSubmit: DriveSettingsFormSubmitHandler = (data) => {\n if (data.name !== drive.header.name) {\n onRenameDrive(drive, data.name);\n }\n if (data.sharingType !== sharingType) {\n onChangeSharingType(drive, data.sharingType);\n }\n if (data.availableOffline !== availableOffline) {\n onChangeAvailableOffline(drive, data.availableOffline);\n }\n onOpenChange(false);\n };\n\n function handleDeleteDrive() {\n onDeleteDrive(drive);\n onOpenChange(false);\n }\n\n function handleCancel() {\n onOpenChange(false);\n }\n\n return (\n <Modal\n {...modalProps}\n contentProps={{\n className: \"rounded-2xl\",\n }}\n onOpenChange={onOpenChange}\n open={open}\n >\n <div\n {...containerProps}\n className={twMerge(\n \"max-w-[408px] rounded-2xl bg-gray-50 p-6 dark:bg-slate-800\",\n containerProps?.className,\n )}\n >\n <div className=\"flex justify-between\">\n <h1 className=\"text-xl font-bold text-gray-900 dark:text-slate-50\">\n Drive settings\n </h1>\n <button\n className=\"flex size-8 items-center justify-center rounded-md bg-gray-100 text-gray-500 outline-none hover:text-gray-900 dark:bg-slate-700 dark:text-slate-400 dark:hover:text-slate-50\"\n onClick={handleCancel}\n tabIndex={-1}\n >\n <Icon name=\"XmarkLight\" size={24} />\n </button>\n </div>\n <Divider className=\"my-4\" />\n <DriveSettingsForm\n handleCancel={handleCancel}\n handleDeleteDrive={handleDeleteDrive}\n onSubmit={onSubmit}\n drive={drive}\n sharingType={sharingType}\n availableOffline={availableOffline}\n systemInfo={systemInfo}\n />\n </div>\n </Modal>\n );\n}\n","import { Icon, Modal } from \"#design-system\";\nimport { JsonViewer } from \"#design-system/ui\";\n\n/**\n * Converts an object to a JSON-serializable form by handling\n * non-serializable values like functions, symbols, and errors.\n */\nfunction toSerializableObject(obj: unknown): unknown {\n return JSON.parse(\n JSON.stringify(obj, (_key, value: unknown) => {\n if (typeof value === \"function\") return \"[Function]\";\n if (typeof value === \"symbol\") return \"[Symbol]\";\n if (value instanceof Error)\n return { name: value.name, message: value.message };\n return value;\n }),\n );\n}\n\nexport type ObjectInspectorModalProps = {\n readonly open: boolean;\n readonly onOpenChange: (open: boolean) => void;\n readonly title: string;\n readonly object: unknown;\n};\n\nexport function ObjectInspectorModal({\n open,\n onOpenChange,\n title,\n object,\n}: ObjectInspectorModalProps) {\n const serializableObject = object ? toSerializableObject(object) : null;\n\n return (\n <Modal\n contentProps={{\n className: \"rounded-2xl\",\n style: { height: \"80vh\", width: \"80vw\", maxWidth: \"900px\" },\n }}\n onOpenChange={onOpenChange}\n open={open}\n title={title}\n >\n <div className=\"flex size-full flex-col bg-gray-50 dark:bg-slate-800\">\n <div className=\"flex shrink-0 items-center justify-between border-b border-gray-200 px-4 py-3 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <h2 className=\"text-lg font-semibold text-gray-900 dark:text-slate-50\">\n {title}\n </h2>\n <button\n className=\"flex size-6 cursor-pointer items-center justify-center rounded-md text-gray-500 outline-none hover:text-gray-900 dark:text-slate-400 dark:hover:text-slate-50\"\n onClick={() => onOpenChange(false)}\n type=\"button\"\n >\n <Icon name=\"XmarkLight\" size={24} />\n </button>\n </div>\n\n <div className=\"flex-1 overflow-auto p-4\">\n {serializableObject ? (\n <JsonViewer data={serializableObject} />\n ) : (\n <p className=\"text-gray-500 dark:text-slate-400\">\n No data to display\n </p>\n )}\n </div>\n </div>\n </Modal>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ObjectInspectorModal } from \"../object-inspector-modal/index.js\";\n\nexport type ProcessorInfo = {\n processorId: string;\n factoryId: string;\n driveId: string;\n processorIndex: number;\n lastOrdinal: number;\n status: \"active\" | \"errored\";\n lastError: string | undefined;\n lastErrorTimestamp: Date | undefined;\n};\n\nexport type ProcessorsInspectorProps = {\n readonly getProcessors: () => Promise<ProcessorInfo[]>;\n readonly onRetry?: (processorId: string) => Promise<void>;\n};\n\ntype SortDirection = \"asc\" | \"desc\";\n\ntype SortOptions = {\n readonly column: string;\n readonly direction: SortDirection;\n};\n\ntype ColumnDef = {\n readonly key: string;\n readonly label: string;\n readonly width?: string;\n};\n\nconst VIEW_COLUMN: ColumnDef = { key: \"view\", label: \"\", width: \"60px\" };\n\nconst COLUMNS: ColumnDef[] = [\n VIEW_COLUMN,\n { key: \"status\", label: \"Status\", width: \"90px\" },\n { key: \"processorId\", label: \"Processor ID\", width: \"150px\" },\n { key: \"factoryId\", label: \"Factory ID\", width: \"150px\" },\n { key: \"driveId\", label: \"Drive ID\", width: \"150px\" },\n { key: \"processorIndex\", label: \"Index\", width: \"70px\" },\n { key: \"lastOrdinal\", label: \"Last Ordinal\", width: \"100px\" },\n { key: \"lastError\", label: \"Error\", width: \"180px\" },\n { key: \"lastErrorTimestamp\", label: \"Error At\", width: \"160px\" },\n { key: \"actions\", label: \"Actions\", width: \"80px\" },\n];\n\nfunction truncateId(id: string, maxLength: number = 12): string {\n if (id.length <= maxLength) return id;\n return id.slice(0, maxLength) + \"...\";\n}\n\nfunction sortProcessors(\n processors: ProcessorInfo[],\n sort: SortOptions | undefined,\n): ProcessorInfo[] {\n if (!sort) return processors;\n\n return [...processors].sort((a, b) => {\n let comparison: number;\n\n switch (sort.column) {\n case \"status\":\n comparison = a.status.localeCompare(b.status);\n break;\n case \"processorId\":\n comparison = a.processorId.localeCompare(b.processorId);\n break;\n case \"factoryId\":\n comparison = a.factoryId.localeCompare(b.factoryId);\n break;\n case \"driveId\":\n comparison = a.driveId.localeCompare(b.driveId);\n break;\n case \"processorIndex\":\n comparison = a.processorIndex - b.processorIndex;\n break;\n case \"lastOrdinal\":\n comparison = a.lastOrdinal - b.lastOrdinal;\n break;\n case \"lastError\":\n comparison = (a.lastError ?? \"\").localeCompare(b.lastError ?? \"\");\n break;\n case \"lastErrorTimestamp\":\n comparison =\n (a.lastErrorTimestamp?.getTime() ?? 0) -\n (b.lastErrorTimestamp?.getTime() ?? 0);\n break;\n default:\n return 0;\n }\n\n return sort.direction === \"asc\" ? comparison : -comparison;\n });\n}\n\nfunction SortIcon({\n direction,\n active,\n}: {\n direction: SortDirection;\n active: boolean;\n}) {\n if (!active) {\n return (\n <Icon\n className=\"opacity-0 group-hover:opacity-50\"\n name=\"CaretSort\"\n size={12}\n />\n );\n }\n\n return (\n <Icon\n className={direction === \"asc\" ? \"rotate-180\" : undefined}\n name=\"TriangleDown\"\n size={12}\n />\n );\n}\n\nexport function ProcessorsInspector({\n getProcessors,\n onRetry,\n}: ProcessorsInspectorProps) {\n const [processors, setProcessors] = useState<ProcessorInfo[]>([]);\n const [loading, setLoading] = useState(true);\n const [sort, setSort] = useState<SortOptions | undefined>();\n const [retryingId, setRetryingId] = useState<string | null>(null);\n const [selectedProcessor, setSelectedProcessor] =\n useState<ProcessorInfo | null>(null);\n\n const [error, setError] = useState<string | null>(null);\n\n const loadProcessors = useCallback(async () => {\n try {\n const result = await getProcessors();\n setProcessors(result);\n setError(null);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setLoading(false);\n }\n }, [getProcessors]);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n void loadProcessors();\n\n const interval = setInterval(() => {\n void loadProcessors();\n }, 2000);\n\n return () => clearInterval(interval);\n }, [loadProcessors]);\n\n const handleRefresh = useCallback(async () => {\n setLoading(true);\n await loadProcessors();\n }, [loadProcessors]);\n\n const handleRetry = useCallback(\n async (processorId: string) => {\n if (!onRetry) return;\n setRetryingId(processorId);\n try {\n await onRetry(processorId);\n await loadProcessors();\n } finally {\n setRetryingId(null);\n }\n },\n [onRetry, loadProcessors],\n );\n\n const handleSort = (columnKey: string) => {\n const newDirection: SortDirection =\n sort?.column === columnKey && sort.direction === \"asc\" ? \"desc\" : \"asc\";\n\n setSort({ column: columnKey, direction: newDirection });\n };\n\n const sortedProcessors = sortProcessors(processors, sort);\n\n const activeCount = processors.filter((p) => p.status === \"active\").length;\n const erroredCount = processors.filter((p) => p.status === \"errored\").length;\n\n return (\n <div className=\"flex h-full flex-col gap-2\">\n <div className=\"flex shrink-0 items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-gray-900 dark:text-slate-50\">\n Processors Inspector\n </h2>\n <div className=\"flex items-center gap-2\">\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={loading}\n onClick={() => void handleRefresh()}\n type=\"button\"\n >\n <Icon name=\"Reload\" size={14} />\n Refresh\n </button>\n </div>\n </div>\n\n <div className=\"flex shrink-0 items-center gap-4 rounded-lg bg-gray-100 px-4 py-2 text-sm dark:bg-slate-700\">\n <div className=\"text-gray-700 dark:text-slate-200\">\n Total: <span className=\"font-medium\">{processors.length}</span>\n </div>\n <div className=\"flex items-center gap-2 text-gray-700 dark:text-slate-200\">\n <span className=\"size-2 rounded-full bg-green-500 dark:bg-green-400\" />\n Active: <span className=\"font-medium\">{activeCount}</span>\n </div>\n <div className=\"flex items-center gap-2 text-gray-700 dark:text-slate-200\">\n <span className=\"size-2 rounded-full bg-red-500 dark:bg-red-400\" />\n Errored: <span className=\"font-medium\">{erroredCount}</span>\n </div>\n </div>\n\n {error && (\n <div className=\"shrink-0 rounded-lg border border-red-300 bg-red-50 px-4 py-2 text-sm text-red-700 dark:border-red-600 dark:bg-red-900 dark:text-red-100\">\n Failed to load processors: {error}\n </div>\n )}\n\n <div className=\"max-h-full overflow-auto rounded-lg border border-gray-300 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <table className=\"w-full border-collapse\">\n <thead className=\"sticky top-0 bg-gray-100 dark:bg-slate-700\">\n <tr>\n {COLUMNS.map((column, index) => {\n const isActive = sort?.column === column.key;\n const sortDirection = isActive ? sort.direction : \"asc\";\n\n return (\n <th\n key={column.key}\n className={twMerge(\n \"group cursor-pointer px-3 py-2 text-left text-xs font-medium text-gray-700 hover:bg-gray-200 hover:text-gray-900 dark:text-slate-200 dark:hover:bg-slate-600 dark:hover:text-slate-100\",\n index > 0 &&\n \"border-l border-gray-300 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n )}\n onClick={() => handleSort(column.key)}\n style={{ width: column.width }}\n >\n <div className=\"flex items-center gap-1\">\n <span className=\"truncate\">{column.label}</span>\n <SortIcon active={isActive} direction={sortDirection} />\n </div>\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {loading && sortedProcessors.length === 0 ? (\n <tr>\n <td\n className=\"px-3 py-8 text-center text-sm text-gray-500 dark:text-slate-400\"\n colSpan={COLUMNS.length}\n >\n Loading...\n </td>\n </tr>\n ) : sortedProcessors.length === 0 ? (\n <tr>\n <td\n className=\"px-3 py-8 text-center text-sm text-gray-500 dark:text-slate-400\"\n colSpan={COLUMNS.length}\n >\n No processors registered\n </td>\n </tr>\n ) : (\n sortedProcessors.map((processor) => (\n <tr\n key={processor.processorId}\n className={twMerge(\n \"hover:bg-blue-50 dark:hover:bg-blue-900\",\n processor.status === \"errored\"\n ? \"bg-red-50 dark:bg-red-900\"\n : \"odd:bg-white even:bg-gray-50 dark:odd:bg-slate-800 dark:even:bg-slate-800\",\n )}\n >\n <td className=\"px-3 py-2 text-xs\">\n <button\n className=\"flex items-center gap-1 rounded-sm bg-blue-50 px-2 py-1 text-xs text-blue-700 hover:bg-blue-100 dark:bg-blue-900 dark:text-blue-100 dark:hover:bg-blue-800\"\n onClick={() => setSelectedProcessor(processor)}\n type=\"button\"\n >\n View\n </button>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span\n className={twMerge(\n \"inline-flex items-center gap-1 rounded-sm px-1.5 py-0.5\",\n processor.status === \"active\"\n ? \"bg-green-100 text-green-700 dark:bg-green-800 dark:text-green-100\"\n : \"bg-red-100 text-red-700 dark:bg-red-800 dark:text-red-100\",\n )}\n >\n {processor.status === \"active\" && (\n <span className=\"inline-block size-1.5 rounded-full bg-green-500 dark:bg-green-400\" />\n )}\n {processor.status === \"errored\" && (\n <span className=\"inline-block size-1.5 rounded-full bg-red-500 dark:bg-red-400\" />\n )}\n {processor.status}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span\n className=\"block truncate\"\n title={processor.processorId}\n >\n {truncateId(processor.processorId)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span\n className=\"block truncate\"\n title={processor.factoryId}\n >\n {truncateId(processor.factoryId)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"block truncate\" title={processor.driveId}>\n {truncateId(processor.driveId)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {processor.processorIndex}\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {processor.lastOrdinal}\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {processor.lastError ? (\n <span\n className=\"block truncate text-red-600 dark:text-red-100\"\n title={processor.lastError}\n >\n {processor.lastError}\n </span>\n ) : (\n <span className=\"text-gray-400 dark:text-slate-500\">\n -\n </span>\n )}\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {processor.lastErrorTimestamp ? (\n <span\n className=\"block truncate\"\n title={processor.lastErrorTimestamp.toISOString()}\n >\n {processor.lastErrorTimestamp.toLocaleString()}\n </span>\n ) : (\n <span className=\"text-gray-400 dark:text-slate-500\">\n -\n </span>\n )}\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {processor.status === \"errored\" && onRetry && (\n <button\n className=\"flex items-center gap-1 rounded-sm bg-yellow-50 px-2 py-1 text-xs text-yellow-700 hover:bg-yellow-100 disabled:opacity-50 dark:bg-yellow-900 dark:text-yellow-100 dark:hover:bg-yellow-800\"\n disabled={retryingId === processor.processorId}\n onClick={() => void handleRetry(processor.processorId)}\n type=\"button\"\n >\n Retry\n </button>\n )}\n </td>\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n\n <div className=\"shrink-0 text-sm text-gray-700 dark:text-slate-200\">\n Showing {sortedProcessors.length} processor(s)\n </div>\n\n <ObjectInspectorModal\n object={selectedProcessor}\n onOpenChange={(open) => !open && setSelectedProcessor(null)}\n open={selectedProcessor !== null}\n title=\"Processor\"\n />\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport type { Job } from \"@powerhousedao/reactor-browser\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ObjectInspectorModal } from \"../object-inspector-modal/index.js\";\n\nexport type QueueState = {\n readonly isPaused: boolean;\n readonly pendingJobs: Job[];\n readonly executingJobs: Job[];\n readonly totalPending: number;\n readonly totalExecuting: number;\n};\n\nexport type QueueInspectorProps = {\n readonly getQueueState: () => Promise<QueueState>;\n readonly onPause: () => Promise<void>;\n readonly onResume: () => Promise<void>;\n};\n\ntype SortDirection = \"asc\" | \"desc\";\n\ntype SortOptions = {\n readonly column: string;\n readonly direction: SortDirection;\n};\n\ntype ColumnDef = {\n readonly key: string;\n readonly label: string;\n readonly width?: string;\n};\n\nconst VIEW_COLUMN: ColumnDef = { key: \"view\", label: \"\", width: \"60px\" };\n\nconst COLUMNS: ColumnDef[] = [\n VIEW_COLUMN,\n { key: \"id\", label: \"ID\", width: \"120px\" },\n { key: \"kind\", label: \"Kind\", width: \"80px\" },\n { key: \"documentId\", label: \"Document ID\", width: \"150px\" },\n { key: \"scope\", label: \"Scope\", width: \"100px\" },\n { key: \"branch\", label: \"Branch\", width: \"100px\" },\n { key: \"createdAt\", label: \"Created At\", width: \"160px\" },\n { key: \"retryCount\", label: \"Retries\", width: \"70px\" },\n { key: \"status\", label: \"Status\", width: \"100px\" },\n];\n\nfunction truncateId(id: string, maxLength: number = 12): string {\n if (id.length <= maxLength) return id;\n return id.slice(0, maxLength) + \"...\";\n}\n\nfunction formatDate(dateStr: string): string {\n const date = new Date(dateStr);\n return date.toLocaleString();\n}\n\ntype JobWithStatus = Job & { status: \"pending\" | \"executing\" };\n\nfunction sortJobs(\n jobs: JobWithStatus[],\n sort: SortOptions | undefined,\n): JobWithStatus[] {\n if (!sort) return jobs;\n\n return [...jobs].sort((a, b) => {\n let comparison: number;\n\n switch (sort.column) {\n case \"id\":\n comparison = a.id.localeCompare(b.id);\n break;\n case \"kind\":\n comparison = a.kind.localeCompare(b.kind);\n break;\n case \"documentId\":\n comparison = a.documentId.localeCompare(b.documentId);\n break;\n case \"scope\":\n comparison = a.scope.localeCompare(b.scope);\n break;\n case \"branch\":\n comparison = a.branch.localeCompare(b.branch);\n break;\n case \"createdAt\":\n comparison = a.createdAt.localeCompare(b.createdAt);\n break;\n case \"retryCount\":\n comparison = (a.retryCount ?? 0) - (b.retryCount ?? 0);\n break;\n case \"status\":\n comparison = a.status.localeCompare(b.status);\n break;\n default:\n return 0;\n }\n\n return sort.direction === \"asc\" ? comparison : -comparison;\n });\n}\n\nfunction SortIcon({\n direction,\n active,\n}: {\n direction: SortDirection;\n active: boolean;\n}) {\n if (!active) {\n return (\n <Icon\n className=\"opacity-0 group-hover:opacity-50\"\n name=\"CaretSort\"\n size={12}\n />\n );\n }\n\n return (\n <Icon\n className={direction === \"asc\" ? \"rotate-180\" : undefined}\n name=\"TriangleDown\"\n size={12}\n />\n );\n}\n\nexport function QueueInspector({\n getQueueState,\n onPause,\n onResume,\n}: QueueInspectorProps) {\n const [state, setState] = useState<QueueState>({\n isPaused: false,\n pendingJobs: [],\n executingJobs: [],\n totalPending: 0,\n totalExecuting: 0,\n });\n const [loading, setLoading] = useState(true);\n const [sort, setSort] = useState<SortOptions | undefined>();\n const [actionInProgress, setActionInProgress] = useState(false);\n const [selectedJob, setSelectedJob] = useState<JobWithStatus | null>(null);\n\n const loadState = useCallback(async () => {\n const newState = await getQueueState();\n setState(newState);\n setLoading(false);\n }, [getQueueState]);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n void loadState();\n\n const interval = setInterval(() => {\n void loadState();\n }, 2000);\n\n return () => clearInterval(interval);\n }, [loadState]);\n\n const handleRefresh = useCallback(async () => {\n setLoading(true);\n await loadState();\n }, [loadState]);\n\n const handlePauseResume = useCallback(async () => {\n setActionInProgress(true);\n if (state.isPaused) {\n await onResume();\n } else {\n await onPause();\n }\n await loadState();\n setActionInProgress(false);\n }, [state.isPaused, onPause, onResume, loadState]);\n\n const handleSort = (columnKey: string) => {\n const newDirection: SortDirection =\n sort?.column === columnKey && sort.direction === \"asc\" ? \"desc\" : \"asc\";\n\n setSort({ column: columnKey, direction: newDirection });\n };\n\n const allJobs: JobWithStatus[] = [\n ...state.executingJobs.map((job) => ({\n ...job,\n status: \"executing\" as const,\n })),\n ...state.pendingJobs.map((job) => ({ ...job, status: \"pending\" as const })),\n ];\n\n const sortedJobs = sortJobs(allJobs, sort);\n\n return (\n <div className=\"flex h-full flex-col gap-2\">\n <div className=\"flex shrink-0 items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-gray-900 dark:text-slate-50\">\n Queue Inspector\n </h2>\n <div className=\"flex items-center gap-2\">\n <button\n className={twMerge(\n \"flex items-center gap-1 rounded-sm border px-3 py-1.5 text-sm disabled:opacity-50\",\n state.isPaused\n ? \"border-green-300 bg-green-50 text-green-700 hover:bg-green-100 dark:border-green-600 dark:bg-green-900 dark:text-green-100 dark:hover:bg-green-800\"\n : \"border-yellow-300 bg-yellow-50 text-yellow-700 hover:bg-yellow-100 dark:border-yellow-600 dark:bg-yellow-900 dark:text-yellow-100 dark:hover:bg-yellow-800\",\n )}\n disabled={actionInProgress}\n onClick={() => void handlePauseResume()}\n type=\"button\"\n >\n <Icon\n name={state.isPaused ? \"ArrowFilledRight\" : \"Ellipsis\"}\n size={14}\n />\n {state.isPaused ? \"Resume\" : \"Pause\"}\n </button>\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={loading}\n onClick={() => void handleRefresh()}\n type=\"button\"\n >\n <Icon name=\"Reload\" size={14} />\n Refresh\n </button>\n </div>\n </div>\n\n <div className=\"flex shrink-0 items-center gap-4 rounded-lg bg-gray-100 px-4 py-2 text-sm dark:bg-slate-700\">\n <div className=\"flex items-center gap-2\">\n <span\n className={twMerge(\n \"size-2 rounded-full\",\n state.isPaused\n ? \"bg-yellow-500 dark:bg-yellow-400\"\n : \"bg-green-500 dark:bg-green-400\",\n )}\n />\n <span className=\"font-medium text-gray-700 dark:text-slate-200\">\n {state.isPaused ? \"Paused\" : \"Running\"}\n </span>\n </div>\n <div className=\"text-gray-700 dark:text-slate-200\">\n Pending: <span className=\"font-medium\">{state.totalPending}</span>\n </div>\n <div className=\"text-gray-700 dark:text-slate-200\">\n Executing: <span className=\"font-medium\">{state.totalExecuting}</span>\n </div>\n </div>\n\n <div className=\"max-h-full overflow-auto rounded-lg border border-gray-300 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <table className=\"w-full border-collapse\">\n <thead className=\"sticky top-0 bg-gray-100 dark:bg-slate-700\">\n <tr>\n {COLUMNS.map((column, index) => {\n const isActive = sort?.column === column.key;\n const sortDirection = isActive ? sort.direction : \"asc\";\n\n return (\n <th\n key={column.key}\n className={twMerge(\n \"group cursor-pointer px-3 py-2 text-left text-xs font-medium text-gray-700 hover:bg-gray-200 hover:text-gray-900 dark:text-slate-200 dark:hover:bg-slate-600 dark:hover:text-slate-100\",\n index > 0 &&\n \"border-l border-gray-300 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n )}\n onClick={() => handleSort(column.key)}\n style={{ width: column.width }}\n >\n <div className=\"flex items-center gap-1\">\n <span className=\"truncate\">{column.label}</span>\n <SortIcon active={isActive} direction={sortDirection} />\n </div>\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {loading && sortedJobs.length === 0 ? (\n <tr>\n <td\n className=\"px-3 py-8 text-center text-sm text-gray-500 dark:text-slate-400\"\n colSpan={COLUMNS.length}\n >\n Loading...\n </td>\n </tr>\n ) : sortedJobs.length === 0 ? (\n <tr>\n <td\n className=\"px-3 py-8 text-center text-sm text-gray-500 dark:text-slate-400\"\n colSpan={COLUMNS.length}\n >\n No jobs in queue\n </td>\n </tr>\n ) : (\n sortedJobs.map((job) => (\n <tr\n key={job.id}\n className=\"odd:bg-white even:bg-gray-50 hover:bg-blue-50 dark:odd:bg-slate-800 dark:even:bg-slate-800 dark:hover:bg-blue-900\"\n >\n <td className=\"px-3 py-2 text-xs\">\n <button\n className=\"flex items-center gap-1 rounded-sm bg-blue-50 px-2 py-1 text-xs text-blue-700 hover:bg-blue-100 dark:bg-blue-900 dark:text-blue-100 dark:hover:bg-blue-800\"\n onClick={() => setSelectedJob(job)}\n type=\"button\"\n >\n View\n </button>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"block truncate\" title={job.id}>\n {truncateId(job.id)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span\n className={twMerge(\n \"inline-block rounded-sm px-1.5 py-0.5\",\n job.kind === \"mutation\"\n ? \"bg-purple-100 text-purple-700 dark:bg-purple-800 dark:text-purple-100\"\n : \"bg-blue-100 text-blue-700 dark:bg-blue-800 dark:text-blue-100\",\n )}\n >\n {job.kind}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"block truncate\" title={job.documentId}>\n {truncateId(job.documentId)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"block truncate\" title={job.scope}>\n {job.scope}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"block truncate\" title={job.branch}>\n {job.branch}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"block truncate\" title={job.createdAt}>\n {formatDate(job.createdAt)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {job.retryCount ?? 0}\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span\n className={twMerge(\n \"inline-flex items-center gap-1 rounded-sm px-1.5 py-0.5\",\n job.status === \"executing\"\n ? \"bg-green-100 text-green-700 dark:bg-green-800 dark:text-green-100\"\n : \"bg-gray-100 text-gray-700 dark:bg-slate-700 dark:text-slate-200\",\n )}\n >\n {job.status === \"executing\" && (\n <span className=\"inline-block size-1.5 animate-pulse rounded-full bg-green-500 dark:bg-green-400\" />\n )}\n {job.status}\n </span>\n </td>\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n\n <div className=\"shrink-0 text-sm text-gray-700 dark:text-slate-200\">\n Showing {sortedJobs.length} job(s)\n </div>\n\n <ObjectInspectorModal\n object={selectedJob}\n onOpenChange={(open) => !open && setSelectedJob(null)}\n open={selectedJob !== null}\n title=\"Job\"\n />\n </div>\n );\n}\n","import { twMerge } from \"tailwind-merge\";\n\nexport type ConnectionStateBadgeProps = {\n readonly state: string;\n readonly failureCount: number;\n};\n\nconst stateStyles: Record<string, string> = {\n connected:\n \"bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100\",\n connecting: \"bg-blue-100 text-blue-800 dark:bg-blue-800 dark:text-blue-100\",\n reconnecting:\n \"bg-yellow-100 text-yellow-800 dark:bg-yellow-800 dark:text-yellow-100\",\n error: \"bg-red-100 text-red-800 dark:bg-red-800 dark:text-red-100\",\n disconnected:\n \"bg-gray-100 text-gray-700 dark:bg-slate-700 dark:text-slate-200\",\n};\n\nexport function ConnectionStateBadge({\n state,\n failureCount,\n}: ConnectionStateBadgeProps) {\n const style =\n stateStyles[state] ??\n \"bg-gray-100 text-gray-700 dark:bg-slate-700 dark:text-slate-200\";\n\n return (\n <span\n className={twMerge(\n \"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium\",\n style,\n )}\n >\n {state}\n {failureCount > 0 && (\n <span className=\"text-xs opacity-75\">({failureCount})</span>\n )}\n </span>\n );\n}\n","export type SortDirection = \"asc\" | \"desc\";\n\nexport type SortOptions = {\n readonly column: string;\n readonly direction: SortDirection;\n};\n\nexport type ColumnDef = {\n readonly key: string;\n readonly label: string;\n readonly width?: string;\n};\n\nexport function truncateId(id: string, maxLength: number = 12): string {\n if (id.length <= maxLength) return id;\n return id.slice(0, maxLength) + \"...\";\n}\n","import { Icon } from \"#design-system\";\nimport { type SortDirection } from \"../utils.js\";\n\nexport type SortIconProps = {\n readonly direction: SortDirection;\n readonly active: boolean;\n};\n\nexport function SortIcon({ direction, active }: SortIconProps) {\n if (!active) {\n return (\n <Icon\n className=\"opacity-0 group-hover:opacity-50\"\n name=\"CaretSort\"\n size={12}\n />\n );\n }\n\n return (\n <Icon\n className={direction === \"asc\" ? \"rotate-180\" : undefined}\n name=\"TriangleDown\"\n size={12}\n />\n );\n}\n","import { Icon } from \"#design-system\";\nimport {\n type SyncOperation,\n SyncOperationStatus,\n} from \"@powerhousedao/reactor-browser\";\nimport { useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ObjectInspectorModal } from \"../../object-inspector-modal/index.js\";\nimport { type ColumnDef, type SortOptions, truncateId } from \"../utils.js\";\nimport { SortIcon } from \"./sort-icon.js\";\n\nexport type MailboxType = \"inbox\" | \"outbox\" | \"deadLetter\";\n\nconst VIEW_COLUMN: ColumnDef = { key: \"view\", label: \"\", width: \"60px\" };\n\nconst COLUMNS: ColumnDef[] = [\n VIEW_COLUMN,\n { key: \"documentId\", label: \"Document ID\", width: \"150px\" },\n { key: \"branch\", label: \"Branch\", width: \"100px\" },\n { key: \"scopes\", label: \"Scopes\", width: \"100px\" },\n { key: \"status\", label: \"Status\", width: \"150px\" },\n { key: \"opsCount\", label: \"Ops Count\", width: \"80px\" },\n];\n\nconst DEAD_LETTER_COLUMNS: ColumnDef[] = [\n VIEW_COLUMN,\n { key: \"documentId\", label: \"Document ID\", width: \"150px\" },\n { key: \"branch\", label: \"Branch\", width: \"100px\" },\n { key: \"scopes\", label: \"Scopes\", width: \"100px\" },\n { key: \"error\", label: \"Error\", width: \"200px\" },\n];\n\nfunction toSerializableObject(obj: unknown): unknown {\n return JSON.parse(\n JSON.stringify(obj, (_key, value: unknown) => {\n if (typeof value === \"function\") return \"[Function]\";\n if (typeof value === \"symbol\") return \"[Symbol]\";\n if (value instanceof Error)\n return { name: value.name, message: value.message };\n return value;\n }),\n );\n}\n\nfunction getStatusLabel(status: SyncOperationStatus): string {\n switch (status) {\n case SyncOperationStatus.Unknown:\n return \"Unknown\";\n case SyncOperationStatus.TransportPending:\n return \"Transport Pending\";\n case SyncOperationStatus.ExecutionPending:\n return \"Execution Pending\";\n case SyncOperationStatus.Applied:\n return \"Applied\";\n case SyncOperationStatus.Error:\n return \"Error\";\n default:\n return \"Unknown\";\n }\n}\n\nfunction getStatusIcon(status: SyncOperationStatus): React.ReactNode {\n switch (status) {\n case SyncOperationStatus.TransportPending:\n case SyncOperationStatus.ExecutionPending:\n return <span>⏳</span>;\n case SyncOperationStatus.Applied:\n return <span>✅</span>;\n case SyncOperationStatus.Error:\n return <span>❌</span>;\n default:\n return <span>❓</span>;\n }\n}\n\nfunction getErrorMessage(error: SyncOperation[\"error\"]): string {\n if (!error) return \"\";\n return error.error.message;\n}\n\nfunction sortOperations(\n operations: readonly SyncOperation[],\n sort: SortOptions | undefined,\n): SyncOperation[] {\n const ops = [...operations];\n if (!sort) return ops;\n\n return ops.sort((a, b) => {\n let comparison: number;\n\n switch (sort.column) {\n case \"documentId\":\n comparison = a.documentId.localeCompare(b.documentId);\n break;\n case \"branch\":\n comparison = a.branch.localeCompare(b.branch);\n break;\n case \"scopes\":\n comparison = a.scopes.join(\",\").localeCompare(b.scopes.join(\",\"));\n break;\n case \"status\":\n comparison = a.status - b.status;\n break;\n case \"opsCount\":\n comparison = a.operations.length - b.operations.length;\n break;\n case \"error\":\n comparison = getErrorMessage(a.error).localeCompare(\n getErrorMessage(b.error),\n );\n break;\n default:\n return 0;\n }\n\n return sort.direction === \"asc\" ? comparison : -comparison;\n });\n}\n\nexport type MailboxTableProps = {\n readonly title: string;\n readonly mailboxType: MailboxType;\n readonly operations: readonly SyncOperation[];\n readonly sort: SortOptions | undefined;\n readonly onSort: (mailbox: MailboxType, column: string) => void;\n readonly collapsed: boolean;\n readonly onToggleCollapse: () => void;\n};\n\nexport function MailboxTable({\n title,\n mailboxType,\n operations,\n sort,\n onSort,\n collapsed,\n onToggleCollapse,\n}: MailboxTableProps) {\n const [selectedOperation, setSelectedOperation] =\n useState<SyncOperation | null>(null);\n const columns = mailboxType === \"deadLetter\" ? DEAD_LETTER_COLUMNS : COLUMNS;\n const sortedOps = sortOperations(operations, sort);\n\n const handleSort = (columnKey: string) => {\n onSort(mailboxType, columnKey);\n };\n\n const handleCopyAll = async () => {\n const serializable = toSerializableObject(operations);\n const json = JSON.stringify(serializable, null, 2);\n await navigator.clipboard.writeText(json);\n };\n\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex items-center justify-between\">\n <button\n className=\"flex items-center gap-2 text-left text-sm font-medium text-gray-700 hover:text-gray-900 dark:text-slate-200 dark:hover:text-slate-50\"\n onClick={onToggleCollapse}\n type=\"button\"\n >\n <Icon\n className={twMerge(\n \"transition-transform\",\n collapsed && \"-rotate-90\",\n )}\n name=\"ChevronDown\"\n size={14}\n />\n {title} ({operations.length} item{operations.length !== 1 ? \"s\" : \"\"})\n </button>\n {operations.length > 0 && (\n <button\n className=\"flex items-center gap-1 rounded-sm bg-gray-100 px-2 py-1 text-xs text-gray-700 hover:bg-gray-200 dark:bg-slate-700 dark:text-slate-200 dark:hover:bg-slate-600 dark:hover:text-slate-100\"\n onClick={() => void handleCopyAll()}\n type=\"button\"\n >\n <Icon name=\"Copy\" size={12} />\n Copy All\n </button>\n )}\n </div>\n\n {!collapsed && (\n <div className=\"scrollbar-thin overflow-auto rounded-lg border border-gray-300 scrollbar-thumb-gray-300 scrollbar-thumb-rounded-md scrollbar-track-transparent dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:scrollbar-thumb-slate-600\">\n <table className=\"w-full border-collapse\">\n <thead className=\"sticky top-0 bg-gray-100 dark:bg-slate-700\">\n <tr>\n {columns.map((column, index) => {\n const isActive = sort?.column === column.key;\n const sortDirection = isActive ? sort.direction : \"asc\";\n\n return (\n <th\n key={column.key}\n className={twMerge(\n \"group cursor-pointer px-3 py-2 text-left text-xs font-medium text-gray-700 hover:bg-gray-200 hover:text-gray-900 dark:text-slate-200 dark:hover:bg-slate-600 dark:hover:text-slate-100\",\n index > 0 &&\n \"border-l border-gray-300 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n )}\n onClick={() => handleSort(column.key)}\n style={{ width: column.width }}\n >\n <div className=\"flex items-center gap-1\">\n <span className=\"truncate\">{column.label}</span>\n <SortIcon active={isActive} direction={sortDirection} />\n </div>\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {sortedOps.length === 0 ? (\n <tr>\n <td\n className=\"px-3 py-4 text-center text-sm text-gray-500 dark:text-slate-400\"\n colSpan={columns.length}\n >\n No operations\n </td>\n </tr>\n ) : (\n sortedOps.map((op) => (\n <tr\n key={op.id}\n className=\"odd:bg-white even:bg-gray-50 hover:bg-blue-50 dark:odd:bg-slate-800 dark:even:bg-slate-800 dark:hover:bg-blue-900\"\n >\n <td className=\"px-3 py-2 text-xs\">\n <button\n className=\"flex items-center gap-1 rounded-sm bg-blue-50 px-2 py-1 text-xs text-blue-700 hover:bg-blue-100 dark:bg-blue-900 dark:text-blue-100 dark:hover:bg-blue-800\"\n onClick={() => setSelectedOperation(op)}\n type=\"button\"\n >\n View\n </button>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"block truncate\" title={op.documentId}>\n {truncateId(op.documentId)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"block truncate\" title={op.branch}>\n {op.branch}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span\n className=\"block truncate\"\n title={op.scopes.join(\", \")}\n >\n {op.scopes.join(\", \")}\n </span>\n </td>\n {mailboxType === \"deadLetter\" ? (\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span\n className=\"block truncate text-red-600 dark:text-red-100\"\n title={getErrorMessage(op.error)}\n >\n {getErrorMessage(op.error) || \"Unknown error\"}\n </span>\n </td>\n ) : (\n <>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"flex items-center gap-1\">\n {getStatusIcon(op.status)}\n {getStatusLabel(op.status)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {op.operations.length}\n </td>\n </>\n )}\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n )}\n\n <ObjectInspectorModal\n object={selectedOperation}\n onOpenChange={(open) => !open && setSelectedOperation(null)}\n open={selectedOperation !== null}\n title=\"Sync Operation\"\n />\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport type {\n IChannel,\n IntervalPollTimer,\n} from \"@powerhousedao/reactor-browser\";\nimport { useCallback, useState } from \"react\";\nimport type { ConnectionStateSummary } from \"../remotes-inspector.js\";\nimport { type SortDirection, type SortOptions } from \"../utils.js\";\nimport { ConnectionStateBadge } from \"./connection-state-badge.js\";\nimport { MailboxTable, type MailboxType } from \"./mailbox-table.js\";\n\nexport type ChannelInspectorProps = {\n readonly remoteName: string;\n readonly channel: IChannel;\n readonly onBack: () => void;\n readonly onRefresh?: () => void;\n readonly connectionState?: ConnectionStateSummary;\n};\n\nfunction formatTimestamp(ms: number): string {\n if (ms === 0) return \"-\";\n return new Date(ms).toLocaleTimeString();\n}\n\nexport function ChannelInspector({\n remoteName,\n channel,\n onBack,\n onRefresh,\n connectionState,\n}: ChannelInspectorProps) {\n const [sorts, setSorts] = useState<\n Record<MailboxType, SortOptions | undefined>\n >({\n inbox: undefined,\n outbox: undefined,\n deadLetter: undefined,\n });\n\n const [collapsed, setCollapsed] = useState<Record<MailboxType, boolean>>({\n inbox: false,\n outbox: false,\n deadLetter: false,\n });\n\n const handleToggleCollapse = (mailbox: MailboxType) => {\n setCollapsed((prev) => ({\n ...prev,\n [mailbox]: !prev[mailbox],\n }));\n };\n\n const handleSort = (mailbox: MailboxType, columnKey: string) => {\n setSorts((prev) => {\n const currentSort = prev[mailbox];\n const newDirection: SortDirection =\n currentSort?.column === columnKey && currentSort.direction === \"asc\"\n ? \"desc\"\n : \"asc\";\n\n return {\n ...prev,\n [mailbox]: { column: columnKey, direction: newDirection },\n };\n });\n };\n\n const getPollerControls = useCallback(() => {\n return \"poller\" in channel ? (channel.poller as IntervalPollTimer) : null;\n }, [channel]);\n\n const pollerControls = getPollerControls();\n const [pollerState, setPollerState] = useState(() => ({\n isPaused: pollerControls?.isPaused() ?? false,\n isRunning: pollerControls?.isRunning() ?? false,\n }));\n\n const [intervalMs, setIntervalMs] = useState(\n () => pollerControls?.getIntervalMs() ?? 2000,\n );\n\n const [mailboxStates, setMailboxStates] = useState(() => ({\n inbox: { isPaused: channel.inbox.isPaused() },\n outbox: { isPaused: channel.outbox.isPaused() },\n }));\n\n const handlePause = useCallback(() => {\n if (pollerControls) {\n pollerControls.pause();\n setPollerState({\n isPaused: pollerControls.isPaused(),\n isRunning: pollerControls.isRunning(),\n });\n }\n }, [pollerControls]);\n\n const handleResume = useCallback(() => {\n if (pollerControls) {\n pollerControls.resume();\n setPollerState({\n isPaused: pollerControls.isPaused(),\n isRunning: pollerControls.isRunning(),\n });\n }\n }, [pollerControls]);\n\n const handlePollNow = useCallback(() => {\n if (pollerControls) {\n pollerControls.triggerNow();\n }\n }, [pollerControls]);\n\n const handleApplyInterval = useCallback(() => {\n if (pollerControls) {\n pollerControls.setIntervalMs(intervalMs);\n }\n }, [pollerControls, intervalMs]);\n\n const handleMailboxPause = useCallback(\n (mailbox: \"inbox\" | \"outbox\") => {\n const mailboxInstance =\n mailbox === \"inbox\" ? channel.inbox : channel.outbox;\n mailboxInstance.pause();\n setMailboxStates((prev) => ({\n ...prev,\n [mailbox]: { isPaused: mailboxInstance.isPaused() },\n }));\n },\n [channel],\n );\n\n const handleMailboxResume = useCallback(\n (mailbox: \"inbox\" | \"outbox\") => {\n const mailboxInstance =\n mailbox === \"inbox\" ? channel.inbox : channel.outbox;\n mailboxInstance.resume();\n setMailboxStates((prev) => ({\n ...prev,\n [mailbox]: { isPaused: mailboxInstance.isPaused() },\n }));\n },\n [channel],\n );\n\n const handleMailboxFlush = useCallback(\n (mailbox: \"inbox\" | \"outbox\") => {\n const mailboxInstance =\n mailbox === \"inbox\" ? channel.inbox : channel.outbox;\n mailboxInstance.flush();\n onRefresh?.();\n },\n [channel, onRefresh],\n );\n\n return (\n <div className=\"flex h-full flex-col gap-3 overflow-auto\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-2 py-1 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={onBack}\n type=\"button\"\n >\n <Icon className=\"rotate-90\" name=\"ChevronDown\" size={14} />\n Back\n </button>\n <h2 className=\"text-lg font-semibold text-gray-900 dark:text-slate-50\">\n Channel: {remoteName}\n </h2>\n </div>\n {onRefresh && (\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={onRefresh}\n type=\"button\"\n >\n <Icon name=\"Reload\" size={14} />\n Refresh\n </button>\n )}\n </div>\n\n {connectionState && (\n <div className=\"rounded-sm border border-gray-200 bg-gray-50 p-4 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <h3 className=\"mb-3 text-sm font-semibold text-gray-900 dark:text-slate-50\">\n Connection State\n </h3>\n <div className=\"flex flex-wrap items-center gap-4 text-sm text-gray-700 dark:text-slate-200\">\n <div className=\"flex items-center gap-2\">\n <span>State:</span>\n <ConnectionStateBadge\n failureCount={connectionState.failureCount}\n state={connectionState.state}\n />\n </div>\n <div>\n Last success: {formatTimestamp(connectionState.lastSuccessUtcMs)}\n </div>\n <div>\n Last failure: {formatTimestamp(connectionState.lastFailureUtcMs)}\n </div>\n <div>Failures: {connectionState.failureCount}</div>\n <div>\n Push:{\" \"}\n <span\n className={\n connectionState.pushBlocked\n ? \"text-red-600 dark:text-red-100\"\n : \"text-green-600 dark:text-green-100\"\n }\n >\n {connectionState.pushBlocked ? \"Blocked\" : \"OK\"}\n </span>\n {connectionState.pushFailureCount > 0 && (\n <span className=\"ml-1 text-red-600 dark:text-red-100\">\n ({connectionState.pushFailureCount} failures)\n </span>\n )}\n </div>\n </div>\n </div>\n )}\n\n {pollerControls && (\n <div className=\"rounded-sm border border-gray-200 bg-gray-50 p-4 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <h3 className=\"mb-3 text-sm font-semibold text-gray-900 dark:text-slate-50\">\n Poller\n </h3>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-4\">\n <div className=\"text-sm text-gray-700 dark:text-slate-200\">\n Status:{\" \"}\n <span\n className={\n pollerState.isPaused\n ? \"text-yellow-600 dark:text-yellow-100\"\n : \"text-green-600 dark:text-green-100\"\n }\n >\n {pollerState.isPaused ? \"Paused\" : \"Running\"}\n </span>\n </div>\n <div className=\"flex items-center gap-1\">\n <label\n className=\"text-sm text-gray-700 dark:text-slate-200\"\n htmlFor=\"poll-interval\"\n >\n Interval:\n </label>\n <input\n className=\"w-20 rounded-sm border border-gray-300 px-2 py-1 text-sm dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\"\n id=\"poll-interval\"\n min={100}\n onChange={(e) => setIntervalMs(Number(e.target.value))}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n handleApplyInterval();\n }\n }}\n type=\"number\"\n value={intervalMs}\n />\n <span className=\"text-sm text-gray-500 dark:text-slate-400\">\n ms\n </span>\n <button\n className=\"ml-1 rounded-sm border border-gray-300 bg-gray-50 px-2 py-1 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={handleApplyInterval}\n type=\"button\"\n >\n Apply\n </button>\n </div>\n </div>\n <div className=\"flex gap-2\">\n {pollerState.isPaused ? (\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={handleResume}\n type=\"button\"\n >\n Resume\n </button>\n ) : (\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={handlePause}\n type=\"button\"\n >\n Pause\n </button>\n )}\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={!pollerState.isPaused}\n onClick={handlePollNow}\n type=\"button\"\n >\n Poll Now\n </button>\n </div>\n </div>\n </div>\n )}\n\n <div className=\"rounded-sm border border-gray-200 bg-gray-50 p-4 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <h3 className=\"mb-3 text-sm font-semibold text-gray-900 dark:text-slate-50\">\n Mailbox Processing\n </h3>\n <div className=\"flex flex-col gap-3\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3 text-sm text-gray-700 dark:text-slate-200\">\n <span>\n Inbox:{\" \"}\n <span\n className={\n mailboxStates.inbox.isPaused\n ? \"text-yellow-600 dark:text-yellow-100\"\n : \"text-green-600 dark:text-green-100\"\n }\n >\n {mailboxStates.inbox.isPaused ? \"Paused\" : \"Active\"}\n </span>\n </span>\n <span className=\"font-mono text-sm text-gray-500 dark:text-slate-400\">\n We ack'd (theirs): {channel.inbox.ackOrdinal} | Received:{\" \"}\n {channel.inbox.latestOrdinal}\n </span>\n </div>\n <div className=\"flex gap-2\">\n {mailboxStates.inbox.isPaused ? (\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={() => handleMailboxResume(\"inbox\")}\n type=\"button\"\n >\n Resume\n </button>\n ) : (\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={() => handleMailboxPause(\"inbox\")}\n type=\"button\"\n >\n Pause\n </button>\n )}\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={!mailboxStates.inbox.isPaused}\n onClick={() => handleMailboxFlush(\"inbox\")}\n type=\"button\"\n >\n Flush\n </button>\n </div>\n </div>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3 text-sm text-gray-700 dark:text-slate-200\">\n <span>\n Outbox:{\" \"}\n <span\n className={\n mailboxStates.outbox.isPaused\n ? \"text-yellow-600 dark:text-yellow-100\"\n : \"text-green-600 dark:text-green-100\"\n }\n >\n {mailboxStates.outbox.isPaused ? \"Paused\" : \"Active\"}\n </span>\n </span>\n <span className=\"font-mono text-sm text-gray-500 dark:text-slate-400\">\n They ack'd (ours): {channel.outbox.ackOrdinal} | Sent:{\" \"}\n {channel.outbox.latestOrdinal}\n </span>\n </div>\n <div className=\"flex gap-2\">\n {mailboxStates.outbox.isPaused ? (\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={() => handleMailboxResume(\"outbox\")}\n type=\"button\"\n >\n Resume\n </button>\n ) : (\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={() => handleMailboxPause(\"outbox\")}\n type=\"button\"\n >\n Pause\n </button>\n )}\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={!mailboxStates.outbox.isPaused}\n onClick={() => handleMailboxFlush(\"outbox\")}\n type=\"button\"\n >\n Flush\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <div className=\"flex flex-col gap-6\">\n <MailboxTable\n collapsed={collapsed.inbox}\n mailboxType=\"inbox\"\n onSort={handleSort}\n onToggleCollapse={() => handleToggleCollapse(\"inbox\")}\n operations={channel.inbox.items}\n sort={sorts.inbox}\n title=\"Inbox\"\n />\n\n <MailboxTable\n collapsed={collapsed.outbox}\n mailboxType=\"outbox\"\n onSort={handleSort}\n onToggleCollapse={() => handleToggleCollapse(\"outbox\")}\n operations={channel.outbox.items}\n sort={sorts.outbox}\n title=\"Outbox\"\n />\n\n <MailboxTable\n collapsed={collapsed.deadLetter}\n mailboxType=\"deadLetter\"\n onSort={handleSort}\n onToggleCollapse={() => handleToggleCollapse(\"deadLetter\")}\n operations={channel.deadLetter.items}\n sort={sorts.deadLetter}\n title=\"Dead Letter\"\n />\n </div>\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport type { Remote } from \"@powerhousedao/reactor-browser\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ChannelInspector } from \"./components/channel-inspector.js\";\nimport { ConnectionStateBadge } from \"./components/connection-state-badge.js\";\nimport { SortIcon } from \"./components/sort-icon.js\";\nimport {\n type ColumnDef,\n type SortDirection,\n type SortOptions,\n truncateId,\n} from \"./utils.js\";\n\nexport type ConnectionStateSummary = {\n state: string;\n failureCount: number;\n lastSuccessUtcMs: number;\n lastFailureUtcMs: number;\n pushBlocked: boolean;\n pushFailureCount: number;\n};\n\nexport type RemotesInspectorProps = {\n readonly getRemotes: () => Promise<Remote[]>;\n readonly removeRemote?: (name: string) => Promise<void>;\n readonly addRemoteManual?: (url: string) => Promise<void>;\n readonly triggerPull?: (name: string) => void;\n readonly connectionStates?: ReadonlyMap<string, ConnectionStateSummary>;\n};\n\nconst BASE_COLUMNS: ColumnDef[] = [\n { key: \"id\", label: \"ID\", width: \"120px\" },\n { key: \"name\", label: \"Name\", width: \"150px\" },\n { key: \"status\", label: \"Status\", width: \"120px\" },\n { key: \"collectionId\", label: \"Collection ID\", width: \"200px\" },\n { key: \"filter\", label: \"Filter\", width: \"200px\" },\n { key: \"channel\", label: \"Channel\", width: \"100px\" },\n];\n\nconst ACTIONS_COLUMN: ColumnDef = {\n key: \"actions\",\n label: \"Actions\",\n width: \"100px\",\n};\n\nfunction formatFilter(filter: Remote[\"filter\"]): string {\n const parts: string[] = [];\n\n if (filter.branch) {\n parts.push(`branch:${filter.branch}`);\n }\n\n if (filter.documentId.length > 0) {\n parts.push(`${filter.documentId.length} doc(s)`);\n }\n\n if (filter.scope.length > 0) {\n parts.push(`${filter.scope.length} scope(s)`);\n }\n\n return parts.length > 0 ? parts.join(\", \") : \"-\";\n}\n\nfunction sortRemotes(\n remotes: Remote[],\n sort: SortOptions | undefined,\n): Remote[] {\n if (!sort) return remotes;\n\n return [...remotes].sort((a, b) => {\n let aValue: string;\n let bValue: string;\n\n switch (sort.column) {\n case \"id\":\n aValue = a.id;\n bValue = b.id;\n break;\n case \"name\":\n aValue = a.name;\n bValue = b.name;\n break;\n case \"collectionId\":\n aValue = a.collectionId;\n bValue = b.collectionId;\n break;\n case \"filter\":\n aValue = formatFilter(a.filter);\n bValue = formatFilter(b.filter);\n break;\n default:\n return 0;\n }\n\n const comparison = aValue.localeCompare(bValue);\n return sort.direction === \"asc\" ? comparison : -comparison;\n });\n}\n\nexport function RemotesInspector({\n getRemotes,\n removeRemote,\n addRemoteManual,\n triggerPull,\n connectionStates,\n}: RemotesInspectorProps) {\n const [remotes, setRemotes] = useState<Remote[]>([]);\n const [loading, setLoading] = useState(true);\n const [sort, setSort] = useState<SortOptions | undefined>();\n const [selectedRemote, setSelectedRemote] = useState<Remote | undefined>();\n const [manualUrl, setManualUrl] = useState(\"\");\n const [adding, setAdding] = useState(false);\n const [addError, setAddError] = useState<string | undefined>();\n\n const hasRowActions = !!removeRemote || !!triggerPull;\n const columns = useMemo(\n () => (hasRowActions ? [...BASE_COLUMNS, ACTIONS_COLUMN] : BASE_COLUMNS),\n [hasRowActions],\n );\n\n const loadRemotes = useCallback(async () => {\n setLoading(true);\n const data = await getRemotes();\n setRemotes(data);\n setLoading(false);\n }, [getRemotes]);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n void loadRemotes();\n }, [loadRemotes]);\n\n const handleRefresh = useCallback(async () => {\n await loadRemotes();\n if (selectedRemote) {\n const updated = remotes.find((r) => r.id === selectedRemote.id);\n setSelectedRemote(updated);\n }\n }, [loadRemotes, selectedRemote, remotes]);\n\n const handleSort = (columnKey: string) => {\n if (\n columnKey === \"channel\" ||\n columnKey === \"actions\" ||\n columnKey === \"status\"\n )\n return;\n\n const newDirection: SortDirection =\n sort?.column === columnKey && sort.direction === \"asc\" ? \"desc\" : \"asc\";\n\n setSort({ column: columnKey, direction: newDirection });\n };\n\n const handleViewChannel = (remote: Remote) => {\n setSelectedRemote(remote);\n };\n\n const handleRemove = useCallback(\n async (remote: Remote) => {\n if (!removeRemote) return;\n await removeRemote(remote.name);\n await loadRemotes();\n if (selectedRemote?.id === remote.id) {\n setSelectedRemote(undefined);\n }\n },\n [removeRemote, loadRemotes, selectedRemote],\n );\n\n const handleBack = () => {\n setSelectedRemote(undefined);\n };\n\n const handleAddManual = useCallback(async () => {\n if (!addRemoteManual) return;\n const url = manualUrl.trim();\n if (!url) return;\n setAdding(true);\n setAddError(undefined);\n try {\n await addRemoteManual(url);\n setManualUrl(\"\");\n await loadRemotes();\n } catch (error) {\n setAddError(error instanceof Error ? error.message : String(error));\n } finally {\n setAdding(false);\n }\n }, [addRemoteManual, manualUrl, loadRemotes]);\n\n const handlePull = useCallback(\n (remote: Remote) => {\n triggerPull?.(remote.name);\n },\n [triggerPull],\n );\n\n if (selectedRemote) {\n return (\n <ChannelInspector\n channel={selectedRemote.channel}\n connectionState={connectionStates?.get(selectedRemote.name)}\n onBack={handleBack}\n onRefresh={() => void handleRefresh()}\n remoteName={selectedRemote.name}\n />\n );\n }\n\n const sortedRemotes = sortRemotes(remotes, sort);\n\n return (\n <div className=\"flex h-full flex-col gap-2\">\n <div className=\"flex shrink-0 items-center justify-between gap-2\">\n <h2 className=\"text-lg font-semibold text-gray-900 dark:text-slate-50\">\n Remotes Inspector\n </h2>\n <div className=\"flex items-center gap-2\">\n {addRemoteManual && (\n <div className=\"flex items-center gap-1\">\n <input\n className=\"w-[260px] rounded-sm border border-gray-300 px-2 py-1.5 text-sm text-gray-900 placeholder:text-gray-400 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:placeholder:text-slate-500\"\n disabled={adding}\n onChange={(e) => setManualUrl(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") void handleAddManual();\n }}\n placeholder=\"https://reactor/d/drive-id\"\n type=\"text\"\n value={manualUrl}\n />\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={adding || !manualUrl.trim()}\n onClick={() => void handleAddManual()}\n title=\"Register a remote drive in manual poll mode (no background polling)\"\n type=\"button\"\n >\n Add (manual)\n </button>\n </div>\n )}\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={loading}\n onClick={() => void handleRefresh()}\n type=\"button\"\n >\n <Icon name=\"Reload\" size={14} />\n Refresh\n </button>\n </div>\n </div>\n {addError && (\n <div className=\"shrink-0 rounded-sm border border-red-300 bg-red-50 px-3 py-1.5 text-xs text-red-700 dark:border-red-600 dark:bg-red-900 dark:text-red-100\">\n {addError}\n </div>\n )}\n\n <div className=\"scrollbar-thin max-h-full overflow-auto rounded-lg border border-gray-300 scrollbar-thumb-gray-300 scrollbar-thumb-rounded-md scrollbar-track-transparent dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:scrollbar-thumb-slate-600\">\n <table className=\"w-full border-collapse\">\n <thead className=\"sticky top-0 bg-gray-100 dark:bg-slate-700\">\n <tr>\n {columns.map((column, index) => {\n const isActive = sort?.column === column.key;\n const sortDirection = isActive ? sort.direction : \"asc\";\n const isSortable =\n column.key !== \"channel\" &&\n column.key !== \"actions\" &&\n column.key !== \"status\";\n\n return (\n <th\n key={column.key}\n className={twMerge(\n \"group px-3 py-2 text-left text-xs font-medium text-gray-700 dark:text-slate-200\",\n index > 0 &&\n \"border-l border-gray-300 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n isSortable &&\n \"cursor-pointer hover:bg-gray-200 hover:text-gray-900 dark:hover:bg-slate-600 dark:hover:text-slate-100\",\n )}\n onClick={() => isSortable && handleSort(column.key)}\n style={{ width: column.width }}\n >\n <div className=\"flex items-center gap-1\">\n <span className=\"truncate\">{column.label}</span>\n {isSortable && (\n <SortIcon active={isActive} direction={sortDirection} />\n )}\n </div>\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {loading && sortedRemotes.length === 0 ? (\n <tr>\n <td\n className=\"px-3 py-8 text-center text-sm text-gray-500 dark:text-slate-400\"\n colSpan={columns.length}\n >\n Loading...\n </td>\n </tr>\n ) : sortedRemotes.length === 0 ? (\n <tr>\n <td\n className=\"px-3 py-8 text-center text-sm text-gray-500 dark:text-slate-400\"\n colSpan={columns.length}\n >\n No remotes configured\n </td>\n </tr>\n ) : (\n sortedRemotes.map((remote) => (\n <tr\n key={remote.id}\n className=\"odd:bg-white even:bg-gray-50 hover:bg-blue-50 dark:odd:bg-slate-800 dark:even:bg-slate-800 dark:hover:bg-blue-900\"\n >\n <td className=\"px-3 py-2 text-xs text-gray-900 dark:text-slate-50\">\n <span className=\"block truncate\" title={remote.id}>\n {truncateId(remote.id)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"block truncate\" title={remote.name}>\n {remote.name}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {connectionStates?.get(remote.name) ? (\n <ConnectionStateBadge\n failureCount={\n connectionStates.get(remote.name)!.failureCount\n }\n state={connectionStates.get(remote.name)!.state}\n />\n ) : (\n <span className=\"text-xs text-gray-400 dark:text-slate-500\">\n -\n </span>\n )}\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span\n className=\"block truncate\"\n title={remote.collectionId}\n >\n {remote.collectionId}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span\n className=\"block truncate\"\n title={formatFilter(remote.filter)}\n >\n {formatFilter(remote.filter)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <button\n className=\"flex items-center gap-1 rounded-sm bg-blue-50 px-2 py-1 text-xs text-blue-700 hover:bg-blue-100 dark:bg-blue-900 dark:text-blue-100 dark:hover:bg-blue-800\"\n onClick={() => handleViewChannel(remote)}\n type=\"button\"\n >\n View\n <Icon name=\"CaretRight\" size={12} />\n </button>\n </td>\n {hasRowActions && (\n <td className=\"border-l border-gray-300 px-3 py-2 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <div className=\"flex items-center gap-1\">\n {triggerPull && (\n <button\n className=\"rounded-sm bg-gray-100 px-2 py-1 text-xs text-gray-700 hover:bg-gray-200 dark:bg-slate-700 dark:text-slate-200 dark:hover:bg-slate-600 dark:hover:text-slate-100\"\n onClick={() => handlePull(remote)}\n title=\"Trigger a single pull cycle for this remote\"\n type=\"button\"\n >\n Pull\n </button>\n )}\n {removeRemote && (\n <button\n className=\"rounded-sm bg-red-50 px-2 py-1 text-xs text-red-700 hover:bg-red-100 dark:bg-red-900 dark:text-red-100 dark:hover:bg-red-800\"\n onClick={() => void handleRemove(remote)}\n type=\"button\"\n >\n Remove\n </button>\n )}\n </div>\n </td>\n )}\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n\n <div className=\"shrink-0 text-sm text-gray-700 dark:text-slate-200\">\n Showing {sortedRemotes.length} remote(s)\n </div>\n </div>\n );\n}\n","import type { DivProps } from \"#design-system\";\nimport { Icon, Modal } from \"#design-system\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { DBExplorer, type DBExplorerProps } from \"../../db-explorer/index.js\";\nimport {\n IntegrityInspector,\n type IntegrityInspectorProps,\n} from \"../../integrity-inspector/index.js\";\nimport {\n ProcessorsInspector,\n type ProcessorsInspectorProps,\n} from \"../../processors-inspector/index.js\";\nimport {\n QueueInspector,\n type QueueInspectorProps,\n} from \"../../queue-inspector/index.js\";\nimport {\n RemotesInspector,\n type RemotesInspectorProps,\n} from \"../../remotes-inspector/index.js\";\nimport { TabContent } from \"../../tabs/tab-content.js\";\nimport { Tabs } from \"../../tabs/tabs.js\";\n\ntype ModalProps = ComponentPropsWithoutRef<typeof Modal>;\n\nexport type InspectorModalProps = {\n readonly open: boolean;\n readonly onOpenChange: (open: boolean) => void;\n readonly modalProps?: ModalProps;\n readonly containerProps?: DivProps;\n readonly dbExplorerProps: DBExplorerProps;\n readonly remotesInspectorProps: RemotesInspectorProps;\n readonly queueInspectorProps?: QueueInspectorProps;\n readonly processorsInspectorProps?: ProcessorsInspectorProps;\n readonly integrityInspectorProps?: IntegrityInspectorProps;\n readonly defaultTab?:\n | \"Database\"\n | \"Remotes\"\n | \"Queue\"\n | \"Processors\"\n | \"Integrity\";\n};\n\nexport function InspectorModal({\n open,\n onOpenChange,\n modalProps,\n containerProps,\n dbExplorerProps,\n remotesInspectorProps,\n queueInspectorProps,\n processorsInspectorProps,\n integrityInspectorProps,\n defaultTab = \"Database\",\n}: InspectorModalProps) {\n return (\n <Modal\n {...modalProps}\n contentProps={{\n className: \"rounded-2xl\",\n style: { height: \"90vh\", width: \"90vw\", maxWidth: \"1400px\" },\n }}\n onOpenChange={onOpenChange}\n open={open}\n >\n <div\n {...containerProps}\n className={twMerge(\n \"flex size-full flex-col\",\n containerProps?.className,\n )}\n >\n <div className=\"flex shrink-0 items-center justify-end px-3 pt-3\">\n <button\n className=\"flex size-6 cursor-pointer items-center justify-center rounded-md text-gray-500 outline-none hover:text-gray-900 dark:text-slate-400 dark:hover:text-slate-50\"\n onClick={() => onOpenChange(false)}\n type=\"button\"\n >\n <Icon name=\"XmarkLight\" size={24} />\n </button>\n </div>\n\n <div className=\"flex min-h-0 flex-1 flex-col overflow-hidden px-3 pb-3\">\n <Tabs defaultValue={defaultTab}>\n <TabContent description=\"Database explorer\" label=\"Database\">\n <div className=\"h-full\">\n <DBExplorer {...dbExplorerProps} />\n </div>\n </TabContent>\n <TabContent description=\"Remotes inspector\" label=\"Remotes\">\n <div className=\"h-full\">\n <RemotesInspector {...remotesInspectorProps} />\n </div>\n </TabContent>\n {queueInspectorProps && (\n <TabContent description=\"Queue inspector\" label=\"Queue\">\n <div className=\"h-full\">\n <QueueInspector {...queueInspectorProps} />\n </div>\n </TabContent>\n )}\n {processorsInspectorProps && (\n <TabContent description=\"Processors inspector\" label=\"Processors\">\n <div className=\"h-full\">\n <ProcessorsInspector {...processorsInspectorProps} />\n </div>\n </TabContent>\n )}\n {integrityInspectorProps && (\n <TabContent description=\"Integrity inspector\" label=\"Integrity\">\n <div className=\"h-full\">\n <IntegrityInspector {...integrityInspectorProps} />\n </div>\n </TabContent>\n )}\n </Tabs>\n </div>\n </div>\n </Modal>\n );\n}\n","import type { ComponentPropsWithoutRef } from \"react\";\nimport { useState } from \"react\";\n\nimport { Modal } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\n\nconst buttonStyles =\n \"min-h-[36px] text-sm font-semibold py-2 px-4 rounded-xl outline-none active:opacity-75 hover:scale-105 transform transition-all\";\n\nexport interface PendingPackageInstallation {\n documentType: string;\n packageName: string;\n}\n\nexport type PackageInstallModalProps = ComponentPropsWithoutRef<\n typeof Modal\n> & {\n readonly pendingInstallations: PendingPackageInstallation[];\n readonly onInstall: (packageName: string) => Promise<void>;\n readonly onDismiss: (packageName: string) => void;\n};\n\ninterface GroupedInstallation {\n packageName: string;\n documentTypes: string[];\n}\n\nfunction groupByPackage(\n installations: PendingPackageInstallation[],\n): GroupedInstallation[] {\n const groups = new Map<string, string[]>();\n for (const item of installations) {\n const existing = groups.get(item.packageName) ?? [];\n existing.push(item.documentType);\n groups.set(item.packageName, existing);\n }\n return Array.from(groups.entries()).map(([packageName, documentTypes]) => ({\n packageName,\n documentTypes,\n }));\n}\n\nexport function PackageInstallModal(props: PackageInstallModalProps) {\n const {\n pendingInstallations,\n onInstall,\n onDismiss,\n open,\n onOpenChange,\n overlayProps,\n contentProps,\n ...restProps\n } = props;\n\n const [installingPackages, setInstallingPackages] = useState<Set<string>>(\n () => new Set(),\n );\n\n const grouped = groupByPackage(pendingInstallations);\n\n async function handleInstall(packageName: string) {\n setInstallingPackages((prev) => new Set(prev).add(packageName));\n try {\n await onInstall(packageName);\n } finally {\n setInstallingPackages((prev) => {\n const next = new Set(prev);\n next.delete(packageName);\n return next;\n });\n }\n }\n\n if (grouped.length === 0) return null;\n\n return (\n <Modal\n open={open ?? grouped.length > 0}\n onOpenChange={(isOpen) => {\n if (!isOpen) {\n for (const { packageName } of grouped) {\n onDismiss(packageName);\n }\n }\n onOpenChange?.(isOpen);\n }}\n contentProps={contentProps}\n overlayProps={{\n ...overlayProps,\n className: overlayProps?.className,\n }}\n {...restProps}\n >\n <div className=\"w-[460px] rounded-xl bg-gray-50 p-6 text-gray-300 dark:bg-slate-800 dark:text-slate-600\">\n <div className=\"border-b border-gray-50 pb-2 text-2xl font-bold text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {grouped.length === 1 ? \"Package Required\" : \"Packages Required\"}\n </div>\n <div className=\"my-4 text-sm text-gray-700 dark:text-slate-200\">\n {grouped.length === 1\n ? \"A document requires a package that is not installed.\"\n : \"Documents require packages that are not installed.\"}\n </div>\n <div className=\"flex flex-col gap-3\">\n {grouped.map(({ packageName, documentTypes }) => {\n const installing = installingPackages.has(packageName);\n return (\n <div\n key={packageName}\n className=\"rounded-xl bg-gray-50 p-4 dark:bg-slate-800\"\n >\n <div className=\"mb-1 text-sm font-semibold text-gray-900 dark:text-slate-100\">\n {packageName}\n </div>\n <div className=\"mb-3 text-xs text-gray-500 dark:text-slate-400\">\n Required for document type\n {documentTypes.length > 1 ? \"s\" : \"\"}:{\" \"}\n {documentTypes.join(\", \")}\n </div>\n <div className=\"flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={() => onDismiss(packageName)}\n disabled={installing}\n className={twMerge(\n buttonStyles,\n \"border border-gray-200 bg-gray-50 text-gray-800 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n installing && \"cursor-not-allowed opacity-50\",\n )}\n >\n Dismiss\n </button>\n <button\n type=\"button\"\n onClick={() => void handleInstall(packageName)}\n disabled={installing}\n className={twMerge(\n buttonStyles,\n \"bg-gray-800 text-gray-50 dark:bg-slate-100 dark:text-slate-900\",\n installing && \"cursor-not-allowed opacity-50\",\n )}\n >\n {installing ? \"Installing...\" : \"Install\"}\n </button>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n </Modal>\n );\n}\n","import type { ComponentPropsWithoutRef, ReactNode } from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { Modal } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\n\ntype ModalProps = ComponentPropsWithoutRef<typeof Modal>;\n\nexport type ReadRequiredModalProps = {\n readonly open?: boolean;\n readonly onOpenChange?: (open: boolean) => void;\n readonly header: ReactNode;\n readonly body?: ReactNode;\n readonly closeLabel: string;\n readonly onContinue: () => void;\n readonly bodyClassName?: string;\n readonly overlayProps?: ModalProps[\"overlayProps\"];\n readonly contentProps?: ModalProps[\"contentProps\"];\n};\n\nexport function ReadRequiredModal(props: ReadRequiredModalProps) {\n const {\n open,\n onOpenChange,\n header,\n body,\n closeLabel,\n onContinue,\n bodyClassName,\n overlayProps,\n contentProps,\n } = props;\n\n const [disableClose, setDisableClose] = useState(true);\n const contentRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const checkScroll = () => {\n const element = contentRef.current;\n if (element) {\n if (element.scrollHeight > element.clientHeight) {\n setDisableClose(true);\n element.addEventListener(\"scroll\", handleScroll);\n } else {\n setDisableClose(false);\n }\n }\n };\n\n const handleScroll = () => {\n const element = contentRef.current;\n if (\n element &&\n element.scrollHeight - Math.ceil(element.scrollTop) ===\n element.clientHeight\n ) {\n setDisableClose(false);\n }\n };\n\n requestAnimationFrame(checkScroll);\n\n return () => {\n const element = contentRef.current;\n if (element) {\n element.removeEventListener(\"scroll\", handleScroll);\n }\n };\n }, []);\n\n return (\n <Modal\n open={open}\n onOpenChange={onOpenChange}\n overlayProps={overlayProps}\n contentProps={contentProps}\n >\n <div className=\"w-[500px] p-6\">\n <div className=\"border-b border-gray-100 pb-2 text-2xl font-bold text-gray-900 dark:border-slate-500 dark:text-slate-100\">\n {header}\n </div>\n <div\n ref={contentRef}\n className={twMerge(\n \"my-6 max-h-[245px] overflow-scroll rounded-md bg-gray-50 p-4 text-center dark:bg-slate-700\",\n bodyClassName,\n )}\n >\n {body}\n </div>\n <div className=\"mt-8 flex justify-between gap-3\">\n <button\n disabled={disableClose}\n onClick={onContinue}\n className={twMerge(\n \"min-h-12 flex-1 transform rounded-xl px-6 py-3 text-base font-semibold transition-all outline-none hover:scale-105 active:opacity-75\",\n \"bg-gray-800 text-gray-50 dark:bg-slate-100 dark:text-slate-900\",\n disableClose &&\n \"cursor-not-allowed bg-gray-300 hover:scale-100 dark:bg-slate-600 dark:text-slate-100\",\n )}\n >\n {closeLabel}\n </button>\n </div>\n </div>\n </Modal>\n );\n}\n","import { useState } from \"react\";\nimport { Disclosure } from \"../../../disclosure/disclosure.js\";\n\nconst PH_DEPENDENCIES = [\n /^@powerhousedao\\/.+$/,\n \"document-drive\",\n \"document-model\",\n];\n\ntype ValidatedPackageJson = {\n version: string;\n dependencies: Record<string, string>;\n};\n\nexport function verifyPackageJsonFields(\n packageJson: unknown,\n): ValidatedPackageJson | false {\n try {\n const parsed = packageJson as {\n version?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n };\n const version = parsed.version || \"Missing version field in package.json\";\n const dependencies = Object.fromEntries(\n Object.entries({\n ...parsed.dependencies,\n ...parsed.devDependencies,\n ...parsed.peerDependencies,\n }).filter(([key]) =>\n PH_DEPENDENCIES.some((regexOrName) =>\n typeof regexOrName === \"string\"\n ? regexOrName === key\n : regexOrName.test(key),\n ),\n ),\n );\n return { version, dependencies };\n } catch (error) {\n console.error(error);\n return false;\n }\n}\n\ntype Props = {\n readonly packageJson: unknown;\n readonly phCliVersion?: string;\n};\n\nexport function DependencyVersions(props: Props) {\n const [isOpen, setIsOpen] = useState(false);\n const { packageJson, phCliVersion } = props;\n\n const validatedData = verifyPackageJsonFields(packageJson);\n if (!validatedData) {\n console.error(\"Failed to validate package.json data\");\n return null;\n }\n\n return (\n <Disclosure\n isOpen={isOpen}\n onOpenChange={() => setIsOpen(!isOpen)}\n title={`App version: ${validatedData.version}`}\n toggleClassName=\"text-gray-900 text-sm dark:text-slate-50\"\n >\n <ul className=\"text-sm text-gray-700 dark:text-slate-200\">\n {Object.entries(validatedData.dependencies).map(([dep, version]) => (\n <li key={dep} className=\"my-1 flex justify-between pr-1\">\n <span>{dep.replace(\"@powerhousedao/\", \"\")}:</span>\n <span className=\"font-normal\">{version}</span>\n </li>\n ))}\n {phCliVersion && (\n <li className=\"my-1 flex justify-between pr-1\" key=\"ph-cli\">\n <span>@powerhousedao/ph-cli:</span>\n <span className=\"font-normal\">{phCliVersion}</span>\n </li>\n )}\n </ul>\n </Disclosure>\n );\n}\n","import { DependencyVersions } from \"../settings-modal/dependency-versions/dependency-versions.js\";\n\ntype Props = {\n packageJson: unknown;\n phCliVersion?: string;\n};\nexport function About(props: Props) {\n const { packageJson, phCliVersion } = props;\n return (\n <div className=\"bg-gray-50 p-3 dark:bg-slate-800\">\n <h2 className=\"font-semibold text-gray-900 dark:text-slate-100\">About</h2>\n <p className=\"text-sm font-normal text-gray-700 dark:text-slate-200\">\n Connect is the hub for your most important documents and processes\n translated into software. Easily capture data in a structured way with\n Connect.\n </p>\n <div className=\"my-4\">\n <DependencyVersions\n packageJson={packageJson}\n phCliVersion={phCliVersion}\n />\n </div>\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\nimport type {\n DocumentDriveDocument,\n SharingType,\n} from \"@powerhousedao/shared/document-drive\";\nimport { capitalCase } from \"change-case\";\nimport { useState } from \"react\";\nimport { ConnectDropdownMenu } from \"../../dropdown-menu/dropdown-menu.js\";\n\nfunction getDriveSharingType(drive: DocumentDriveDocument): SharingType {\n if (typeof drive !== \"object\") return \"LOCAL\";\n const isReadDrive = \"readContext\" in drive;\n const { sharingType: _sharingType } = !isReadDrive\n ? drive.state.local\n : { sharingType: \"PUBLIC\" };\n const __sharingType = _sharingType?.toUpperCase();\n const validTypes: string[] = [\"LOCAL\", \"CLOUD\", \"PUBLIC\"];\n return !__sharingType ||\n __sharingType === \"PRIVATE\" ||\n !validTypes.includes(__sharingType)\n ? \"LOCAL\"\n : (__sharingType as SharingType);\n}\n\ntype ModifyDrivesProps = {\n drives: DocumentDriveDocument[];\n onDeleteDrive: (drive: DocumentDriveDocument) => void;\n className?: string;\n};\n\ntype LocalStorageProps = {\n onClearStorage: () => void | Promise<void>;\n className?: string;\n};\n\ntype Props = ModifyDrivesProps & LocalStorageProps;\n\nexport function DangerZone(props: Props) {\n const { className, ...rest } = props;\n return (\n <div\n className={twMerge(\n \"h-full rounded-lg bg-gray-50 p-3 dark:bg-slate-800\",\n className,\n )}\n >\n <h2 className=\"mb-4 font-semibold text-gray-900 dark:text-slate-100\">\n Modify Drives\n </h2>\n <ModifyDrives {...rest} />\n <h2 className=\"my-4 font-semibold text-gray-900 dark:text-slate-100\">\n Local Storage\n </h2>\n <LocalStorage {...rest} />\n </div>\n );\n}\n\nfunction ModifyDrives(props: ModifyDrivesProps) {\n const { className, ...rest } = props;\n return (\n <div className={className}>\n <DriveList {...rest} />\n </div>\n );\n}\n\nfunction DriveList(props: ModifyDrivesProps) {\n const { className, ...rest } = props;\n return (\n <div className={className}>\n {props.drives.map((drive) => (\n <Drive key={drive.header.id} drive={drive} {...rest} />\n ))}\n </div>\n );\n}\n\nfunction Drive(props: ModifyDrivesProps & { drive: DocumentDriveDocument }) {\n const { drive, className, onDeleteDrive } = props;\n const [isDropdownMenuOpen, setIsDropdownMenuOpen] = useState(false);\n const localDriveIcon = <Icon name=\"Hdd\" size={16} className=\"flex-none\" />;\n\n const cloudDriveIcon = <Icon name=\"Server\" size={16} className=\"flex-none\" />;\n\n const publicDriveIcon = drive.state.global.icon ? (\n <img\n alt=\"drive icon\"\n className=\"size-4 flex-none object-contain\"\n src={drive.state.global.icon}\n />\n ) : (\n <Icon name=\"Server\" size={16} className=\"flex-none\" />\n );\n\n function getNodeIcon() {\n const sharingType = getDriveSharingType(drive);\n if (sharingType === \"PUBLIC\") {\n return publicDriveIcon;\n }\n if (sharingType === \"CLOUD\") {\n return cloudDriveIcon;\n }\n return localDriveIcon;\n }\n\n const icon = getNodeIcon();\n\n return (\n <div\n className={twMerge(\n \"mb-4 flex w-96 items-center gap-2 rounded-md border border-gray-200 bg-gray-50 px-3 py-2 text-gray-900 shadow-sm last-of-type:mb-0 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n className,\n )}\n >\n {icon}\n <div>\n <span className=\"block text-sm/4.5 font-medium\">\n {capitalCase(drive.header.name)}\n </span>\n <div className=\"flex items-baseline gap-x-2 leading-4.5\">\n <span className=\"text-sm text-gray-700 dark:text-slate-200\">\n {capitalCase(getDriveSharingType(drive))} App\n </span>\n <a\n href=\"https://www.powerhouse.inc/\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"group flex items-center gap-x-2 text-sm text-gray-500 transition-colors hover:text-purple-700 dark:text-slate-500 dark:hover:text-purple-100\"\n >\n By Powerhouse\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 12 12\"\n className=\"size-4 text-gray-400 transition-colors group-hover:text-inherit dark:text-slate-500\"\n >\n <path\n d=\"M7.99365 11.9939C9.46632 11.9939 10.6603 10.7999 10.6603 9.32722V7.32722C10.6603 6.95922 10.3617 6.66056 9.99365 6.66056C9.62565 6.66056 9.32699 6.95922 9.32699 7.32722V9.32722C9.32699 10.0639 8.73032 10.6606 7.99365 10.6606H2.66032C1.92365 10.6606 1.32699 10.0639 1.32699 9.32722V3.99389C1.32699 3.25723 1.92365 2.66056 2.66032 2.66056H4.66032C5.02832 2.66056 5.32699 2.36189 5.32699 1.99389C5.32699 1.6259 5.02832 1.32723 4.66032 1.32723H2.66032C1.18765 1.32723 -0.00634766 2.52123 -0.00634766 3.99389V9.32722C-0.00634766 10.7999 1.18765 11.9939 2.66032 11.9939H7.99365ZM5.32699 7.32722C5.49765 7.32722 5.67565 7.26989 5.80632 7.13989L10.1396 2.80656L11.9937 4.66056V-0.00610352H7.32699L9.18099 1.8479L4.84766 6.18123C4.58766 6.4419 4.58766 6.87922 4.84766 7.13989C4.97832 7.26989 5.15632 7.32722 5.32699 7.32722Z\"\n fill=\"currentColor\"\n />\n </svg>\n </a>\n </div>\n </div>\n <ConnectDropdownMenu\n items={[\n {\n id: \"delete-drive\",\n label: \"Delete\",\n icon: <Icon name=\"Trash\" />,\n className: \"text-red-900 dark:text-red-400\",\n },\n ]}\n onItemClick={(id) => {\n if (id === \"delete-drive\") {\n onDeleteDrive(drive);\n }\n }}\n onOpenChange={setIsDropdownMenuOpen}\n open={isDropdownMenuOpen}\n >\n <button\n className=\"group ml-auto flex-none\"\n onClick={(e) => {\n e.stopPropagation();\n setIsDropdownMenuOpen(true);\n }}\n >\n <Icon\n className=\"text-gray-700 group-hover:text-gray-900 dark:text-slate-200 dark:group-hover:text-slate-50\"\n name=\"VerticalDots\"\n size={16}\n />\n </button>\n </ConnectDropdownMenu>\n </div>\n );\n}\n\nfunction LocalStorage(props: LocalStorageProps) {\n const { onClearStorage } = props;\n return (\n <div>\n <button\n className=\"flex items-center gap-x-2 rounded-md border border-gray-300 bg-transparent px-3 py-1 text-sm font-medium text-red-900 transition-colors hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={() => void onClearStorage()}\n >\n Clear Storage <Icon name=\"Trash\" size={16} />\n </button>\n </div>\n );\n}\n","import type { SelectOption } from \"#design-system/ui\";\nimport { SelectFieldRaw } from \"#design-system/ui\";\nimport { twMerge } from \"tailwind-merge\";\n\ntype Props = {\n documentModelEditor: string;\n setDocumentModelEditor: (value: string) => void;\n documentModelEditorOptions: SelectOption[];\n className?: string;\n};\n\nexport function DefaultEditor(props: Props) {\n const { className, ...rest } = props;\n return (\n <div\n className={twMerge(\n \"rounded-lg bg-gray-50 p-3 dark:bg-slate-800\",\n className,\n )}\n >\n <DefaultEditorSelect {...rest} />\n </div>\n );\n}\n\nexport function DefaultEditorSelect(props: Props) {\n const {\n documentModelEditor,\n setDocumentModelEditor,\n documentModelEditorOptions,\n className,\n } = props;\n\n return (\n <div>\n <h3 className=\"mb-4 font-semibold text-gray-900 dark:text-slate-50\">\n Default Editor Selection\n </h3>\n <SelectFieldRaw\n className={twMerge(\"max-w-fit min-w-36\", className)}\n name=\"default-editor\"\n required\n value={documentModelEditor}\n options={documentModelEditorOptions}\n multiple={false}\n onChange={(value) => setDocumentModelEditor(value as string)}\n />\n </div>\n );\n}\n","/**\n * Parse a package specifier into a bare name and an optional tag/version.\n *\n * - Scoped names split on the LAST `@` (since the name itself starts with\n * `@scope/`): `@scope/pkg@dev` → `{ name: \"@scope/pkg\", tag: \"dev\" }`.\n * - Unscoped names split on the first `@`: `pkg@1.2.3` →\n * `{ name: \"pkg\", tag: \"1.2.3\" }`.\n * - A bare name (no separator) returns `{ name, tag: undefined }`.\n * - Trailing/leading whitespace is trimmed; an empty tag (e.g. \"pkg@\")\n * is treated as missing.\n */\nexport function parsePackageSpec(spec: string): {\n name: string;\n tag: string | undefined;\n} {\n const trimmed = spec.trim();\n if (trimmed.length === 0) return { name: \"\", tag: undefined };\n\n const splitAt = trimmed.startsWith(\"@\")\n ? trimmed.lastIndexOf(\"@\")\n : trimmed.indexOf(\"@\");\n\n if (splitAt > 0) {\n const name = trimmed.slice(0, splitAt);\n const tag = trimmed.slice(splitAt + 1);\n return { name, tag: tag.length > 0 ? tag : undefined };\n }\n\n return { name: trimmed, tag: undefined };\n}\n\n/**\n * Compose a spec string from a name and optional tag/version. Used by\n * callers that want to re-serialize what `parsePackageSpec` parsed.\n */\nexport function buildPackageSpec(name: string, tag?: string): string {\n return tag ? `${name}@${tag}` : name;\n}\n","import { Icon } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\nimport {\n Input,\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"#design-system/ui\";\nimport { useMemo, useState } from \"react\";\n\nexport type VersionSelection =\n | { kind: \"tag\"; value: string }\n | { kind: \"version\"; value: string };\n\nexport interface VersionPickerProps {\n distTags?: Record<string, string>;\n versions?: string[];\n selected: VersionSelection;\n onChange: (next: VersionSelection) => void;\n disabled?: boolean;\n className?: string;\n}\n\nexport function resolveDefaultVersionSelection(options: {\n distTags?: Record<string, string>;\n versions?: string[];\n version?: string;\n preferredTag?: string;\n}): VersionSelection {\n const { distTags, versions, version, preferredTag } = options;\n\n if (preferredTag && distTags && preferredTag in distTags) {\n return { kind: \"tag\", value: preferredTag };\n }\n if (distTags?.latest) {\n return { kind: \"tag\", value: \"latest\" };\n }\n const firstTag = distTags ? Object.keys(distTags)[0] : undefined;\n if (firstTag) {\n return { kind: \"tag\", value: firstTag };\n }\n if (versions && versions.length > 0) {\n return { kind: \"version\", value: versions[versions.length - 1] };\n }\n return { kind: \"tag\", value: version ?? \"latest\" };\n}\n\nexport const VersionPicker: React.FC<VersionPickerProps> = (props) => {\n const { distTags, versions, selected, onChange, disabled, className } = props;\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState(\"\");\n\n const tagEntries = useMemo(\n () => (distTags ? Object.entries(distTags) : []),\n [distTags],\n );\n\n const filteredTags = useMemo(() => {\n const needle = query.trim().toLowerCase();\n if (!needle) return tagEntries;\n return tagEntries.filter(\n ([tag, ver]) =>\n tag.toLowerCase().includes(needle) ||\n ver.toLowerCase().includes(needle),\n );\n }, [tagEntries, query]);\n\n const filteredVersions = useMemo(() => {\n const all = versions ?? [];\n const needle = query.trim().toLowerCase();\n if (!needle) return all.slice().reverse();\n return all.filter((v) => v.toLowerCase().includes(needle)).reverse();\n }, [versions, query]);\n\n const hasAnyPickable = tagEntries.length > 0 || (versions?.length ?? 0) > 0;\n\n const triggerLabel = selected.value;\n\n return (\n <Popover\n open={open && !disabled}\n onOpenChange={(next) => {\n setOpen(next);\n if (!next) setQuery(\"\");\n }}\n >\n <PopoverTrigger\n disabled={disabled || !hasAnyPickable}\n className={twMerge(\n \"flex items-center justify-between gap-2 rounded-md border border-gray-300 bg-gray-50 px-2.5 py-1 text-xs font-medium text-gray-900 transition-colors dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n \"hover:bg-gray-50 focus:ring-2 focus:ring-gray-900/20 focus:outline-none dark:hover:bg-slate-800\",\n \"disabled:cursor-not-allowed disabled:opacity-60\",\n className,\n )}\n data-version-picker-trigger\n >\n <span className=\"truncate\">{triggerLabel}</span>\n <Icon\n name=\"ChevronDown\"\n size={12}\n className=\"shrink-0 text-gray-500 dark:text-slate-400\"\n />\n </PopoverTrigger>\n <PopoverContent\n data-version-picker\n align=\"start\"\n sideOffset={4}\n className=\"w-56 p-0\"\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <div className=\"border-b border-gray-200 p-2 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <div className=\"relative\">\n <Icon\n name=\"Search\"\n size={14}\n className=\"absolute top-1/2 left-2 -translate-y-1/2 text-gray-400 dark:text-slate-500\"\n />\n <Input\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder=\"Search versions...\"\n className=\"h-8 pl-7 text-xs\"\n />\n </div>\n </div>\n <div className=\"max-h-60 overflow-y-auto py-1\">\n {filteredTags.length === 0 && filteredVersions.length === 0 && (\n <p className=\"px-3 py-4 text-center text-xs text-gray-500 dark:text-slate-400\">\n No matches.\n </p>\n )}\n {filteredTags.length > 0 && (\n <div className=\"pb-1\">\n <p className=\"px-3 py-1 text-xs font-semibold tracking-wide text-gray-500 uppercase dark:text-slate-400\">\n Tags\n </p>\n {filteredTags.map(([tag, ver]) => {\n const isSelected =\n selected.kind === \"tag\" && selected.value === tag;\n return (\n <button\n key={`tag:${tag}`}\n type=\"button\"\n onClick={() => {\n onChange({ kind: \"tag\", value: tag });\n setOpen(false);\n setQuery(\"\");\n }}\n className={twMerge(\n \"flex w-full items-center justify-between gap-2 px-3 py-1.5 text-left text-xs transition-colors\",\n \"hover:bg-gray-100 dark:hover:bg-slate-700\",\n isSelected &&\n \"bg-gray-100 font-semibold dark:bg-slate-700\",\n )}\n >\n <span className=\"truncate text-gray-900 dark:text-slate-50\">\n {tag}\n </span>\n <span className=\"truncate text-gray-500 dark:text-slate-400\">\n {ver}\n </span>\n </button>\n );\n })}\n </div>\n )}\n {filteredVersions.length > 0 && (\n <div>\n <p className=\"px-3 py-1 text-xs font-semibold tracking-wide text-gray-500 uppercase dark:text-slate-400\">\n Versions\n </p>\n {filteredVersions.map((ver) => {\n const isSelected =\n selected.kind === \"version\" && selected.value === ver;\n return (\n <button\n key={`ver:${ver}`}\n type=\"button\"\n onClick={() => {\n onChange({ kind: \"version\", value: ver });\n setOpen(false);\n setQuery(\"\");\n }}\n className={twMerge(\n \"flex w-full items-center px-3 py-1.5 text-left text-xs transition-colors\",\n \"hover:bg-gray-100 dark:hover:bg-slate-700\",\n isSelected &&\n \"bg-gray-100 font-semibold dark:bg-slate-700\",\n )}\n >\n <span className=\"truncate text-gray-900 dark:text-slate-50\">\n {ver}\n </span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n );\n};\n","import { PackageAnimation } from \"#design-system\";\nimport type {\n SearchAutocompleteOption,\n SearchAutocompleteRowContext,\n} from \"#design-system/ui\";\nimport { SearchAutocomplete } from \"#design-system/ui\";\nimport type { RegistryPackageList } from \"@powerhousedao/shared/registry\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { buildPackageSpec, parsePackageSpec } from \"./parse-package-spec.js\";\nimport type { VersionSelection } from \"./version-picker.js\";\nimport {\n VersionPicker,\n resolveDefaultVersionSelection,\n} from \"./version-picker.js\";\n\nexport type PackageManagerInputProps = {\n registryPackageList: RegistryPackageList;\n onInstall: (packageSpec: string) => Promise<void>;\n disabled?: boolean;\n className?: string;\n};\n\nconst NPM_NAME_RE =\n /^@[a-z0-9][a-z0-9._-]*\\/[a-z0-9][a-z0-9._-]*$|^[a-z0-9][a-z0-9._-]*$/i;\n\nfunction isPlausiblePackageName(name: string): boolean {\n return name.length >= 2 && NPM_NAME_RE.test(name);\n}\n\ntype PackageResultCardProps = {\n option: SearchAutocompleteOption;\n ctx: SearchAutocompleteRowContext;\n typedTag: string | undefined;\n};\n\nfunction PackageResultCard(props: PackageResultCardProps) {\n const { option, ctx, typedTag } = props;\n const { selectingValue, selectLabel, selectingContent, handleSelect } = ctx;\n\n const baseName = option.label.split(\" @ \")[0] ?? option.value;\n const hasVersionMetadata =\n (option.distTags && Object.keys(option.distTags).length > 0) ||\n (option.versions?.length ?? 0) > 0;\n\n const [selected, setSelected] = useState<VersionSelection>(() =>\n resolveDefaultVersionSelection({\n distTags: option.distTags,\n versions: option.versions,\n version: option.version,\n preferredTag: typedTag,\n }),\n );\n\n // Re-sync when the typed tag changes (e.g. user edits the search query).\n // We track `typedTag` so typing `pkg@dev` pre-selects the `dev` chip.\n useEffect(() => {\n if (!typedTag) return;\n if (option.distTags && typedTag in option.distTags) {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setSelected({ kind: \"tag\", value: typedTag });\n } else if (option.versions?.includes(typedTag)) {\n setSelected({ kind: \"version\", value: typedTag });\n }\n }, [typedTag, option.distTags, option.versions]);\n\n // npm-fallback and other metadata-less rows: trust the option's prebuilt\n // spec (which already encodes any typed tag) and skip the picker entirely.\n const installSpec = hasVersionMetadata\n ? buildPackageSpec(baseName, selected.value)\n : option.value;\n const isSelecting = selectingValue === installSpec;\n const isDisabled = option.disabled === true;\n\n return (\n <div className=\"flex items-start justify-between gap-3 rounded-md p-2 hover:bg-gray-50 dark:hover:bg-slate-800\">\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium text-gray-900 dark:text-slate-50\">\n {baseName}\n </p>\n {option.description && (\n <p className=\"truncate text-xs text-gray-700 dark:text-slate-200\">\n {option.description}\n </p>\n )}\n {option.meta && (\n <p className=\"truncate text-xs text-gray-700 dark:text-slate-200\">\n {option.meta}\n </p>\n )}\n {hasVersionMetadata && (\n <div className=\"mt-2\">\n <VersionPicker\n distTags={option.distTags}\n versions={option.versions}\n selected={selected}\n onChange={setSelected}\n disabled={isDisabled}\n />\n </div>\n )}\n </div>\n <div className=\"shrink-0 self-center\">\n {isSelecting && selectingContent ? (\n <div className=\"flex items-center justify-center\">\n {selectingContent}\n </div>\n ) : isDisabled ? (\n <span className=\"rounded-md bg-gray-100 px-3 py-1 text-xs font-medium text-gray-500 dark:bg-slate-700 dark:text-slate-400\">\n {option.disabledLabel ?? \"Unavailable\"}\n </span>\n ) : (\n <button\n onClick={() => handleSelect(installSpec)}\n disabled={isSelecting}\n className=\"rounded-md bg-gray-900 px-3 py-1 text-xs font-medium text-white transition-colors hover:bg-gray-800 disabled:opacity-50 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-100\"\n >\n {isSelecting ? \"...\" : selectLabel}\n </button>\n )}\n </div>\n </div>\n );\n}\n\nexport const PackageManagerInput: React.FC<PackageManagerInputProps> = (\n props,\n) => {\n const { registryPackageList, onInstall, disabled, className } = props;\n const [typedTag, setTypedTag] = useState<string | undefined>(undefined);\n\n const fetchOptions = async (\n query: string,\n ): Promise<SearchAutocompleteOption[]> => {\n const { name: namePart, tag } = parsePackageSpec(query);\n setTypedTag(tag);\n const needle = namePart.toLowerCase();\n\n const localOptions: SearchAutocompleteOption[] = registryPackageList\n .filter(\n (pkg) =>\n pkg.name.toLowerCase().includes(needle) ||\n pkg.manifest?.description?.toLowerCase().includes(needle),\n )\n .map((pkg) => {\n const isInstalled =\n pkg.status === \"local-install\" || pkg.status === \"registry-install\";\n return {\n // `value` carries the default install spec; the row overrides it\n // with the version picker's current selection at click time.\n value: pkg.name,\n label: pkg.name,\n version: pkg.version,\n description: pkg.manifest?.description,\n meta: pkg.manifest?.publisher?.name,\n disabled: isInstalled,\n disabledLabel: isInstalled ? \"Installed\" : undefined,\n distTags: pkg.distTags,\n versions: pkg.versions,\n };\n });\n\n if (!isPlausiblePackageName(namePart) || localOptions.length > 0) {\n return Promise.resolve(localOptions);\n }\n\n const fallbackSpec = buildPackageSpec(namePart, tag);\n const fallbackLabel = tag ? `${namePart} @ ${tag}` : namePart;\n const fallbackOption: SearchAutocompleteOption = {\n value: fallbackSpec,\n label: fallbackLabel,\n version: tag,\n description:\n \"Not published to this registry. Install via the npmjs.org uplink.\",\n meta: \"npm fallback\",\n };\n return Promise.resolve([fallbackOption]);\n };\n\n const handleSelect = useCallback(\n (value: string) => {\n return onInstall(value);\n },\n [onInstall],\n );\n\n const renderRow = useCallback(\n (option: SearchAutocompleteOption, ctx: SearchAutocompleteRowContext) => (\n <PackageResultCard option={option} ctx={ctx} typedTag={typedTag} />\n ),\n [typedTag],\n );\n\n return (\n <div className={className}>\n <h3 className=\"mb-4 font-semibold text-gray-900 dark:text-slate-50\">\n Install Package\n </h3>\n <SearchAutocomplete\n fetchOptions={fetchOptions}\n onSelect={handleSelect}\n selectLabel=\"Install\"\n selectingContent={\n <PackageAnimation animate loop color=\"#6b7280\" size={48} />\n }\n placeholder=\"Search packages (e.g. my-pkg, my-pkg@dev, my-pkg@1.2.3)...\"\n disabled={disabled}\n renderRow={renderRow}\n keepOpenSelector=\"[data-version-picker],[data-version-picker-trigger]\"\n />\n </div>\n );\n};\n","import { Icon } from \"#design-system\";\nimport type {\n RegistryPackage,\n RegistryPackageList,\n} from \"@powerhousedao/shared/registry\";\nimport type { ReactNode } from \"react\";\nimport { useCallback, useEffect, useLayoutEffect, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ConnectDropdownMenu } from \"../../../dropdown-menu/dropdown-menu.js\";\nimport { buildPackageSpec } from \"./parse-package-spec.js\";\nimport type { VersionSelection } from \"./version-picker.js\";\nimport {\n resolveDefaultVersionSelection,\n VersionPicker,\n} from \"./version-picker.js\";\n\nconst PackageDetail: React.FC<{ label: string; value: ReactNode }> = ({\n label,\n value,\n}) => {\n return (\n <div className=\"flex items-start gap-2 text-sm\">\n <p className=\"text-gray-700 dark:text-slate-200\">{label}:</p>\n <p className=\"text-gray-700 dark:text-slate-200\">{value}</p>\n </div>\n );\n};\n\nexport const PackageManagerListItem = (props: {\n registryPackage: RegistryPackage;\n onInstall: (packageSpec: string) => Promise<void>;\n onUninstall: (packageName: string) => void;\n className?: string;\n}) => {\n const { registryPackage, onInstall, onUninstall, className } = props;\n const [isDropdownMenuOpen, setIsDropdownMenuOpen] = useState(false);\n\n const canPickVersion =\n registryPackage.status === \"available\" ||\n registryPackage.status === \"dismissed\";\n const hasVersionMetadata =\n (registryPackage.distTags &&\n Object.keys(registryPackage.distTags).length > 0) ||\n (registryPackage.versions?.length ?? 0) > 0;\n\n const [selected, setSelected] = useState<VersionSelection>(() =>\n resolveDefaultVersionSelection({\n distTags: registryPackage.distTags,\n versions: registryPackage.versions,\n version: registryPackage.version,\n }),\n );\n\n const installDropdownItem = {\n id: \"install\",\n label: \"Install\",\n icon: <Icon name=\"DownloadFile\" />,\n className: \"text-gray-900 dark:text-slate-100\",\n } as const;\n\n const uninstallDropdownItem = {\n id: \"uninstall\",\n label: \"Uninstall\",\n icon: <Icon name=\"Trash\" />,\n className: \"text-red-900 dark:text-red-400\",\n } as const;\n\n function getDropdownItems() {\n return [\n canPickVersion ? installDropdownItem : undefined,\n registryPackage.status === \"registry-install\"\n ? uninstallDropdownItem\n : undefined,\n ].filter((item) => item !== undefined);\n }\n\n const dropdownItems = getDropdownItems();\n return (\n <li\n className={twMerge(\n \"relative flex flex-col items-start rounded-md border border-gray-200 bg-gray-50 p-3 text-sm/5 shadow-sm dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n className,\n )}\n >\n <div className=\"flex flex-wrap items-center gap-2 pr-8\">\n <h3 className=\"font-semibold text-gray-900 dark:text-slate-50\">\n {registryPackage.name}\n </h3>\n {canPickVersion && hasVersionMetadata ? (\n <VersionPicker\n distTags={registryPackage.distTags}\n versions={registryPackage.versions}\n selected={selected}\n onChange={setSelected}\n />\n ) : registryPackage.version ? (\n <span className=\"text-xs font-normal text-gray-500 dark:text-slate-400\">\n v{registryPackage.version}\n </span>\n ) : null}\n </div>\n {registryPackage.manifest !== null &&\n (() => {\n const { description, category, publisher } = registryPackage.manifest;\n const hasAnyField =\n description != null ||\n category != null ||\n publisher?.name != null ||\n publisher?.url != null;\n if (!hasAnyField) return null;\n return (\n <>\n {description != null && (\n <PackageDetail label=\"Description\" value={description} />\n )}\n {category != null && (\n <PackageDetail label=\"Category\" value={category} />\n )}\n {publisher?.name != null && (\n <PackageDetail label=\"Publisher\" value={publisher.name} />\n )}\n {publisher?.url != null && (\n <PackageDetail\n label=\"Publisher URL\"\n value={\n <a className=\"underline\" href={publisher.url}>\n {publisher.url}\n </a>\n }\n />\n )}\n </>\n );\n })()}\n <ConnectDropdownMenu\n items={dropdownItems}\n onItemClick={(id) => {\n if (id === \"install\") {\n const spec =\n canPickVersion && hasVersionMetadata\n ? buildPackageSpec(registryPackage.name, selected.value)\n : registryPackage.name;\n onInstall(spec).catch(console.error);\n return;\n }\n onUninstall(registryPackage.name);\n }}\n onOpenChange={setIsDropdownMenuOpen}\n open={isDropdownMenuOpen}\n >\n <button\n className=\"group absolute top-3 right-3\"\n onClick={(e) => {\n e.stopPropagation();\n setIsDropdownMenuOpen(true);\n }}\n >\n <Icon\n className=\"text-gray-700 group-hover:text-gray-900 dark:text-slate-200 dark:group-hover:text-slate-50\"\n name=\"VerticalDots\"\n />\n </button>\n </ConnectDropdownMenu>\n </li>\n );\n};\n\nexport const PackageManagerList = (props: {\n registryPackageList: RegistryPackageList;\n onInstall: (packageSpec: string) => Promise<void>;\n onUninstall: (packageName: string) => void;\n className?: string;\n}) => {\n const { className, registryPackageList, onInstall, onUninstall } = props;\n const [maxHeight, setMaxHeight] = useState<number | undefined>();\n\n const locallyInstalledPackages = registryPackageList.filter(\n (p) => p.status === \"local-install\",\n );\n const registryInstalledPackages = registryPackageList.filter(\n (p) => p.status === \"registry-install\",\n );\n const availablePackages = registryPackageList.filter(\n (p) => p.status === \"available\",\n );\n const dismissedPackages = registryPackageList.filter(\n (p) => p.status === \"dismissed\",\n );\n\n useLayoutEffect(() => {\n const calculateMaxHeight = () => {\n const viewportHeight = window.innerHeight;\n const availableHeight = viewportHeight - 516;\n setMaxHeight(Math.max(200, availableHeight));\n };\n\n calculateMaxHeight();\n\n window.addEventListener(\"resize\", calculateMaxHeight);\n return () => window.removeEventListener(\"resize\", calculateMaxHeight);\n }, []);\n\n const hasLocallyInstalled = locallyInstalledPackages.length > 0;\n const hasRegistryInstalled = registryInstalledPackages.length > 0;\n const hasAnyInstalled = hasLocallyInstalled || hasRegistryInstalled;\n const hasAvailable = availablePackages.length > 0;\n const hasDismissed = dismissedPackages.length > 0;\n const installedCount =\n locallyInstalledPackages.length + registryInstalledPackages.length;\n\n return (\n <div\n className={twMerge(\n \"flex flex-col items-stretch overflow-hidden\",\n className,\n )}\n style={{ maxHeight }}\n >\n <div className=\"flex-1 overflow-y-auto pr-2\">\n <PackageSection\n sectionId=\"installed\"\n title=\"Installed Packages\"\n count={installedCount}\n isEmpty={!hasAnyInstalled}\n emptyText=\"No packages installed.\"\n >\n {hasLocallyInstalled && (\n <PackageSubSection\n title=\"Locally installed\"\n count={locallyInstalledPackages.length}\n >\n <PackageList\n packages={locallyInstalledPackages}\n onInstall={onInstall}\n onUninstall={onUninstall}\n />\n </PackageSubSection>\n )}\n {hasRegistryInstalled && (\n <PackageSubSection\n title=\"Installed from registry\"\n count={registryInstalledPackages.length}\n >\n <PackageList\n packages={registryInstalledPackages}\n onInstall={onInstall}\n onUninstall={onUninstall}\n />\n </PackageSubSection>\n )}\n </PackageSection>\n\n <PackageSection\n sectionId=\"available\"\n title=\"Available Packages\"\n count={availablePackages.length}\n isEmpty={!hasAvailable}\n emptyText=\"No packages available to install.\"\n >\n <PackageList\n packages={availablePackages}\n onInstall={onInstall}\n onUninstall={onUninstall}\n />\n </PackageSection>\n\n {hasDismissed && (\n <PackageSection\n sectionId=\"dismissed\"\n title=\"Dismissed Packages\"\n count={dismissedPackages.length}\n >\n <PackageList\n packages={dismissedPackages}\n onInstall={onInstall}\n onUninstall={onUninstall}\n />\n </PackageSection>\n )}\n </div>\n </div>\n );\n};\n\nconst STORAGE_KEY = \"ph:package-manager:collapsed-sections\";\n\nfunction loadCollapsedSections(): Record<string, boolean> {\n if (typeof window === \"undefined\") return {};\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n return raw ? (JSON.parse(raw) as Record<string, boolean>) : {};\n } catch {\n return {};\n }\n}\n\nfunction useCollapsedSection(sectionId: string): [boolean, () => void] {\n const [collapsed, setCollapsed] = useState<boolean>(\n () => loadCollapsedSections()[sectionId] ?? true,\n );\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n try {\n const current = loadCollapsedSections();\n current[sectionId] = collapsed;\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(current));\n } catch {\n // ignore persistence errors\n }\n }, [sectionId, collapsed]);\n\n const toggle = useCallback(() => setCollapsed((prev) => !prev), []);\n return [collapsed, toggle];\n}\n\nconst PackageSection: React.FC<{\n sectionId: string;\n title: string;\n count: number;\n isEmpty?: boolean;\n emptyText?: string;\n children?: ReactNode;\n}> = ({ sectionId, title, count, isEmpty, emptyText, children }) => {\n const [collapsed, toggle] = useCollapsedSection(sectionId);\n const contentId = `package-section-${sectionId}`;\n\n return (\n <section className=\"mb-6\">\n <h3 className=\"sticky top-0 z-10 mb-3 border-b border-gray-200 bg-gray-50 text-gray-900 dark:border-slate-600 dark:bg-slate-800 dark:text-slate-100\">\n <button\n type=\"button\"\n onClick={toggle}\n aria-expanded={!collapsed}\n aria-controls={contentId}\n className=\"flex w-full items-center gap-2 pb-2 text-left text-base font-semibold text-gray-900 hover:text-gray-700 dark:text-slate-100 dark:hover:text-slate-200\"\n >\n <Icon\n name=\"ChevronDown\"\n size={16}\n className={twMerge(\n \"shrink-0 text-gray-700 transition-transform dark:text-slate-200\",\n collapsed && \"-rotate-90\",\n )}\n />\n <span>{title}</span>\n <span className=\"text-xs font-medium text-gray-700 dark:text-slate-200\">\n {count}\n </span>\n </button>\n </h3>\n {!collapsed && (\n <div id={contentId}>\n {isEmpty ? (\n <p className=\"text-sm text-gray-700 dark:text-slate-200\">\n {emptyText}\n </p>\n ) : (\n <div className=\"flex flex-col gap-4\">{children}</div>\n )}\n </div>\n )}\n </section>\n );\n};\n\nconst PackageSubSection: React.FC<{\n title: string;\n count: number;\n children: ReactNode;\n}> = ({ title, count, children }) => {\n return (\n <div>\n <h4 className=\"mb-2 flex items-baseline gap-2 text-xs font-semibold tracking-wide text-gray-700 uppercase dark:text-slate-200\">\n <span>{title}</span>\n <span className=\"font-medium tracking-normal text-gray-500 normal-case dark:text-slate-400\">\n ({count})\n </span>\n </h4>\n {children}\n </div>\n );\n};\n\nconst PackageList: React.FC<{\n packages: RegistryPackageList;\n onInstall: (packageSpec: string) => Promise<void>;\n onUninstall: (packageName: string) => void;\n}> = ({ packages, onInstall, onUninstall }) => {\n return (\n <ul className=\"flex flex-col items-stretch gap-4 pr-2\">\n {packages.map((pkg) => (\n <PackageManagerListItem\n key={pkg.name}\n registryPackage={pkg}\n onInstall={onInstall}\n onUninstall={onUninstall}\n />\n ))}\n </ul>\n );\n};\n","import type { RegistryPackageList } from \"@powerhousedao/shared/registry\";\nimport { twMerge } from \"tailwind-merge\";\nimport { PackageManagerInput } from \"./package-manager-input.js\";\nimport { PackageManagerList } from \"./package-manager-list.js\";\n\ntype Props = {\n registryPackageList: RegistryPackageList;\n mutable: boolean;\n /**\n * Install handler. The argument is the full spec the user chose — either\n * the bare package name, or `name@tag` / `name@version` when they typed\n * a suffix in the search input or picked one via the filter UI.\n */\n onInstall: (packageSpec: string) => Promise<void>;\n onUninstall: (packageName: string) => void;\n disabled?: boolean;\n className?: string;\n};\n\nexport const PackageManager: React.FC<Props> = (props) => {\n const {\n registryPackageList,\n onInstall,\n onUninstall,\n mutable,\n disabled,\n className,\n } = props;\n\n return (\n <div\n className={twMerge(\n \"flex h-full flex-1 flex-col rounded-lg bg-gray-50 p-3 text-gray-900 dark:bg-slate-800 dark:text-slate-100\",\n className,\n )}\n >\n {mutable && (\n <PackageManagerInput\n className=\"mb-4\"\n registryPackageList={registryPackageList}\n onInstall={onInstall}\n disabled={disabled}\n />\n )}\n <PackageManagerList\n registryPackageList={registryPackageList}\n onUninstall={onUninstall}\n onInstall={onInstall}\n />\n </div>\n );\n};\n","import type { ComponentProps } from \"react\";\n\nimport { Icon, Modal } from \"#design-system\";\nimport { useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport type SettingsTab = {\n id: string;\n icon?: React.ReactNode;\n label: React.ReactNode;\n content: React.ReactNode | React.ComponentType<any>;\n};\n\ntype Props = {\n readonly title: React.ReactNode;\n readonly tabs: SettingsTab[];\n defaultTab?: string;\n} & ComponentProps<typeof Modal>;\n\nexport function SettingsModal(props: Props) {\n const {\n title,\n overlayProps,\n contentProps,\n onOpenChange,\n tabs,\n defaultTab,\n ...restProps\n } = props;\n\n const [selectedTab, setSelectedTab] = useState(defaultTab ?? tabs.at(0)?.id);\n\n const tabsContent = tabs.map((tab) => (\n <button type=\"button\" onClick={() => setSelectedTab(tab.id)} key={tab.id}>\n <div\n className={twMerge(\n \"flex h-9 w-48 cursor-pointer items-center gap-x-2 rounded-md pl-3 text-gray-700 hover:bg-gray-50 dark:text-slate-200 dark:hover:bg-slate-800\",\n selectedTab === tab.id\n ? \"bg-gray-50 dark:bg-slate-800\"\n : \"bg-transparent\",\n )}\n >\n {tab.icon}\n <span>{tab.label}</span>\n </div>\n </button>\n ));\n\n const selectedTabContent = tabs.find(\n (tab) => tab.id === selectedTab,\n )?.content;\n\n const SelectedTabComponent = selectedTabContent;\n\n return (\n <Modal\n contentProps={{\n ...contentProps,\n className: twMerge(\n \"min-h-full w-full max-w-4xl rounded-xl\",\n contentProps?.className,\n ),\n style: {\n ...contentProps?.style,\n boxShadow:\n \"0px 0px 16px 4px rgba(0, 0, 0, 0.04), 0px 33px 32px -16px rgba(0, 0, 0, 0.10)\",\n },\n }}\n onOpenChange={onOpenChange}\n overlayProps={{\n ...overlayProps,\n className: twMerge(\"py-28\", overlayProps?.className),\n }}\n {...restProps}\n >\n <div className=\"flex justify-between rounded-t-xl border-b border-gray-50 p-4 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <h1 className=\"text-center text-xl font-semibold text-gray-900 dark:text-slate-50\">\n {title}\n </h1>\n <button\n type=\"button\"\n className=\"flex size-6 items-center justify-center rounded-md text-gray-900 outline-none dark:text-slate-100\"\n onClick={() => onOpenChange?.(false)}\n >\n <Icon name=\"XmarkLight\" size={24} />\n </button>\n </div>\n <div className=\"flex flex-1\">\n <div className=\"flex flex-col gap-y-1 p-3 pt-6\">{tabsContent}</div>\n <div className=\"m-6 flex h-full flex-1 flex-col overflow-hidden rounded-lg border border-gray-50 bg-gray-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {typeof SelectedTabComponent === \"function\" ? (\n <SelectedTabComponent />\n ) : (\n SelectedTabComponent\n )}\n </div>\n </div>\n </Modal>\n );\n}\n","import type { ComponentPropsWithoutRef } from \"react\";\n\nimport { Modal } from \"#design-system\";\nimport { ModalButton } from \"./modal-button.js\";\n\nexport type ConnectUpgradeDriveModalProps = ComponentPropsWithoutRef<\n typeof Modal\n> & {\n readonly header: React.ReactNode;\n readonly body: React.ReactNode;\n readonly onContinue: () => void;\n readonly cancelLabel: string;\n readonly continueLabel: string;\n};\n\nexport function ConnectUpgradeDriveModal(props: ConnectUpgradeDriveModalProps) {\n const {\n body,\n header,\n onOpenChange,\n onContinue,\n cancelLabel,\n continueLabel,\n overlayProps,\n contentProps,\n ...restProps\n } = props;\n\n return (\n <Modal\n contentProps={contentProps}\n onOpenChange={onOpenChange}\n overlayProps={{\n ...overlayProps,\n className: overlayProps?.className,\n }}\n {...restProps}\n >\n <div className=\"w-100 bg-gray-50 p-6 text-gray-300 dark:bg-slate-800 dark:text-slate-200\">\n <div className=\"pb-2 text-2xl font-bold text-gray-900 dark:text-slate-100\">\n {header}\n </div>\n <div className=\"my-6 rounded-md bg-gray-50 p-4 text-center text-gray-900 dark:bg-slate-800 dark:text-slate-100\">\n {body}\n </div>\n <div className=\"mt-8 flex justify-between gap-3\">\n <ModalButton variant=\"cancel\" onClick={() => onOpenChange?.(false)}>\n {cancelLabel}\n </ModalButton>\n <ModalButton variant=\"confirm\" onClick={onContinue}>\n {continueLabel}\n </ModalButton>\n </div>\n </div>\n </Modal>\n );\n}\n","import { Icon } from \"#design-system\";\n\ntype Props = {\n readonly branch?: string;\n};\nexport function Branch(props: Props) {\n const { branch = \"main\" } = props;\n\n return (\n <button className=\"flex h-8 w-fit items-center gap-1 rounded-lg bg-gray-50 pr-2 pl-1 text-xs text-stone-300 dark:bg-slate-800\">\n <Icon name=\"Branch\" />\n <span>BRANCH</span>\n <span className=\"text-gray-900 dark:text-slate-50\">{branch}</span>\n </button>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { useCopyToClipboard } from \"usehooks-ts\";\n\ntype Props = {\n readonly docId: string;\n readonly onCopy?: () => void;\n};\nexport function DocId(props: Props) {\n const { docId, onCopy } = props;\n const [, copy] = useCopyToClipboard();\n\n function handleCopy(text: string) {\n return () => {\n copy(text)\n .then(() => {\n onCopy?.();\n })\n .catch((error) => {\n console.error(\"Failed to copy!\", error);\n });\n };\n }\n\n return (\n <button\n className=\"flex h-8 w-fit items-center gap-1 rounded-lg bg-gray-50 pr-2 pl-1 text-xs text-stone-300 dark:bg-slate-800\"\n onClick={handleCopy(docId)}\n >\n <Icon name=\"Link\" />\n DOC ID\n <span className=\"text-gray-900 dark:text-slate-50\">{docId}</span>\n </button>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { useCopyToClipboard } from \"usehooks-ts\";\n\nexport type DocumentStateProps = {\n readonly documentState: object;\n readonly onCopyState?: () => void;\n};\n\nexport const DocumentState = (props: DocumentStateProps) => {\n const { documentState, onCopyState } = props;\n const [, copy] = useCopyToClipboard();\n\n function handleCopy() {\n const jsonState = JSON.stringify(documentState, null, 2);\n copy(jsonState)\n .then(() => {\n onCopyState?.();\n })\n .catch((error) => {\n console.error(\"Failed to copy document state!\", error);\n });\n }\n\n return (\n <button\n className=\"rounded-lg bg-gray-50 p-1 text-stone-300 dark:bg-slate-800\"\n onClick={handleCopy}\n >\n <Icon name=\"CurlyBrackets\" />\n </button>\n );\n};\n","import { ConnectSelect } from \"../../select/select.js\";\n\ntype Props = {\n readonly value: string;\n readonly onChange: (value: string) => void;\n};\nexport function Scope(props: Props) {\n const { value, onChange } = props;\n const items = [\n { displayValue: \"Global scope\", value: \"global\" },\n { displayValue: \"Local scope\", value: \"local\" },\n ] as const;\n\n return (\n <ConnectSelect\n absolutePositionMenu\n containerClassName=\"bg-gray-50 text-gray-500 rounded-lg w-fit text-xs z-10 dark:bg-slate-800 dark:text-slate-400\"\n id=\"scope select\"\n itemClassName=\"py-2 text-gray-500 grid grid-cols-[auto,auto] gap-1 dark:text-slate-400\"\n items={items}\n menuClassName=\"min-w-0 text-gray-500 dark:text-slate-400\"\n onChange={onChange}\n value={value}\n />\n );\n}\n","import { Icon } from \"#design-system\";\nimport type { ReactNode } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Branch } from \"./branch.js\";\nimport { DocId } from \"./doc-id.js\";\nimport { DocumentState } from \"./document-state.js\";\nimport { Scope } from \"./scope.js\";\n\ninterface Props extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n readonly title: ReactNode;\n readonly docId: string;\n readonly scope: string;\n readonly onChangeScope: (scope: string) => void;\n readonly onClose: () => void;\n readonly documentState?: object;\n readonly onCopyState?: () => void;\n readonly onCopyDocId?: () => void;\n}\n\nexport function Header(props: Props) {\n const {\n title,\n docId,\n scope,\n onChangeScope,\n onClose,\n className,\n documentState,\n onCopyState,\n onCopyDocId,\n ...divProps\n } = props;\n return (\n <header\n className={twMerge(\n \"flex items-center justify-between bg-transparent\",\n className,\n )}\n {...divProps}\n >\n <div className=\"flex items-center gap-3\">\n <button\n name=\"close-revision-history\"\n className=\"rounded-lg bg-gray-50 p-1 text-stone-300 shadow-button dark:bg-slate-800\"\n onClick={onClose}\n >\n <Icon name=\"VariantArrowLeft\" />\n </button>\n <h1 className=\"text-xs text-gray-900 dark:text-slate-50\">{title}</h1>\n </div>\n <div className=\"flex items-center gap-2\">\n <DocId docId={docId} onCopy={onCopyDocId} />\n {documentState && (\n <DocumentState\n documentState={documentState}\n onCopyState={onCopyState}\n />\n )}\n <Branch />\n <Scope onChange={onChangeScope} value={scope} />\n </div>\n </header>\n );\n}\n","import { useEffect, useState } from \"react\";\n\ntype EnsData = {\n ens: string;\n address: string;\n avatar: string | null;\n avatar_small: string | null;\n avatar_url: string | null;\n contentHash: string | null;\n header: string | null;\n header_url: string | null;\n ens_primary: string;\n resolverAddress: string;\n url: string | null;\n github: string | null;\n twitter: string | null;\n telegram: string | null;\n email: string | null;\n description: string | null;\n notice: string | null;\n keywords: string | null;\n discord: string | null;\n};\n\ntype UseEnsResult = {\n data: EnsData | undefined;\n isLoading: boolean;\n error: Error | undefined;\n};\n\nconst ensCache = new Map<`0x${string}`, Promise<EnsData | undefined>>();\n\nfunction fetchEns(address: `0x${string}`): Promise<EnsData | undefined> {\n const cached = ensCache.get(address);\n if (cached) return cached;\n\n const promise = fetch(`https://api.ensdata.net/${address}`)\n .then((res) => {\n if (!res.ok) throw new Error(`ENS lookup failed: ${res.status}`);\n return res.json() as Promise<EnsData>;\n })\n .catch((err: unknown) => {\n ensCache.delete(address);\n throw err instanceof Error ? err : new Error(\"ENS lookup failed\");\n });\n\n ensCache.set(address, promise);\n return promise;\n}\n\nexport function useEns(address: `0x${string}` | undefined): UseEnsResult {\n const [data, setData] = useState<EnsData>();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error>();\n\n useEffect(() => {\n if (!address) {\n setData(undefined);\n setError(undefined);\n return;\n }\n\n let cancelled = false;\n setIsLoading(true);\n setError(undefined);\n\n fetchEns(address)\n .then((json) => {\n if (cancelled) return;\n setData(json);\n })\n .catch((err: unknown) => {\n if (cancelled) return;\n setError(err instanceof Error ? err : new Error(\"ENS lookup failed\"));\n })\n .finally(() => {\n if (cancelled) return;\n setIsLoading(false);\n });\n\n return () => {\n cancelled = true;\n };\n }, [address]);\n\n return { data, isLoading, error };\n}\n","export function formatEthAddress(address: string) {\n return `${address.slice(0, 7)}...${address.slice(-5)}`;\n}\n","import {\n Anchor,\n Content,\n Portal,\n Root,\n Trigger,\n} from \"@radix-ui/react-popover\";\nimport { useState, type ReactNode } from \"react\";\nimport { funnel } from \"remeda\";\n\n/* A hybrid popover / tooltip component intended for showing data that needs\n to show / hide on hover, while also being able to stay open so that the user can\n interact with its contents.\n\n Uses these rules:\n\n When the user hover's the trigger, show the tooltip / popover.\n Immediately place the content under the user's cursor.\n Then let the responsibility of closing the tooltip / popover be transferred _to the content_.\n When the user leaves _the contents_ or interacts elsewhere, only then close.\n*/\nexport function CodePopover(props: {\n content: ReactNode;\n trigger: ReactNode;\n anchor?: ReactNode;\n}) {\n const { content, trigger, anchor } = props;\n const [isOpen, setIsOpen] = useState(false);\n\n /* debounce calls to open by 300ms */\n const opener = funnel(() => setIsOpen(true), {\n triggerAt: \"start\",\n minQuietPeriodMs: 300,\n });\n\n /* debounce calls to close by 100ms */\n const closer = funnel(() => setIsOpen(false), {\n triggerAt: \"start\",\n minQuietPeriodMs: 100,\n });\n\n /* If we are in the process of closing, cancel that operation.\n Then call the opener.\n */\n function open() {\n closer.cancel();\n opener.call();\n }\n\n /* If we are in the process of opening, cancel that operation.\n Then call the closer.\n */\n function close() {\n opener.cancel();\n closer.call();\n }\n\n return (\n <Root\n /* This component combines internal state with the existing accessibility behaviors from the radix popover */\n open={isOpen}\n onOpenChange={(changedIsOpen) => (changedIsOpen ? open() : close())}\n >\n {/* Trigger only manages opening */}\n <Trigger onMouseEnter={open}>{trigger}</Trigger>\n {!!anchor && <Anchor asChild>{anchor}</Anchor>}\n <Portal>\n <Content\n /* We need to force mount so that the events are fired as expected */\n forceMount\n /* content only manages closing */\n onMouseLeave={close}\n /* Offset the position to ensure that we open under the user's cursor */\n sideOffset={-28}\n /* Do not focus the trigger after closing since that item is not interactive */\n onCloseAutoFocus={(e) => e.preventDefault()}\n /* Set an arbitrarily large bottom collision detection padding so that very long content flows below the fold */\n collisionPadding={{\n top: 24,\n right: 24,\n bottom: -10_000,\n left: 24,\n }}\n className=\"z-50 rounded-lg border border-gray-200 bg-gray-50 p-2 text-xs shadow-tooltip outline-none dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\"\n >\n {content}\n </Content>\n </Portal>\n </Root>\n );\n}\n","import { useEns } from \"../../../hooks/use-ens.js\";\nimport { formatEthAddress } from \"../../../utils/address.js\";\nimport { CodePopover } from \"../../code-popover.js\";\nimport { ENSAvatar } from \"../../ens-avatar/ens-avatar.js\";\nimport { FormattedJsonViewer } from \"../../formatted-json-viewer.js\";\n\nexport type AddressProps = {\n readonly address: `0x${string}` | undefined;\n readonly chainId: number | undefined;\n};\n\nexport function Address(props: AddressProps) {\n const { address, chainId } = props;\n const { data: ensData } = useEns(address);\n\n if (!address) return null;\n\n const shortenedAddress = formatEthAddress(address);\n\n return (\n <CodePopover\n content={<FormattedJsonViewer value={{ address }} />}\n trigger={\n <span className=\"flex w-fit cursor-pointer items-center gap-1 rounded-lg bg-gray-100 p-1 text-xs text-gray-100 dark:bg-slate-700 dark:text-slate-800\">\n <ENSAvatar\n address={address}\n chainId={chainId}\n avatarUrl={ensData?.avatar_url ?? undefined}\n />\n {shortenedAddress}\n </span>\n }\n />\n );\n}\n","import { Icon } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\nimport { CodePopover } from \"../../code-popover.js\";\nimport { FormattedJsonViewer } from \"../../formatted-json-viewer.js\";\n\nexport type ErrorsProps = {\n readonly errors: string[] | undefined;\n};\n\nexport function Errors(props: ErrorsProps) {\n const { errors } = props;\n\n const hasErrors = !!errors?.length;\n\n const color = hasErrors\n ? \"text-red-800 dark:text-red-100\"\n : \"text-green-700 dark:text-green-100\";\n\n const icon = hasErrors ? (\n <Icon name=\"Exclamation\" size={16} />\n ) : (\n <Icon name=\"Check\" size={16} />\n );\n\n const text = hasErrors ? `Error: ${errors[0]}` : \"No errors\";\n\n const content = (\n <span\n className={twMerge(\n \"flex w-fit items-center rounded-lg border border-gray-200 bg-gray-50 px-2 py-1 text-xs dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n color,\n hasErrors && \"cursor-pointer\",\n )}\n >\n {icon}\n <span className={twMerge(\"inline-block max-w-36 truncate\")}>{text}</span>\n </span>\n );\n\n if (hasErrors)\n return (\n <CodePopover\n content={<FormattedJsonViewer value={errors} />}\n trigger={content}\n />\n );\n\n return content;\n}\n","import { Icon } from \"#design-system\";\nimport { CodePopover } from \"../../code-popover.js\";\nimport { FormattedJsonViewer } from \"../../formatted-json-viewer.js\";\nexport type OperationProps = {\n readonly operationType: string;\n readonly operationInput: Record<string, any>;\n};\n\nexport function Operation(props: OperationProps) {\n const { operationType, operationInput } = props;\n return (\n <CodePopover\n content={<FormattedJsonViewer value={operationInput} />}\n trigger={\n <span className=\"flex cursor-pointer items-center gap-2 text-xs text-gray-900 dark:text-slate-50\">\n {operationType}\n <Icon\n className=\"text-gray-300 dark:text-slate-600\"\n name=\"Braces\"\n size={16}\n />\n </span>\n }\n />\n );\n}\n","import { Icon } from \"#design-system\";\nimport { CodePopover } from \"../../code-popover.js\";\nimport { FormattedJsonViewer } from \"../../formatted-json-viewer.js\";\n\nexport type RevisionNumberProps = {\n readonly operationIndex: number;\n readonly eventId: string;\n readonly stateHash: string;\n};\nexport function RevisionNumber(props: RevisionNumberProps) {\n const { operationIndex, eventId, stateHash } = props;\n const revisionNumber = operationIndex + 1;\n\n return (\n <CodePopover\n content={\n <FormattedJsonViewer\n value={{\n revisionNumber,\n eventId,\n stateHash,\n }}\n />\n }\n trigger={\n <span className=\"flex cursor-pointer items-center gap-2 text-xs text-gray-700 dark:text-slate-200\">\n Revision {revisionNumber}.\n <a>\n <Icon\n className=\"cursor-pointer text-gray-100 dark:text-slate-800\"\n name=\"Ellipsis\"\n size={14}\n />\n </a>\n </span>\n }\n />\n );\n}\n","import { Icon } from \"#design-system\";\nimport { CodePopover } from \"../../code-popover.js\";\nimport { FormattedJsonViewer } from \"../../formatted-json-viewer.js\";\nimport type { Signature } from \"../types.js\";\n\nexport type SignatureProps = {\n readonly signatures: Signature[] | undefined;\n};\nexport function Signature(props: SignatureProps) {\n const { signatures } = props;\n\n if (!signatures?.length) return null;\n\n return (\n <CodePopover\n trigger={\n <span className=\"flex w-fit cursor-pointer items-center gap-1 rounded-lg border border-gray-200 bg-gray-50 px-2 py-1 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <VerificationStatus signatures={signatures} />{\" \"}\n <Icon\n className=\"text-gray-300 dark:text-slate-600\"\n name=\"InfoSquare\"\n size={16}\n />\n </span>\n }\n content={<FormattedJsonViewer value={signatures} collapsed={1} />}\n />\n );\n}\n\nfunction VerificationStatus(props: SignatureProps) {\n const { signatures } = props;\n\n if (!signatures?.length) return null;\n\n const signatureCount = signatures.length;\n\n const verifiedSignaturesCount = signatures.filter(\n (signature) => signature.isVerified,\n ).length;\n const signatureText = signatureCount === 1 ? \"signature\" : \"signatures\";\n const verificationStatusText = `${verifiedSignaturesCount}/${signatureCount} ${signatureText} verified`;\n const color =\n verifiedSignaturesCount === 0\n ? \"text-red-800 dark:text-red-100\"\n : verifiedSignaturesCount === signatureCount\n ? \"text-green-700 dark:text-green-100\"\n : \"text-orange-700 dark:text-orange-100\";\n\n return <span className={`text-xs ${color}`}>{verificationStatusText}</span>;\n}\n","import { format } from \"date-fns\";\nimport { CodePopover } from \"../../code-popover.js\";\nimport { FormattedJsonViewer } from \"../../formatted-json-viewer.js\";\n\nexport type TimestampProps = {\n readonly timestampUtcMs: number | string;\n};\n\nexport function Timestamp(props: TimestampProps) {\n const { timestampUtcMs: timestamp } = props;\n\n const timestampNumber =\n typeof timestamp === \"string\" && !timestamp.includes(\"-\")\n ? parseInt(timestamp)\n : timestamp;\n\n const date = new Date(timestampNumber);\n const shortDate = format(date, \"HH:mm 'UTC'\");\n const longDate = format(date, \"eee, dd MMM yyyy HH:mm:ss 'UTC'\");\n\n return (\n <CodePopover\n content={\n <FormattedJsonViewer\n value={{ timestampFormatted: longDate, timestampUtcMs: timestamp }}\n />\n }\n trigger={\n <span className=\"cursor-pointer text-xs text-gray-900 dark:text-slate-50\">\n committed at {shortDate}\n </span>\n }\n />\n );\n}\n","import { memo } from \"react\";\nimport type { Revision as RevisionProps } from \"../types.js\";\nimport { Address } from \"./address.js\";\nimport { Errors } from \"./errors.js\";\nimport { Operation } from \"./operation.js\";\nimport { RevisionNumber } from \"./revision-number.js\";\nimport { Signature } from \"./signature.js\";\nimport { Timestamp } from \"./timestamp.js\";\n\nexport function _Revision(props: RevisionProps) {\n return (\n <article className=\"flex items-center justify-between rounded-xl border border-gray-200 bg-gray-50 px-4 py-2 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <div className=\"flex items-center gap-2\">\n <RevisionNumber {...props} />\n <Operation {...props} />\n <Address {...props} />\n <Timestamp {...props} />\n </div>\n <div className=\"flex items-center gap-1\">\n <Signature {...props} />\n <Errors {...props} />\n </div>\n </article>\n );\n}\n\nexport const Revision = memo(_Revision);\n","export type SkipProps = {\n readonly operationIndex: number;\n readonly skipCount: number;\n};\n\nexport function Skip(props: SkipProps) {\n const { operationIndex, skipCount } = props;\n const revisionNumber = operationIndex;\n\n const skippedRevisions =\n skipCount === 1\n ? `${revisionNumber}`\n : `${revisionNumber} - ${revisionNumber + 1 - skipCount}`;\n\n return (\n <article className=\"grid grid-cols-[1fr,auto,1fr] items-center py-2\">\n <div className=\"h-px rounded-full bg-gray-100 dark:bg-slate-700\" />\n <div className=\"mx-3 text-xs text-gray-100 dark:text-slate-800\">\n [Skipped Revision {skippedRevisions}]\n </div>\n <div className=\"h-px rounded-full bg-gray-100 dark:bg-slate-700\" />\n </article>\n );\n}\n","import type { Operation } from \"@powerhousedao/shared/document-model\";\nimport type { Day, Revision, Signature, Skip } from \"./types.js\";\n\nexport function makeRows(operations: Operation[]) {\n const revisionsAndSkips: (Revision | Skip | Day)[] = [];\n const seenDays = new Set<string>();\n\n for (const operation of operations) {\n if (!operation.timestampUtcMs) continue;\n const day = operation.timestampUtcMs.split(\"T\")[0];\n\n if (!seenDays.has(day)) {\n seenDays.add(day);\n revisionsAndSkips.push({\n type: \"day\",\n height: 32,\n timestampUtcMs: day,\n });\n }\n\n revisionsAndSkips.push({\n type: \"revision\",\n height: 46,\n operationIndex: operation.index,\n eventId: operation.id ?? \"EVENT_ID_NOT_FOUND\",\n stateHash: operation.hash,\n operationType: operation.action.type,\n operationInput: operation.action.input ?? {},\n address: operation.action?.context?.signer?.user.address as\n | `0x${string}`\n | undefined,\n chainId: operation.action?.context?.signer?.user.chainId,\n timestampUtcMs: operation.timestampUtcMs,\n signatures: makeSignatures(\n (operation.action?.context?.signer?.signatures as\n | string[][]\n | undefined) ?? [],\n ),\n errors: operation.error ? [operation.error] : undefined,\n });\n\n if (operation.skip > 0) {\n revisionsAndSkips.push({\n type: \"skip\",\n height: 34,\n operationIndex: operation.index,\n skipCount: operation.skip,\n timestampUtcMs: operation.timestampUtcMs,\n });\n }\n }\n\n return revisionsAndSkips;\n}\n\nexport function getUniqueDatesInOrder(operations: Operation[]) {\n const dates = new Set<string>();\n\n for (const operation of operations) {\n if (!operation.timestampUtcMs) continue;\n const date = operation.timestampUtcMs.split(\"T\")[0];\n dates.add(date);\n }\n\n return Array.from(dates).sort(\n (a, b) => new Date(b).getTime() - new Date(a).getTime(),\n );\n}\n\nfunction makeSignatureFromSignatureArray(signatureArray: string[]): Signature {\n const [signerAddress, hash, prevStateHash, signatureBytes] = signatureArray;\n\n return {\n signerAddress,\n hash,\n prevStateHash,\n signatureBytes,\n isVerified: true,\n };\n}\n\nfunction makeSignatures(signaturesArray: string[][] | undefined) {\n return signaturesArray?.map(makeSignatureFromSignatureArray);\n}\n","import { Icon } from \"#design-system\";\nimport { format } from \"date-fns\";\n\nexport function Day(props: { readonly timestampUtcMs: string }) {\n const { timestampUtcMs: timestamp } = props;\n const formattedDate = format(timestamp, \"MMM dd, yyyy\");\n return (\n <h2 className=\"-ml-6 flex items-center gap-1 bg-gray-50 py-2 text-xs text-gray-100 dark:bg-slate-800 dark:text-slate-800\">\n <Icon name=\"Ring\" size={16} /> Changes on {formattedDate}\n </h2>\n );\n}\n","import type { Operation } from \"@powerhousedao/shared/document-model\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Revision } from \"../revision/revision.js\";\nimport { Skip } from \"../skip/skip.js\";\nimport { makeRows } from \"../utils.js\";\nimport { Day } from \"./day.js\";\n\nexport type TimelineProps = {\n readonly localOperations: Operation[];\n readonly globalOperations: Operation[];\n readonly scope: string;\n};\n\nexport function Timeline(props: TimelineProps) {\n const { localOperations, globalOperations, scope } = props;\n const operations = scope === \"local\" ? localOperations : globalOperations;\n const initialNumRowsToShow = 100;\n const allRows = useMemo(() => makeRows(operations), [operations]);\n const [scrollAmount, setScrollAmount] = useState(0);\n const [numRowsToShow, setNumRowsToShow] = useState(initialNumRowsToShow);\n const [rows, setRows] = useState(() => allRows.slice(0, numRowsToShow));\n\n const parentRef = useRef<HTMLDivElement>(null);\n\n const hasNextPage = rows.length < allRows.length;\n\n const rowVirtualizer = useVirtualizer({\n count: rows.length,\n getScrollElement: () => parentRef.current,\n estimateSize: (i) => allRows[i].height,\n gap: 8,\n });\n\n useEffect(() => {\n if (!hasNextPage) return;\n const ratio = Math.floor(scrollAmount / 46);\n const newNumRevisions = initialNumRowsToShow + ratio;\n setNumRowsToShow((prev) =>\n newNumRevisions > prev ? newNumRevisions : prev,\n );\n }, [scrollAmount, hasNextPage]);\n\n useEffect(() => {\n setRows(allRows.slice(0, numRowsToShow));\n }, [allRows, numRowsToShow]);\n\n const handleScroll = (e: WheelEvent) => {\n setScrollAmount((prev) => {\n const n = prev + e.deltaY;\n if (n < 0) {\n return 0;\n }\n return n;\n });\n };\n\n useEffect(() => {\n window.addEventListener(\"wheel\", handleScroll);\n return () => {\n window.removeEventListener(\"wheel\", handleScroll);\n };\n }, []);\n\n return (\n <div\n className=\"border-l border-gray-100 dark:border-none dark:bg-slate-800 dark:text-slate-100\"\n ref={parentRef}\n style={{\n height: `${rowVirtualizer.getTotalSize()}px`,\n width: \"100%\",\n position: \"relative\",\n }}\n >\n {rowVirtualizer.getVirtualItems().map((virtualRow) => {\n const row = rows[virtualRow.index];\n\n return (\n <div\n key={virtualRow.index}\n style={{\n position: \"absolute\",\n top: 0,\n left: 16,\n width: \"100%\",\n height: `${virtualRow.size}px`,\n transform: `translateY(${virtualRow.start}px)`,\n }}\n >\n {row.type === \"revision\" && (\n <Revision {...row} key={virtualRow.key} />\n )}\n {row.type === \"skip\" && <Skip key={virtualRow.key} {...row} />}\n {row.type === \"day\" && <Day key={virtualRow.key} {...row} />}\n </div>\n );\n })}\n </div>\n );\n}\n","import { Pagination, usePagination } from \"#design-system\";\nimport type { Operation } from \"@powerhousedao/shared/document-model\";\nimport {\n garbageCollect,\n sortOperations,\n} from \"@powerhousedao/shared/document-model\";\nimport { useMemo, useState } from \"react\";\nimport { ConnectTooltipProvider } from \"../tooltip/tooltip.js\";\nimport { Header } from \"./header/header.js\";\nimport { Timeline } from \"./timeline/timeline.js\";\n\ntype Props = {\n readonly documentTitle: string;\n readonly documentId: string;\n readonly globalOperations: Operation[];\n readonly localOperations: Operation[];\n readonly onClose: () => void;\n readonly itemsPerPage?: number;\n readonly documentState?: object;\n readonly onCopyState?: () => void;\n readonly onCopyDocId?: () => void;\n};\n\nexport function RevisionHistory(props: Props) {\n const {\n documentTitle,\n documentId,\n globalOperations,\n localOperations,\n onClose,\n itemsPerPage = 100,\n documentState,\n onCopyState,\n onCopyDocId,\n } = props;\n\n const [scope, setScope] = useState<string>(\"global\");\n\n const visibleOperations = useMemo(() => {\n const operations = scope === \"global\" ? globalOperations : localOperations;\n return garbageCollect(sortOperations(operations)).sort(\n (a, b) => b.index - a.index,\n );\n }, [globalOperations, localOperations, scope]);\n\n const {\n pageItems,\n pages,\n goToPage,\n goToNextPage,\n goToPreviousPage,\n goToFirstPage,\n goToLastPage,\n hiddenNextPages,\n isNextPageAvailable,\n isPreviousPageAvailable,\n } = usePagination(visibleOperations, {\n itemsPerPage,\n });\n\n function onChangeScope(scope: string) {\n goToFirstPage();\n setScope(scope);\n }\n\n const showPagination = visibleOperations.length > itemsPerPage;\n\n const PaginationComponent = showPagination ? (\n <div className=\"mt-4 flex w-full justify-end\">\n <Pagination\n firstPageLabel=\"First Page\"\n goToFirstPage={goToFirstPage}\n goToLastPage={goToLastPage}\n goToNextPage={goToNextPage}\n goToPage={goToPage}\n goToPreviousPage={goToPreviousPage}\n hiddenNextPages={hiddenNextPages}\n isNextPageAvailable={isNextPageAvailable}\n isPreviousPageAvailable={isPreviousPageAvailable}\n lastPageLabel=\"Last Page\"\n nextPageLabel=\"Next\"\n pages={pages}\n previousPageLabel=\"Previous\"\n />\n </div>\n ) : (\n <hr className=\"h-12 border-none\" />\n );\n\n return (\n <ConnectTooltipProvider>\n <div className=\"p-6 dark:bg-slate-800\">\n <Header\n docId={documentId}\n onChangeScope={onChangeScope}\n onClose={onClose}\n scope={scope}\n title={documentTitle}\n documentState={documentState}\n onCopyState={onCopyState}\n onCopyDocId={onCopyDocId}\n />\n {PaginationComponent}\n <div className=\"mt-4 flex justify-center rounded-md bg-gray-50 p-4 dark:bg-slate-800\">\n {visibleOperations.length > 0 ? (\n <div className=\"grid grid-cols-[minmax(min-content,1018px)]\">\n <Timeline\n globalOperations={scope === \"global\" ? pageItems : []}\n localOperations={scope === \"local\" ? pageItems : []}\n scope={scope}\n />\n </div>\n ) : (\n <h3 className=\"my-40 text-gray-700 dark:text-slate-200\">\n This document has no recorded operations yet.\n </h3>\n )}\n </div>\n {PaginationComponent}\n </div>\n </ConnectTooltipProvider>\n );\n}\n","import { twMerge } from \"tailwind-merge\";\n\nexport type FilterItemType = {\n id: string;\n label: string;\n icon?: React.JSX.Element;\n};\n\nexport interface FilterItemProps extends React.HTMLAttributes<HTMLDivElement> {\n item: FilterItemType;\n}\n\nexport const FilterItem: React.FC<FilterItemProps> = (props) => {\n const { item, className, ...containerProps } = props;\n\n return (\n <div\n className={twMerge(\n \"flex h-full flex-row items-center justify-between gap-x-4 px-2\",\n typeof className === \"string\" && className,\n )}\n {...containerProps}\n >\n {item.icon}\n <div className=\"text-sm font-semibold text-gray-200 dark:text-slate-700\">\n {item.label}\n </div>\n </div>\n );\n};\n","import {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n Icon,\n} from \"#design-system\";\nimport type { ChangeEvent } from \"react\";\nimport { useMemo } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport type { FilterItemType } from \"./filter-item.js\";\nimport { FilterItem } from \"./filter-item.js\";\n\nexport interface ConnectSearchBarProps {\n value?: string;\n onChange?: (value: string) => void;\n placeholder?: string;\n filterLabel?: string;\n filterItems?: Array<FilterItemType>;\n selectedFilter?: string;\n onFilterSelect?: (filterId: string) => void;\n className?: string;\n}\n\nexport const ConnectSearchBar: React.FC<ConnectSearchBarProps> = (props) => {\n const {\n value,\n onChange,\n placeholder,\n filterLabel,\n filterItems,\n selectedFilter,\n onFilterSelect = () => {},\n className,\n } = props;\n\n const items = useMemo(\n () =>\n filterItems?.map((item) => ({\n id: item.id,\n content: <FilterItem item={item} />,\n })) ?? [],\n [filterItems],\n );\n\n const selectedItemFilter = filterItems?.find(\n (item) => item.id === selectedFilter,\n );\n\n const filterLabelContent = selectedItemFilter ? (\n <FilterItem className=\"gap-x-1\" item={selectedItemFilter} />\n ) : (\n filterLabel && (\n <div className=\"mr-2 text-sm font-semibold text-gray-200 dark:text-slate-700\">\n {filterLabel}\n </div>\n )\n );\n\n function handleChange(event: ChangeEvent<HTMLInputElement>) {\n onChange?.(event.target.value);\n }\n\n return (\n <div className={twMerge(\"flex items-center\", className)}>\n <Icon className=\"mr-3 text-gray-700 dark:text-slate-200\" name=\"Search\" />\n <input\n className={twMerge(\n \"flex h-[52px] min-w-0 flex-1 items-center rounded-xl border border-gray-200 bg-gray-50 px-4 text-sm text-gray-200 outline-none dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n )}\n onChange={handleChange}\n placeholder={placeholder}\n value={value}\n />\n <DropdownMenu>\n <DropdownMenuTrigger className=\"ml-3 flex h-full flex-row items-center outline-none\">\n {filterLabelContent} <Icon name=\"ChevronDown\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"rounded-xl border border-gray-100 bg-gray-50 p-2 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {items.map((item) => (\n <DropdownMenuItem\n className=\"h-10 cursor-pointer overflow-hidden rounded-lg hover:bg-gray-100 dark:hover:bg-slate-700\"\n id={item.id}\n key={item.id}\n onSelect={() => onFilterSelect(item.id)}\n >\n {item.content}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n );\n};\n","import { twMerge } from \"tailwind-merge\";\nimport { ConnectTooltip } from \"../tooltip/tooltip.js\";\n\ntype SidebarItemProps = {\n readonly icon?: React.JSX.Element;\n readonly title: string;\n readonly description?: string;\n readonly containerClassName?: string;\n readonly active?: boolean;\n readonly onClick?: (event: React.MouseEvent<HTMLDivElement>) => void;\n};\nexport const SidebarItem = function SidebarItem(props: SidebarItemProps) {\n const {\n icon,\n title,\n description: _description,\n containerClassName,\n active,\n onClick,\n } = props;\n return (\n <ConnectTooltip\n content={title}\n side=\"right\"\n sideOffset={12}\n className=\"border-none bg-gray-800 px-3 py-2 text-sm text-white dark:bg-slate-100 dark:text-slate-900\"\n >\n <div\n className={twMerge(\n \"group/sidebar-item relative flex cursor-pointer flex-col items-center justify-center text-center text-sm text-gray-900 dark:text-slate-50\",\n containerClassName,\n active && \"bg-gray-50 dark:bg-slate-800\",\n onClick && \"cursor-pointer\",\n )}\n onClick={onClick}\n >\n {active ? (\n <div className=\"absolute top-1/2 left-0 h-10 w-1 -translate-y-1/2 rounded-r-sm bg-violet-400 dark:bg-violet-500\" />\n ) : (\n <div className=\"absolute top-1/2 left-0 h-6 w-1 -translate-y-1/2 rounded-r-sm bg-gray-300 opacity-0 transition-opacity group-hover/sidebar-item:opacity-100 dark:bg-slate-600 dark:text-slate-100\" />\n )}\n <div className=\"mx-auto py-4\">\n {icon || (\n <div className=\"flex size-8 items-center justify-center rounded-lg bg-gray-900 dark:bg-slate-50\">\n <span className=\"text-sm font-medium text-white dark:text-slate-900\">\n {title.slice(0, 1).toUpperCase()}\n </span>\n </div>\n )}\n </div>\n </div>\n </ConnectTooltip>\n );\n};\n","import { Icon } from \"#design-system\";\nimport { SidebarItem } from \"./sidebar-item.js\";\n\ntype SidebarAddDriveItemProps = {\n readonly containerClassName?: string;\n readonly onClick?: (event: React.MouseEvent<HTMLDivElement>) => void;\n};\nexport const SidebarAddDriveItem = function SidebarAddDriveItem(\n props: SidebarAddDriveItemProps,\n) {\n const { containerClassName, onClick } = props;\n return (\n <SidebarItem\n title=\"Create New Drive\"\n icon={<Icon name=\"PlusSquare\" size={32} />}\n onClick={onClick}\n containerClassName={containerClassName}\n />\n );\n};\n","import { useTheme } from \"@powerhousedao/reactor-browser\";\nimport { Monitor, Moon, Sun } from \"lucide-react\";\nimport { twMerge } from \"tailwind-merge\";\n\ntype Theme = \"light\" | \"dark\" | \"system\";\n\nconst OPTIONS = [\n { value: \"light\", Icon: Sun, label: \"Light\" },\n { value: \"dark\", Icon: Moon, label: \"Dark\" },\n { value: \"system\", Icon: Monitor, label: \"System\" },\n] as const;\n\nexport function ThemeSwitch() {\n const { theme, isSystem, setTheme } = useTheme();\n\n function select(val: Theme) {\n setTheme(val);\n }\n\n function isActive(value: Theme) {\n if (value === \"system\" && isSystem) return true;\n if (!isSystem && value === \"dark\" && theme === \"dark\") return true;\n if (!isSystem && value === \"light\" && theme === \"light\") return true;\n return false;\n }\n\n return (\n <div\n role=\"radiogroup\"\n aria-label=\"Theme\"\n className=\"flex w-fit flex-col items-center gap-4 rounded-xl\"\n >\n {OPTIONS.map(({ value, Icon, label }) => (\n <div\n key={value}\n role=\"radio\"\n aria-checked={isActive(value)}\n aria-label={label}\n tabIndex={0}\n onClick={() => select(value)}\n onKeyDown={(e) =>\n (e.key === \"Enter\" || e.key === \" \") && select(value)\n }\n className={twMerge(\n \"flex size-fit cursor-pointer content-center items-center transition-colors\",\n isActive(value)\n ? \"text-gray-900 dark:text-slate-50\"\n : \"text-gray-500 dark:text-slate-400\",\n )}\n >\n <Icon size={24} strokeWidth={2} aria-hidden=\"true\" />\n </div>\n ))}\n </div>\n );\n}\n","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","import { Icon } from \"#design-system\";\nimport type { FC } from \"react\";\nimport { useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport interface AccountPopoverLoginProps {\n onLogin: (() => void) | undefined;\n}\n\nexport const AccountPopoverLogin: FC<AccountPopoverLoginProps> = ({\n onLogin,\n}) => {\n const [loading, setLoading] = useState(false);\n\n const allowLogin = !loading && !!onLogin;\n\n const content = loading ? (\n <Icon name=\"Reload\" size={14} className=\"animate-spin\" />\n ) : (\n <span>Connect</span>\n );\n\n const handleLogin = () => {\n if (onLogin) {\n setLoading(true);\n onLogin();\n }\n };\n\n return (\n <div className=\"p-4\">\n <div className=\"mb-4 flex justify-center\">\n <div className=\"flex h-5.5 w-20.75 items-center justify-center overflow-hidden text-gray-900 dark:text-slate-50\">\n <Icon name=\"RenownLight\" size={83} />\n </div>\n </div>\n <button\n onClick={allowLogin ? handleLogin : undefined}\n className={twMerge(\n \"mt-4 flex h-7 w-full cursor-pointer items-center justify-center rounded-lg border border-gray-300 bg-transparent text-sm text-gray-900 active:opacity-70 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n allowLogin ? \"cursor-pointer\" : \"cursor-wait\",\n )}\n type=\"button\"\n >\n {content}\n </button>\n </div>\n );\n};\n","import renownShortDark from \"#assets/renown-short-dark.png\";\nimport renownShortHoverDark from \"#assets/renown-short-hover-dark.png\";\nimport renownShortHover from \"#assets/renown-short-hover.png\";\nimport renownShort from \"#assets/renown-short.png\";\nimport { useTheme } from \"@powerhousedao/reactor-browser\";\nimport { twMerge } from \"tailwind-merge\";\nimport { AccountPopoverLogin } from \"../account-popover/account-popover-login.js\";\nimport { AccountPopover } from \"../account-popover/account-popover.js\";\n\nexport interface SidebarLoginProps {\n onLogin: (() => void) | undefined;\n}\n\nexport const SidebarLogin: React.FC<SidebarLoginProps> = ({ onLogin }) => {\n const content = <AccountPopoverLogin onLogin={onLogin} />;\n const { theme } = useTheme();\n const isDark = theme === \"dark\";\n const src = isDark ? renownShortDark : renownShort;\n const hoverSrc = isDark ? renownShortHoverDark : renownShortHover;\n\n return (\n <AccountPopover content={content}>\n <div\n className={twMerge(\n \"group/sidebar-footer flex w-full items-baseline justify-start text-sm/10 font-semibold text-gray-700 dark:text-slate-200\",\n onLogin ? \"cursor-pointer\" : \"cursor-wait\",\n )}\n >\n <img\n width={42}\n height={42}\n loading=\"lazy\"\n className=\"group-hover/sidebar-footer:hidden\"\n src={src}\n alt=\"Renown Login\"\n />\n <img\n width={42}\n height={42}\n loading=\"lazy\"\n className=\"hidden group-hover/sidebar-footer:block\"\n src={hoverSrc}\n alt=\"Renown Login Hover\"\n />\n </div>\n </AccountPopover>\n );\n};\n","import { Icon, PowerhouseButton } from \"#design-system\";\nimport type { FC } from \"react\";\nimport { useCallback, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport interface AccountPopoverUserProps {\n address: `0x${string}`;\n onDisconnect: (() => void) | undefined;\n etherscanUrl?: string;\n username?: string;\n}\n\n// short eth address\nconst shortAddress = (address: `0x${string}`) =>\n `${address.slice(0, 7)}...${address.slice(-5)}`;\n\nexport const AccountPopoverUser: FC<AccountPopoverUserProps> = ({\n address,\n onDisconnect,\n etherscanUrl,\n username = \"\",\n}: AccountPopoverUserProps) => {\n const [isCopied, setIsCopied] = useState(false);\n\n const copyToClipboard = useCallback(async (text: string) => {\n try {\n await navigator.clipboard.writeText(text);\n setIsCopied(true);\n setTimeout(() => setIsCopied(false), 2000);\n } catch (err) {\n console.error(\"Failed to copy address:\", err);\n }\n }, []);\n\n return (\n <div className=\"flex flex-col divide-y divide-gray-200 text-gray-900 dark:divide-slate-500 dark:text-slate-50\">\n <div className=\"px-3 py-2\">\n {username && <div className=\"text-sm font-medium\">{username}</div>}\n <div className=\"mt-1 flex items-center gap-2\">\n <PowerhouseButton\n size=\"small\"\n color=\"light\"\n onClick={() => void copyToClipboard(address)}\n className=\"w-full cursor-pointer bg-transparent p-0 active:opacity-70\"\n type=\"button\"\n >\n <div className=\"relative flex w-full items-center gap-1\">\n <div\n className={`flex items-center gap-1 transition-opacity duration-150 ${isCopied ? \"opacity-0\" : \"opacity-100\"}`}\n >\n <span className=\"text-xs\">{shortAddress(address)}</span>\n <Icon name=\"FilesEarmark\" color=\"#9EA0A1\" size={14} />\n </div>\n <div\n className={`absolute left-0 text-xs transition-opacity duration-150 ${isCopied ? \"opacity-100\" : \"opacity-0\"}`}\n >\n Copied to clipboard!\n </div>\n </div>\n </PowerhouseButton>\n </div>\n </div>\n {etherscanUrl && (\n <div className=\"px-3 py-2\">\n <a\n href={etherscanUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-sm text-gray-900 hover:text-gray-600 dark:text-slate-50 dark:hover:text-slate-300\"\n >\n <Icon name=\"Ethscan\" size={14} />\n View on Etherscan\n </a>\n </div>\n )}\n <div className=\"px-3 py-2\">\n <button\n onClick={onDisconnect}\n className={twMerge(\n \"flex w-full items-center gap-2 text-sm text-red-900 dark:text-red-400\",\n onDisconnect\n ? \"cursor-pointer hover:text-red-700 dark:hover:text-red-100\"\n : \"pointer-events-none cursor-wait\",\n )}\n type=\"button\"\n >\n <Icon name=\"Disconnect\" size={14} />\n Disconnect\n </button>\n </div>\n </div>\n );\n};\n","import { AccountPopoverUser } from \"../account-popover/account-popover-user.js\";\nimport { AccountPopover } from \"../account-popover/account-popover.js\";\nimport { ENSAvatar } from \"../ens-avatar/ens-avatar.js\";\n\nexport interface SidebarUserProps {\n address: `0x${string}`;\n ensName?: string;\n avatarUrl?: string;\n etherscanUrl: string;\n onDisconnect: (() => void) | undefined;\n}\n\nexport const SidebarUser: React.FC<SidebarUserProps> = ({\n address,\n ensName,\n avatarUrl,\n etherscanUrl,\n onDisconnect,\n}) => {\n const content = (\n <AccountPopoverUser\n address={address}\n username={ensName}\n onDisconnect={onDisconnect}\n etherscanUrl={etherscanUrl}\n />\n );\n\n return (\n <AccountPopover content={content}>\n <div className=\"flex items-center justify-center rounded-sm\">\n <ENSAvatar address={address} avatarUrl={avatarUrl} size=\"40px\" />\n </div>\n </AccountPopover>\n );\n};\n","import { Icon, SidebarFooter } from \"#design-system\";\nimport { Settings } from \"lucide-react\";\nimport type { ComponentProps } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ThemeSwitch } from \"../theme-switch.js\";\nimport { SidebarLogin } from \"./sidebar-login.js\";\nimport { SidebarUser } from \"./sidebar-user.js\";\nexport interface ConnectSidebarFooterProps extends ComponentProps<\n typeof SidebarFooter\n> {\n address: `0x${string}` | undefined;\n ensName?: string;\n avatarUrl?: string;\n onClickSettings: (() => void) | undefined;\n onLogin: (() => void) | undefined;\n etherscanUrl?: string;\n onDisconnect: (() => void) | undefined;\n onHomeClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n showDebug?: boolean;\n onDebugClick?: () => void;\n}\n\nexport const ConnectSidebarFooter: React.FC<ConnectSidebarFooterProps> = ({\n address,\n ensName,\n avatarUrl,\n className,\n onLogin,\n onClickSettings,\n onDisconnect,\n onHomeClick,\n showDebug,\n onDebugClick,\n etherscanUrl = \"\",\n ...props\n}) => {\n return (\n <SidebarFooter\n {...props}\n className={twMerge(\n \"flex flex-col items-center gap-3 border-t border-gray-300 px-2 py-4 dark:border-none dark:bg-slate-700 dark:text-slate-100\",\n className,\n )}\n >\n {onHomeClick && (\n <button\n aria-label=\"Home\"\n type=\"button\"\n className=\"cursor-pointer\"\n onClick={onHomeClick}\n >\n <Icon\n className=\"text-gray-700 dark:text-slate-200\"\n name=\"ConnectSmall\"\n size={24}\n />\n </button>\n )}\n {showDebug && onDebugClick && (\n <button\n aria-label=\"Debug Settings\"\n type=\"button\"\n id=\"connect-debug-button\"\n className=\"cursor-pointer\"\n onClick={onDebugClick}\n >\n <Icon className=\"text-gray-700 dark:text-slate-200\" name=\"Tube\" />\n </button>\n )}\n <div className={onHomeClick ? \"mt-3\" : \"\"}>\n {address ? (\n <SidebarUser\n address={address}\n ensName={ensName}\n avatarUrl={avatarUrl}\n onDisconnect={onDisconnect}\n etherscanUrl={etherscanUrl}\n />\n ) : (\n <SidebarLogin onLogin={onLogin} />\n )}\n </div>\n <button\n aria-label=\"Settings\"\n type=\"button\"\n className={twMerge(onClickSettings ? \"cursor-pointer\" : \"cursor-wait\")}\n onClick={onClickSettings}\n >\n <Settings\n className=\"text-gray-700 dark:text-slate-200\"\n size={24}\n strokeWidth={2}\n />\n <span className=\"hidden text-sm/6 font-semibold text-gray-900 dark:text-slate-100\">\n Settings\n </span>\n </button>\n <ThemeSwitch />\n </SidebarFooter>\n );\n};\n","import { SidebarHeader } from \"#design-system\";\nimport type { ComponentProps } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport interface ConnectSidebarHeaderProps extends ComponentProps<\n typeof SidebarHeader\n> {}\n\nexport const ConnectSidebarHeader: React.FC<ConnectSidebarHeaderProps> = ({\n className,\n children,\n ...props\n}) => {\n if (!children) {\n return null;\n }\n\n return (\n <SidebarHeader\n {...props}\n className={twMerge(\n \"flex justify-center gap-4 border-b border-gray-300 py-4 text-gray-500 dark:bg-slate-700 dark:text-slate-100\",\n className,\n )}\n >\n {children}\n </SidebarHeader>\n );\n};\n","import { Sidebar, SidebarPanel } from \"#design-system\";\nimport type { HTMLAttributes } from \"react\";\nimport type { ConnectSidebarFooterProps } from \"./sidebar-footer.js\";\nimport { ConnectSidebarFooter } from \"./sidebar-footer.js\";\nimport type { ConnectSidebarHeaderProps } from \"./sidebar-header.js\";\nimport { ConnectSidebarHeader } from \"./sidebar-header.js\";\n\nexport interface ConnectSidebarProps\n extends\n HTMLAttributes<HTMLElement>,\n ConnectSidebarHeaderProps,\n ConnectSidebarFooterProps {\n maxWidth?: string;\n minWidth?: string;\n headerContent?: React.ReactNode;\n loadingUser?: boolean;\n onLogin: (() => void) | undefined;\n onDisconnect: (() => void) | undefined;\n etherscanUrl?: string;\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n}\n\nexport const ConnectSidebar: React.FC<ConnectSidebarProps> = ({\n onClick,\n address,\n ensName,\n avatarUrl,\n headerContent,\n onClickSettings,\n maxWidth = \"304px\",\n minWidth = \"58px\",\n onLogin,\n onDisconnect,\n etherscanUrl,\n showDebug,\n onDebugClick,\n ...props\n}) => {\n return (\n <Sidebar {...props} maxWidth={maxWidth} minWidth={minWidth}>\n <SidebarPanel>\n <ConnectSidebarHeader>{headerContent}</ConnectSidebarHeader>\n <div className=\"flex flex-col\">{props.children}</div>\n </SidebarPanel>\n <ConnectSidebarFooter\n address={address}\n ensName={ensName}\n avatarUrl={avatarUrl}\n onClickSettings={onClickSettings}\n onLogin={onLogin}\n onDisconnect={onDisconnect}\n etherscanUrl={etherscanUrl}\n onHomeClick={onClick}\n showDebug={showDebug}\n onDebugClick={onDebugClick}\n />\n </Sidebar>\n );\n};\n","type SyncStatus =\n | \"INITIAL_SYNC\"\n | \"SYNCING\"\n | \"SUCCESS\"\n | \"CONFLICT\"\n | \"MISSING\"\n | \"ERROR\";\n\nexport type FileStatus = { path: string; status?: SyncStatus };\n\n/**\n * Retrieves the sync status of a folder based on its path and their children files.\n *\n * @param folderPath - The path of the folder.\n * @param sortedFiles - The sorted list of files.\n * @returns The sync status of the folder.\n */\nexport const getFolderStatus = (\n folderPath: string,\n sortedFiles: FileStatus[],\n): SyncStatus => {\n for (const file of sortedFiles) {\n if (file.path.startsWith(folderPath)) {\n return file.status || \"SUCCESS\";\n }\n }\n\n return \"SUCCESS\";\n};\n\n/**\n * Sorts an array of files by their status.\n * The order priority is:\n * - ERROR\n * - CONFLICT\n * - SYNCING\n * - MISSING\n * - SUCCESS\n *\n * @param files - The array of files to be sorted.\n * @returns The sorted array of files.\n */\nexport const sortFilesByStatus = (files: FileStatus[]) => {\n return files.sort((a, b) => {\n const statusOrder = [\n \"ERROR\",\n \"CONFLICT\",\n \"SYNCING\",\n \"MISSING\",\n \"SYNCING\",\n \"SUCCESS\",\n ];\n\n return (\n statusOrder.indexOf(a.status || \"SUCCESS\") -\n statusOrder.indexOf(b.status || \"SUCCESS\")\n );\n });\n};\n\n/**\n * Removes files with a status of 'SUCCESS' from the given array of FileStatus objects.\n * @param files - An array of FileStatus objects.\n * @returns A new array containing only the FileStatus objects with a status other than 'SUCCESS'.\n */\nexport const removeSuccessFiles = (files: FileStatus[]) => {\n return files.filter((file) => file.status !== \"SUCCESS\");\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["Popover","PopoverContent","PopoverTrigger","AccountPopover","children","content","ConnectLoaderVideo","getDimensions","AnimatedLoader","props","style","size","delegatedProps","dimensions","_style","objectFit","pointerEvents","width","replace","height","useLayoutEffect","useRef","useState","twMerge","useEventListener","useOnClickOutside","NodeInput","props","onSubmit","onCancel","defaultValue","className","minLength","inputProps","value","setValue","ref","handleSubmit","length","e","key","setTimeout","current","focus","select","scroll","left","target","Icon","addFolder","setSelectedDrive","setSelectedNode","useDragNode","useDropNode","useSelectedDriveId","useSelectedDriveSafe","useSelectedNodePath","useUserPermissions","Fragment","useState","twMerge","NodeInput","Breadcrumbs","isAllowedToCreateDocuments","selectedDrive","selectedDriveId","selectedNodePath","isCreating","setIsCreating","onAddNew","onSubmit","name","at","id","then","node","catch","error","console","finally","onCancel","hasSelectedDrive","hasNodePath","length","undefined","state","global","header","map","parentFolder","Breadcrumb","props","parentId","onClick","isDragging","dragProps","srcId","isDropTarget","dropProps","containerStyles","Icon","useTheme","Select","components","DropdownIndicator","props","ClearIndicator","MenuList","label","onClick","rest","hasAddItemButton","children","Combobox","invalid","addItemButtonProps","theme","dark","menuListProps","menuList","dropdownIndicator","display","transition","color","padding","boxSizing","clearIndicator","baseStyles","container","borderColor","fontSize","placeholder","control","alignItems","cursor","flexWrap","justifyContent","minHeight","outline","position","backgroundColor","borderStyle","borderWidth","borderRadius","option","state","isSelected","colors","primary","primary25","primary50","primary75","danger","dangerLight","neutral0","neutral5","neutral10","neutral20","neutral30","neutral40","neutral50","neutral60","neutral70","neutral80","neutral90","PowerhouseButton","twMerge","useState","CookieBanner","props","children","cookies","submitLabel","rejectLabel","onSubmit","onReject","className","divProps","cookiesValue","setCookiesValue","handleOnChange","event","id","checked","target","prevState","map","cookie","value","buttonStyles","i","label","twMerge","defaultStyle","ModalButton","props","variant","className","rest","confirmStyle","cancelStyle","variantStyle","Modal","ModalButton","ConnectConfirmationModal","props","open","onOpenChange","header","body","cancelLabel","continueLabel","onCancel","onContinue","continueDisabled","overlayProps","contentProps","Icon","useState","twMerge","INDENT_PX","TreeItem","label","depth","expanded","selected","hasChildren","icon","onToggle","onClick","children","handleChevronClick","e","stopPropagation","paddingLeft","ColumnItem","column","typeLabel","dataType","length","slice","name","SchemaTreeSidebar","schema","tables","selectedTable","onSelectTable","onRefresh","loading","expandedNodes","setExpandedNodes","toggleNode","nodeId","prev","handleTableClick","tableName","isSchemaExpanded","handleRefreshClick","undefined","map","table","isTableExpanded","isSelected","columns","col","Icon","forwardRef","useState","twJoin","twMerge","fixedForwardRef","render","ConnectSelect","Select","props","ref","items","value","id","onChange","containerClassName","menuClassName","itemClassName","absolutePositionMenu","borderRadius","showItems","setShowItems","selectedItem","getItemByValue","onItemClick","item","disabled","find","itemsToShow","filter","map","ItemContainer","className","icon","displayValue","description","toLowerCase","Icon","useCallback","useMemo","useState","twMerge","ConnectSelect","getAvailableOperators","column","baseOperators","dataType","toLowerCase","includes","getInputType","operator","FilterClauseComponent","clause","columns","onUpdate","onRemove","showConnector","connector","onConnectorChange","find","c","name","availableOperators","inputType","showValueInput","columnItems","map","col","value","displayValue","operatorItems","op","connectorItems","handleColumnChange","columnName","newColumn","newAvailableOperators","newOperator","handleOperatorChange","handleValueChange","id","e","target","FilterBar","filters","onFiltersChange","isExpanded","setIsExpanded","handleAddFilter","newClause","Date","now","Math","random","clauses","connectors","length","handleUpdateClause","index","newClauses","handleRemoveClause","filter","_","i","newConnectors","undefined","handleConnectorChange","hasFilters","updatedClause","Icon","useState","twMerge","FilterBar","formatCellValue","value","undefined","JSON","stringify","toString","String","escapeCsvValue","includes","replace","rowToCsv","row","columns","map","column","name","join","rowsToCsv","rows","header","col","dataRows","copyToClipboard","text","navigator","clipboard","writeText","SortIcon","direction","active","TableView","pagination","onPageChange","onSort","currentSort","loading","filters","onFiltersChange","onCopyAll","offset","limit","total","currentPage","Math","floor","totalPages","ceil","startItem","endItem","min","length","goToPage","page","handleSort","columnName","newDirection","getVisiblePages","maxVisible","Array","from","_","i","start","max","end","pages","push","visiblePages","copying","setCopying","copiedRowIndex","setCopiedRowIndex","handleCopyAll","csv","setTimeout","err","console","error","handleCopyRow","rowIndex","toLocaleString","index","isActive","sortDirection","colIndex","useCallback","useEffect","useRef","useState","ConnectConfirmationModal","SchemaTreeSidebar","TableView","rowsToCsv","DEFAULT_PAGE_SIZE","DBExplorer","schema","getTables","getTableRows","getDefaultSort","pageSize","onImportDb","onExportDb","pgVersionControl","fileInputRef","tables","setTables","tablesLoading","setTablesLoading","selectedTable","setSelectedTable","tableData","setTableData","pagination","setPagination","offset","limit","total","sort","setSort","filters","setFilters","loading","setLoading","pendingImport","setPendingImport","pendingResetMajor","setPendingResetMajor","resetting","setResetting","columns","find","t","name","loadTableData","data","prev","handleCopyAll","rows","loadTables","handleRefresh","newTables","some","undefined","handleSelectTable","table","handlePageChange","handleSort","newSort","handleImportClick","current","click","handleFileChange","e","file","target","files","text","then","content","value","handleImportConfirm","handleImportCancel","handleExportClick","resetTargetMajor","supportedPgVersions","m","currentPgVersion","handleResetConfirm","onResetToPgVersion","open","newFilters","useState","DebugInspector","supportedPgVersions","currentPgVersion","onResetToPgVersion","status","setStatus","pendingMajor","setPendingMajor","confirmMajor","setConfirmMajor","error","setError","handleReset","major","err","Error","message","String","running","map","isPending","useEffect","useRef","twMerge","SEQUENCE","id","dropDelay","fallDelay","ANIM_DUR","HOLD","LAST_DROP","LAST_FALL","LOOP_TOTAL","DROP_STYLE","FALL_STYLE","PATHS","b1","b2","b3","b4","b5","b6","b7","b8","b9","b10","LogoAnimation","size","className","refsMap","timers","getEls","current","clearTimers","forEach","clearTimeout","schedule","fn","delay","push","setTimeout","resetAll","Object","values","flat","el","style","animation","opacity","runDrop","runFall","startLoop","fallStart","refFor","includes","map","LogoAnimation","DefaultEditorLoader","props","message","divProps","Icon","twJoin","twMerge","Disclosure","props","title","isOpen","onOpenChange","children","containerClassName","toggleClassName","contentClassName","twMerge","Divider","props","className","TabContent","props","label","_label","children","Content","List","Root","Trigger","React","Tabs","children","defaultValue","Children","map","child","_i","isValidElement","label","disabled","props","i","JsonViewer","useMemo","twMerge","TabContent","Tabs","formatScopeLabel","text","charAt","toUpperCase","slice","toLowerCase","DocumentStateViewer","state","ignoredScopes","defaultScope","className","scopes","Object","keys","filter","scope","includes","initialScope","at","length","map","Content","Portal","Provider","Root","Trigger","twMerge","ConnectTooltip","props","children","content","open","defaultOpen","onOpenChange","className","side","sideOffset","delayDuration","rest","ConnectTooltipProvider","Icon","formatDistanceToNow","useEffect","useState","twMerge","ConnectTooltip","HDivider","props","className","timestampUtcMs","timestamp","title","subtitle","onClick","isSelected","open","setOpen","hasContent","setTimeout","formatTimestamp","isoString","Date","addSuffix","tooltipContent","handleMouseEnter","handleMouseLeave","Icon","format","parseISO","useState","twMerge","ConnectTooltip","getBarHeight","size","formatTimestamp","isoString","date","TimelineBar","onClick","className","timestampUtcMs","timestamp","additions","deletions","addSize","delSize","isSelected","open","setOpen","noChanges","addBarHeight","delBarHeight","tooltipContent","handleMouseEnter","handleMouseLeave","useCallback","useEffect","useMemo","useRef","useState","ConnectTooltipProvider","HDivider","TimelineBar","defaultTimeLineItem","id","type","addSize","delSize","DocumentTimeline","props","timeline","onItemClick","selectedItem","setSelectedItem","scrollContainerRef","handleClick","item","mergedTimelineItems","unselectedItems","selectedItems","indexSelected","findIndex","slice","renderTimelineItems","items","map","timestampUtcMs","title","subtitle","additions","deletions","unselectedContent","selectedContent","current","scrollLeft","scrollWidth","twMerge","ToolbarContainer","props","children","className","rest","ToolbarControlsContainer","useDocumentById","redo","undo","defaultTo","filter","hasAtLeast","isTruthy","merge","pipe","prop","values","hasRevisions","document","useUndo","documentId","dispatch","canUndo","useRedo","canRedo","clipboard","useDocumentUndoRedo","undoProps","redoProps","setSelectedNode","showRevisionHistory","useDownloadDocument","useGetSwitchboardLink","useNodeParentFolderById","isDefined","twMerge","Icon","useRedo","useUndo","ToolbarButton","props","className","children","disabled","rest","ToolbarUndoButton","onClick","onClickOverride","document","undo","canUndo","header","id","makeOnClick","ToolbarRedoButton","redo","canRedo","ToolbarDownloadButton","downloadDocument","ToolbarSwitchboardButton","getSwitchboardLink","then","url","window","open","catch","error","console","ToolbarHistoryButton","ToolbarCloseButton","parentFolder","defaultOnClick","twMerge","NodeInput","ToolbarInput","props","defaultValue","className","onSubmit","onCancel","ariaLabel","useNodeActions","useNodeById","useState","twMerge","ToolbarInput","ToolbarName","props","document","inputClassName","titleClassName","isEditing","setIsEditing","node","header","id","onRenameNode","onRenameDriveNodes","documentName","name","documentId","activateEditing","cancelEditing","onSubmit","newName","Promise","all","catch","console","error","keys","ToolbarCloseButton","ToolbarDownloadButton","ToolbarHistoryButton","ToolbarRedoButton","ToolbarSwitchboardButton","ToolbarUndoButton","ToolbarName","defaultControlSlots","first","second","third","controlSlots","documentToolbarControls","defaultControlComponents","undo","redo","download","name","switchboard","history","close","defaultTo","filter","hasAtLeast","isArray","isDefined","isIncludedIn","map","pipe","prop","defaultControlComponents","defaultControlSlots","documentToolbarControls","makeIsEnabledChecker","args","enabledControls","disabledControls","control","makeToolbarControlsRenderer","document","componentOverrides","checkIsEnabled","renderComponent","Component","slot","isControlInPosition","position","makeCustomControlsRenderer","customControls","pos","controlOrControlList","renderCustomControlList","renderCustomControl","component","controls","controlsInPosition","key","useSelectedDocumentSafe","map","controlSlots","ToolbarContainer","ToolbarControlsContainer","makeCustomControlsRenderer","makeToolbarControlsRenderer","DocumentToolbar","props","selectedDocument","toolbarClassName","document","toolbarContainer","Container","children","slot","ControlsContainerSlot","controlsContainerClassName","enabledControls","disabledControls","componentOverrides","customControls","controlsContainer","ControlsContainer","renderToolbarControls","renderCustomControls","Icon","Modal","ModalButton","ConnectReplaceDuplicateModal","props","open","onOpenChange","title","fileName","message","duplicateLabel","onDuplicate","overlayProps","contentProps","defaultMessage","UploadFileItemErrorDetails","props","status","errorDetails","Icon","getDocumentIcon","documentType","UploadFileItemHeader","props","fileName","fileSize","onClose","delegatedProps","UploadFileItemProgressBar","props","status","progress","clamped","Math","min","max","width","twMerge","getStatusText","status","getStatusColor","shouldShowCTA","onOpenDocument","onFindResolution","Boolean","getCTAText","UploadFileItemStatusRow","props","progress","handleCTAClick","Math","round","forwardRef","twMerge","UploadFileItemErrorDetails","UploadFileItemHeader","UploadFileItemProgressBar","UploadFileItemStatusRow","UploadFileItem","props","ref","fileName","fileSize","status","documentType","progress","errorDetails","onClose","onOpenDocument","onFindResolution","className","delegatedProps","getUploadListTitle","count","explicitTitle","Icon","useMemo","useState","twMerge","UploadFileItem","getUploadListTitle","UploadFileList","props","items","title","defaultCollapsed","onClose","className","delegatedProps","isCollapsed","setIsCollapsed","computedTitle","length","v","map","item","idx","fileName","generateId","Date","now","Math","random","toString","substring","formatFileSize","bytes","k","sizes","i","floor","log","parseFloat","pow","toFixed","mapProgressStageToStatus","stage","mapUploadsToFileItems","uploadsArray","removeUpload","setSelectedNodeFn","onConflictResolution","filter","upload","undefined","map","fileName","fileSize","status","progress","errorDetails","documentType","onClose","id","onOpenDocument","fileNode","console","error","onFindResolution","twMerge","UploadFileList","mapUploadsToFileItems","UploadFileListContainer","props","uploadsArray","uploadsCount","removeUpload","clearAllUploads","setSelectedNode","onClose","onConflictResolution","className","delegatedProps","items","handleClose","useCallback","useEffect","useReducer","formatFileSize","generateId","mapProgressStageToStatus","uploadsReducer","state","action","type","payload","id","fileName","fileSize","status","progress","fileNode","undefined","currentUpload","stage","errorDetails","error","documentType","duplicateType","uploadToUpdate","failedUpload","removed","rest","conflictUpload","file","parentNode","filteredUploads","upload","Object","entries","useUploadTracker","useLocalStorage","driveId","getInitialState","stored","localStorage","getItem","parsed","JSON","parse","console","uploads","dispatch","setItem","stringify","createUploadHandler","onAddFile","parent","fileId","name","size","progressCallback","Error","message","removeUpload","uploadId","clearAllUploads","clearConflictedUploads","getUploadsArray","values","getUploadsCount","keys","length","resolveConflict","resolution","result","Promise","resolve","then","catch","uploadsArray","uploadsCount","Icon","setSelectedNode","useDropFile","useEffect","useState","twMerge","ConnectReplaceDuplicateModal","UploadFileListContainer","useUploadTracker","DropZone","props","title","subtitle","node","_node","enable","children","onAddFile","useLocalStorage","driveId","acceptedFileExtensions","_acceptedFileExtensions","className","delegatedProps","modalOpen","setModalOpen","conflictUploadId","setConflictUploadId","uploadsArray","uploadsCount","createUploadHandler","clearAllUploads","clearConflictedUploads","removeUpload","resolveConflict","handleAddFile","handleConflictResolution","uploadId","handleDuplicate","handleModalClose","isDropTarget","dropProps","find","u","id","fileName","undefined","useIsDragAndDropEnabled","useOnDropFile","useSelectedDriveId","DropZone","DropZoneWrapper","children","props","isDragAndDropEnabled","selectedDriveId","onDropFile","onAddFile","file","parent","onProgress","resolveConflict","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","twMerge","ConnectDropdownMenu","props","children","items","open","onItemClick","onOpenChange","menuClassName","map","id","label","icon","className","e","stopPropagation","Icon","EditorActionButtons","props","onSwitchboardLinkClick","onDownloadDocument","_onDownloadDocument","onClose","onShowRevisionHistory","onShowTimeline","Icon","twMerge","EditorUndoRedoButtons","props","canUndo","canRedo","undo","redo","buttonStyles","ImgPowerhouse","ENSAvatar","props","avatarUrl","size","style","width","height","Icon","defaultDriveOptions","defaultNodeOptions","normalNodeOptions","debugNodeOptions","nodeOptions","sharingTypeOptions","value","icon","description","disabled","locationInfoByLocation","CLOUD","title","LOCAL","SWITCHBOARD","debugNodeOptionsMap","ADD_TRIGGER","label","REMOVE_TRIGGER","ADD_INVALID_TRIGGER","folderNodeDropdownOptions","DUPLICATE","RENAME","DELETE","className","fileNodeDropdownOptions","DOWNLOAD","SYNCING","SUCCESS","CONFLICT","MISSING","ERROR","INITIAL_SYNC","syncStatuses","Icon","twMerge","CONFLICT","ERROR","INITIAL_SYNC","MISSING","SUCCESS","SYNCING","syncIcons","SyncStatusIcon","props","syncStatus","className","overrideSyncIcons","iconProps","icons","syncStatusIcons","Icon","getSyncStatusSync","setSelectedNode","showDeleteNodeModal","useDownloadDocument","useDragNode","useNodeActions","useSelectedDriveSafe","useUserPermissions","useState","addProp","entries","map","pipe","twMerge","fileNodeDropdownOptions","ConnectDropdownMenu","NodeInput","SyncStatusIcon","getDriveSharingType","drive","isReadDrive","sharingType","_sharingType","state","local","__sharingType","toUpperCase","validTypes","includes","FileItem","props","fileNode","className","customDocumentIconSrc","mode","setMode","isDropdownMenuOpen","setIsDropdownMenuOpen","selectedDrive","isDragging","dragProps","srcId","id","parentId","parentFolder","undefined","isAllowedToCreateDocuments","onRenameNode","onRenameDriveNodes","onDuplicateNode","downloadDocument","isReadMode","syncStatus","dropdownMenuHandlers","DOWNLOAD","DUPLICATE","RENAME","DELETE","dropdownMenuOptions","option","onSubmit","name","Promise","all","catch","error","console","finally","onCancel","onDropdownMenuOptionClick","itemId","handler","icon","iconNode","SUCCESS","containerStyles","content","documentType","e","stopPropagation","DefaultFileIcon","Icon","setSelectedNode","showDeleteNodeModal","useDragNode","useDropNode","useNodeActions","useUserPermissions","useState","addProp","entries","map","pipe","twMerge","folderNodeDropdownOptions","ConnectDropdownMenu","NodeInput","FolderItem","props","folderNode","className","isAllowedToCreateDocuments","mode","setMode","isDropdownMenuOpen","setIsDropdownMenuOpen","isDragging","dragProps","srcId","id","parentId","parentFolder","isDropTarget","dropProps","onRenameNode","onRenameDriveNodes","onDuplicateNode","isReadMode","onCancel","onSubmit","name","Promise","all","catch","error","console","finally","dropdownMenuHandlers","DUPLICATE","RENAME","DELETE","dropdownMenuOptions","option","onDropdownMenuOptionClick","itemId","handler","content","containerStyles","undefined","e","stopPropagation","twMerge","FooterLink","props","as","Component","className","restProps","twMerge","Footer","children","className","props","forwardRef","twJoin","twMerge","FormInput","props","ref","icon","errorMessage","isDirty","containerClassName","inputClassName","errorMessageClassName","hideErrors","delegatedProps","type","isError","Icon","Controller","ConnectSelect","appToInputOption","app","value","id","displayValue","name","icon","description","AppFormInput","props","control","appOptions","delegatedProps","items","map","field","forwardRef","Toggle","props","ref","id","forwardRef","Toggle","AvailableOfflineToggle","props","ref","twMerge","Label","props","children","className","labelProps","Controller","ConnectSelect","sharingTypeOptions","SharingTypeFormInput","props","control","delegatedProps","field","PowerhouseButton","useForm","FormInput","AppFormInput","AvailableOfflineToggle","Label","SharingTypeFormInput","AddLocalDriveForm","props","register","handleSubmit","control","formState","errors","defaultValues","name","sharingType","availableOffline","id","appOptions","e","onSubmit","required","message","Icon","DriveName","props","driveName","twMerge","locationInfoByLocation","LocationInfo","props","location","className","divProps","locationInfo","icon","title","description","PowerhouseButton","useEffect","useState","useForm","useDebounceValue","Disclosure","Divider","FormInput","AvailableOfflineToggle","DriveName","LocationInfo","AddRemoteDriveForm","props","sharingType","requestPublicDrive","remoteDriveDetails","setPublicDriveDetails","showLocationSettings","setShowLocationSettings","isUrlValid","setIsUrlValid","hasConfirmedUrl","setHasConfirmedUrl","errorMessage","setErrorMessage","url","setUrl","debouncedUrl","setDebouncedUrl","register","handleSubmit","setValue","mode","defaultValues","availableOffline","fetchPublicDrive","catch","console","error","id","name","location","undefined","message","onSubmit","e","target","value","preventDefault","useTheme","JsonView","darkTheme","lightTheme","isStrictEqual","isString","Icon","FormattedJsonViewer","props","theme","style","onClick","children","rest","value","keyName","maxLength","length","maxWidth","toString","HomeBackgroundImage","src","mixBlendMode","Icon","twMerge","HomeScreenItem","props","icon","title","description","containerClassName","shareable","onClick","slice","toUpperCase","Icon","showPHModal","HomeScreenItem","HomeScreenAddDriveItem","props","containerClassName","type","twMerge","HomeBackgroundImage","HomeScreen","props","children","containerClassName","homeBackground","undefined","Icon","useCallback","useState","twMerge","IntegrityInspector","onValidate","onRebuildKeyframes","onRebuildSnapshots","documentId","setDocumentId","branch","setBranch","status","setStatus","validationResult","setValidationResult","rebuildResult","setRebuildResult","error","setError","confirmAction","setConfirmAction","clearResults","handleValidate","trim","result","undefined","err","Error","message","String","handleRebuildKeyframes","handleRebuildSnapshots","e","target","value","ValidationResultView","totalIssues","keyframeIssues","length","snapshotIssues","isConsistent","map","issue","i","scope","revision","keyframeHash","replayedHash","snapshotHash","RebuildResultView","keyframesDeleted","scopesInvalidated","twMerge","LogoAnimation","LoadingScreen","props","showLoadingScreen","loadingComponent","size","className","Modal","twMerge","AddLocalDriveForm","AddRemoteDriveForm","TabContent","Tabs","AddDriveModal","props","handleCancel","onOpenChange","open","onAddRemoteDrive","onAddLocalDrive","requestPublicDrive","modalProps","containerProps","className","appOptions","Icon","Modal","isValidName","useCallback","useState","FormInput","ModalButton","CLOSE_ANIMATION_DURATION","CreateDocumentModal","props","onOpenChange","onContinue","overlayProps","contentProps","restProps","nodeName","setNodeName","isValid","setIsValid","handleCancel","setTimeout","handleCreate","handleSubmit","e","preventDefault","className","name","target","value","Icon","useState","FormInput","ConnectConfirmationModal","ConnectDeleteDriveModal","props","inputPlaceholder","body","driveName","confirmationModalProps","inputName","setInputName","e","target","value","ConnectConfirmationModal","ConnectDeleteItemModal","props","onDelete","deleteLabel","restProps","Icon","forwardRef","FormInput","DriveNameInput","props","ref","icon","Icon","PowerhouseButton","useState","DriveNameInput","DeleteDrive","props","drive","handleDeleteDrive","onCancel","driveNameInput","setDriveNameInput","isAllowedToDelete","header","name","deleteDrive","event","target","value","Icon","PowerhouseButton","useState","useForm","Disclosure","Divider","AvailableOfflineToggle","DeleteDrive","DriveNameInput","Label","LocationInfo","SharingTypeFormInput","DriveSettingsForm","props","drive","sharingType","availableOffline","systemInfo","onSubmit","handleDeleteDrive","name","header","showLocationSettings","setShowLocationSettings","showAbout","setShowAbout","showDangerZone","setShowDangerZone","showDeleteDrive","setShowDeleteDrive","register","handleSubmit","control","mode","defaultValues","location","e","status","version","gitHash","Icon","Modal","twMerge","Divider","DriveSettingsForm","DriveSettingsModal","props","drive","open","sharingType","availableOffline","systemInfo","onOpenChange","onDeleteDrive","onRenameDrive","onChangeSharingType","onChangeAvailableOffline","modalProps","containerProps","onSubmit","data","name","header","handleDeleteDrive","handleCancel","className","Icon","Modal","JsonViewer","toSerializableObject","obj","JSON","parse","stringify","_key","value","Error","name","message","ObjectInspectorModal","open","onOpenChange","title","object","serializableObject","className","style","height","width","maxWidth","Icon","useCallback","useEffect","useState","twMerge","ObjectInspectorModal","VIEW_COLUMN","key","label","width","COLUMNS","truncateId","id","maxLength","length","slice","sortProcessors","processors","sort","a","b","comparison","column","status","localeCompare","processorId","factoryId","driveId","processorIndex","lastOrdinal","lastError","lastErrorTimestamp","getTime","direction","SortIcon","active","undefined","ProcessorsInspector","getProcessors","onRetry","setProcessors","loading","setLoading","setSort","retryingId","setRetryingId","selectedProcessor","setSelectedProcessor","error","setError","loadProcessors","result","e","Error","message","String","interval","setInterval","clearInterval","handleRefresh","handleRetry","handleSort","columnKey","newDirection","sortedProcessors","activeCount","filter","p","erroredCount","map","index","isActive","sortDirection","processor","toISOString","toLocaleString","open","Icon","useCallback","useEffect","useState","twMerge","ObjectInspectorModal","VIEW_COLUMN","key","label","width","COLUMNS","truncateId","id","maxLength","length","slice","formatDate","dateStr","date","Date","toLocaleString","sortJobs","jobs","sort","a","b","comparison","column","localeCompare","kind","documentId","scope","branch","createdAt","retryCount","status","direction","SortIcon","active","undefined","QueueInspector","getQueueState","onPause","onResume","state","setState","isPaused","pendingJobs","executingJobs","totalPending","totalExecuting","loading","setLoading","setSort","actionInProgress","setActionInProgress","selectedJob","setSelectedJob","loadState","newState","interval","setInterval","clearInterval","handleRefresh","handlePauseResume","handleSort","columnKey","newDirection","allJobs","map","job","sortedJobs","index","isActive","sortDirection","open","twMerge","stateStyles","connected","connecting","reconnecting","error","disconnected","ConnectionStateBadge","state","failureCount","style","truncateId","id","maxLength","length","slice","Icon","SortIcon","direction","active","undefined","Icon","SyncOperationStatus","useState","twMerge","ObjectInspectorModal","truncateId","SortIcon","VIEW_COLUMN","key","label","width","COLUMNS","DEAD_LETTER_COLUMNS","toSerializableObject","obj","JSON","parse","stringify","_key","value","Error","name","message","getStatusLabel","status","Unknown","TransportPending","ExecutionPending","Applied","getStatusIcon","getErrorMessage","error","sortOperations","operations","sort","ops","a","b","comparison","column","documentId","localeCompare","branch","scopes","join","length","direction","MailboxTable","title","mailboxType","onSort","collapsed","onToggleCollapse","selectedOperation","setSelectedOperation","columns","sortedOps","handleSort","columnKey","handleCopyAll","serializable","json","navigator","clipboard","writeText","map","index","isActive","sortDirection","op","id","open","Icon","useCallback","useState","ConnectionStateBadge","MailboxTable","formatTimestamp","ms","Date","toLocaleTimeString","ChannelInspector","remoteName","channel","onBack","onRefresh","connectionState","sorts","setSorts","inbox","undefined","outbox","deadLetter","collapsed","setCollapsed","handleToggleCollapse","mailbox","prev","handleSort","columnKey","currentSort","newDirection","column","direction","getPollerControls","poller","pollerControls","pollerState","setPollerState","isPaused","isRunning","intervalMs","setIntervalMs","getIntervalMs","mailboxStates","setMailboxStates","handlePause","pause","handleResume","resume","handlePollNow","triggerNow","handleApplyInterval","handleMailboxPause","mailboxInstance","handleMailboxResume","handleMailboxFlush","flush","failureCount","state","lastSuccessUtcMs","lastFailureUtcMs","pushBlocked","pushFailureCount","e","Number","target","value","key","ackOrdinal","latestOrdinal","items","Icon","useCallback","useEffect","useMemo","useState","twMerge","ChannelInspector","ConnectionStateBadge","SortIcon","truncateId","BASE_COLUMNS","key","label","width","ACTIONS_COLUMN","formatFilter","filter","parts","branch","push","documentId","length","scope","join","sortRemotes","remotes","sort","a","b","aValue","bValue","column","id","name","collectionId","comparison","localeCompare","direction","RemotesInspector","getRemotes","removeRemote","addRemoteManual","triggerPull","connectionStates","setRemotes","loading","setLoading","setSort","selectedRemote","setSelectedRemote","manualUrl","setManualUrl","adding","setAdding","addError","setAddError","hasRowActions","columns","loadRemotes","data","handleRefresh","updated","find","r","handleSort","columnKey","newDirection","handleViewChannel","remote","handleRemove","undefined","handleBack","handleAddManual","url","trim","error","Error","message","String","handlePull","channel","get","sortedRemotes","e","target","value","map","index","isActive","sortDirection","isSortable","failureCount","state","Icon","Modal","twMerge","DBExplorer","IntegrityInspector","ProcessorsInspector","QueueInspector","RemotesInspector","TabContent","Tabs","InspectorModal","open","onOpenChange","modalProps","containerProps","dbExplorerProps","remotesInspectorProps","queueInspectorProps","processorsInspectorProps","integrityInspectorProps","defaultTab","className","style","height","width","maxWidth","useState","Modal","twMerge","buttonStyles","groupByPackage","installations","groups","Map","item","existing","get","packageName","push","documentType","set","Array","from","entries","map","documentTypes","PackageInstallModal","props","pendingInstallations","onInstall","onDismiss","open","onOpenChange","overlayProps","contentProps","restProps","installingPackages","setInstallingPackages","Set","grouped","handleInstall","prev","add","next","delete","length","isOpen","className","installing","has","join","useEffect","useRef","useState","Modal","twMerge","ReadRequiredModal","props","open","onOpenChange","header","body","closeLabel","onContinue","bodyClassName","overlayProps","contentProps","disableClose","setDisableClose","contentRef","checkScroll","element","current","scrollHeight","clientHeight","addEventListener","handleScroll","Math","ceil","scrollTop","requestAnimationFrame","removeEventListener","useState","Disclosure","PH_DEPENDENCIES","verifyPackageJsonFields","packageJson","parsed","version","dependencies","Object","fromEntries","entries","devDependencies","peerDependencies","filter","key","some","regexOrName","test","error","console","DependencyVersions","props","isOpen","setIsOpen","phCliVersion","validatedData","map","dep","replace","DependencyVersions","About","props","packageJson","phCliVersion","Icon","twMerge","capitalCase","useState","ConnectDropdownMenu","getDriveSharingType","drive","isReadDrive","sharingType","_sharingType","state","local","__sharingType","toUpperCase","validTypes","includes","DangerZone","props","className","rest","ModifyDrives","DriveList","drives","map","header","id","Drive","onDeleteDrive","isDropdownMenuOpen","setIsDropdownMenuOpen","localDriveIcon","cloudDriveIcon","publicDriveIcon","global","icon","getNodeIcon","name","label","e","stopPropagation","LocalStorage","onClearStorage","SelectFieldRaw","twMerge","DefaultEditor","props","className","rest","DefaultEditorSelect","documentModelEditor","setDocumentModelEditor","documentModelEditorOptions","value","parsePackageSpec","spec","trimmed","trim","length","name","tag","undefined","splitAt","startsWith","lastIndexOf","indexOf","slice","buildPackageSpec","Icon","twMerge","Input","Popover","PopoverContent","PopoverTrigger","useMemo","useState","resolveDefaultVersionSelection","options","distTags","versions","version","preferredTag","kind","value","latest","firstTag","Object","keys","undefined","length","VersionPicker","props","selected","onChange","disabled","className","open","setOpen","query","setQuery","tagEntries","entries","filteredTags","needle","trim","toLowerCase","filter","tag","ver","includes","filteredVersions","all","slice","reverse","v","hasAnyPickable","triggerLabel","next","e","preventDefault","target","map","isSelected","PackageAnimation","SearchAutocomplete","useCallback","useEffect","useState","buildPackageSpec","parsePackageSpec","VersionPicker","resolveDefaultVersionSelection","NPM_NAME_RE","isPlausiblePackageName","name","length","test","PackageResultCard","props","option","ctx","typedTag","selectingValue","selectLabel","selectingContent","handleSelect","baseName","label","split","value","hasVersionMetadata","distTags","Object","keys","versions","selected","setSelected","version","preferredTag","kind","includes","installSpec","isSelecting","isDisabled","disabled","description","meta","disabledLabel","PackageManagerInput","registryPackageList","onInstall","className","setTypedTag","undefined","fetchOptions","query","namePart","tag","needle","toLowerCase","localOptions","filter","pkg","manifest","map","isInstalled","status","publisher","Promise","resolve","fallbackSpec","fallbackLabel","fallbackOption","renderRow","Icon","useCallback","useEffect","useLayoutEffect","useState","twMerge","ConnectDropdownMenu","buildPackageSpec","resolveDefaultVersionSelection","VersionPicker","PackageDetail","label","value","PackageManagerListItem","props","registryPackage","onInstall","onUninstall","className","isDropdownMenuOpen","setIsDropdownMenuOpen","canPickVersion","status","hasVersionMetadata","distTags","Object","keys","length","versions","selected","setSelected","version","installDropdownItem","id","icon","uninstallDropdownItem","getDropdownItems","undefined","filter","item","dropdownItems","name","manifest","description","category","publisher","hasAnyField","url","spec","catch","console","error","e","stopPropagation","PackageManagerList","registryPackageList","maxHeight","setMaxHeight","locallyInstalledPackages","p","registryInstalledPackages","availablePackages","dismissedPackages","calculateMaxHeight","viewportHeight","window","innerHeight","availableHeight","Math","max","addEventListener","removeEventListener","hasLocallyInstalled","hasRegistryInstalled","hasAnyInstalled","hasAvailable","hasDismissed","installedCount","STORAGE_KEY","loadCollapsedSections","raw","localStorage","getItem","JSON","parse","useCollapsedSection","sectionId","collapsed","setCollapsed","current","setItem","stringify","toggle","prev","PackageSection","title","count","isEmpty","emptyText","children","contentId","PackageSubSection","PackageList","packages","map","pkg","twMerge","PackageManagerInput","PackageManagerList","PackageManager","props","registryPackageList","onInstall","onUninstall","mutable","disabled","className","Icon","Modal","useState","twMerge","SettingsModal","props","title","overlayProps","contentProps","onOpenChange","tabs","defaultTab","navFooter","restProps","selectedTab","setSelectedTab","at","id","tabsContent","map","tab","icon","label","selectedTabContent","find","content","SelectedTabComponent","className","style","boxShadow","Modal","ModalButton","ConnectUpgradeDriveModal","props","body","header","onOpenChange","onContinue","cancelLabel","continueLabel","overlayProps","contentProps","restProps","className","Icon","Branch","props","branch","Icon","useCopyToClipboard","DocId","props","docId","onCopy","copy","handleCopy","text","then","catch","error","console","Icon","useCopyToClipboard","DocumentState","props","documentState","onCopyState","copy","handleCopy","jsonState","JSON","stringify","then","catch","error","console","ConnectSelect","Scope","props","value","onChange","items","displayValue","Icon","twMerge","Branch","DocId","DocumentState","Scope","Header","props","title","docId","scope","onChangeScope","onClose","className","documentState","onCopyState","onCopyDocId","divProps","useEffect","useState","ensCache","Map","fetchEns","address","cached","get","promise","fetch","then","res","ok","Error","status","json","catch","err","delete","set","useEns","data","setData","isLoading","setIsLoading","error","setError","undefined","cancelled","finally","formatEthAddress","address","slice","Anchor","Content","Portal","Root","Trigger","useState","funnel","CodePopover","props","content","trigger","anchor","isOpen","setIsOpen","opener","triggerAt","minQuietPeriodMs","closer","open","cancel","call","close","changedIsOpen","e","preventDefault","top","right","bottom","left","useEns","formatEthAddress","CodePopover","ENSAvatar","FormattedJsonViewer","Address","props","address","chainId","data","ensData","shortenedAddress","avatar_url","undefined","Icon","twMerge","CodePopover","FormattedJsonViewer","Errors","props","errors","hasErrors","length","color","icon","text","content","Icon","CodePopover","FormattedJsonViewer","Operation","props","operationType","operationInput","Icon","CodePopover","FormattedJsonViewer","RevisionNumber","props","operationIndex","eventId","stateHash","revisionNumber","Icon","CodePopover","FormattedJsonViewer","Signature","props","signatures","length","VerificationStatus","signatureCount","verifiedSignaturesCount","filter","signature","isVerified","signatureText","verificationStatusText","color","format","CodePopover","FormattedJsonViewer","Timestamp","props","timestampUtcMs","timestamp","timestampNumber","includes","parseInt","date","Date","shortDate","longDate","timestampFormatted","memo","Address","Errors","Operation","RevisionNumber","Signature","Timestamp","_Revision","props","Revision","Skip","props","operationIndex","skipCount","revisionNumber","skippedRevisions","makeRows","operations","revisionsAndSkips","seenDays","Set","operation","timestampUtcMs","day","split","has","add","push","type","height","operationIndex","index","eventId","id","stateHash","hash","operationType","action","operationInput","input","address","context","signer","user","chainId","signatures","makeSignatures","errors","error","undefined","skip","skipCount","getUniqueDatesInOrder","dates","date","Array","from","sort","a","b","Date","getTime","makeSignatureFromSignatureArray","signatureArray","signerAddress","prevStateHash","signatureBytes","isVerified","signaturesArray","map","Icon","format","Day","props","timestampUtcMs","timestamp","formattedDate","useVirtualizer","useEffect","useMemo","useRef","useState","Revision","Skip","makeRows","Day","Timeline","props","localOperations","globalOperations","scope","operations","initialNumRowsToShow","allRows","scrollAmount","setScrollAmount","numRowsToShow","setNumRowsToShow","rows","setRows","slice","parentRef","hasNextPage","length","rowVirtualizer","count","getScrollElement","current","estimateSize","i","height","gap","ratio","Math","floor","newNumRevisions","prev","handleScroll","e","n","deltaY","window","addEventListener","removeEventListener","getTotalSize","width","position","getVirtualItems","map","virtualRow","row","index","top","left","size","transform","start","type","key","Pagination","usePagination","garbageCollect","sortOperations","useMemo","useState","ConnectTooltipProvider","Header","Timeline","RevisionHistory","props","documentTitle","documentId","globalOperations","localOperations","onClose","itemsPerPage","documentState","onCopyState","onCopyDocId","scope","setScope","visibleOperations","operations","sort","a","b","index","pageItems","pages","goToPage","goToNextPage","goToPreviousPage","goToFirstPage","goToLastPage","hiddenNextPages","isNextPageAvailable","isPreviousPageAvailable","onChangeScope","showPagination","length","PaginationComponent","twMerge","FilterItem","props","item","className","containerProps","icon","label","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","Icon","useMemo","twMerge","FilterItem","ConnectSearchBar","props","value","onChange","placeholder","filterLabel","filterItems","selectedFilter","onFilterSelect","className","items","map","item","id","content","selectedItemFilter","find","filterLabelContent","handleChange","event","target","twMerge","ConnectTooltip","SidebarItem","props","icon","title","description","_description","containerClassName","active","onClick","slice","toUpperCase","Icon","SidebarItem","SidebarAddDriveItem","props","containerClassName","onClick","Icon","useState","twMerge","AccountPopoverLogin","onLogin","loading","setLoading","allowLogin","content","handleLogin","undefined","renownShortDark","renownShortHoverDark","renownShortHover","renownShort","useTheme","twMerge","AccountPopoverLogin","AccountPopover","SidebarLogin","onLogin","content","theme","isDark","src","hoverSrc","Icon","PowerhouseButton","useCallback","useState","twMerge","shortAddress","address","slice","AccountPopoverUser","onDisconnect","etherscanUrl","username","isCopied","setIsCopied","copyToClipboard","text","navigator","clipboard","writeText","setTimeout","err","console","error","AccountPopoverUser","AccountPopover","ENSAvatar","SidebarUser","address","ensName","avatarUrl","etherscanUrl","onDisconnect","content","Icon","SidebarFooter","Settings","twMerge","SidebarLogin","SidebarUser","ConnectSidebarFooter","address","ensName","avatarUrl","className","onLogin","onClickSettings","onDisconnect","onHomeClick","showDebug","onDebugClick","etherscanUrl","props","SidebarHeader","twMerge","ConnectSidebarHeader","className","children","props","Sidebar","SidebarPanel","ConnectSidebarFooter","ConnectSidebarHeader","ConnectSidebar","onClick","address","ensName","avatarUrl","headerContent","onClickSettings","maxWidth","minWidth","onLogin","onDisconnect","etherscanUrl","showDebug","onDebugClick","props","children","useTheme","Monitor","Moon","Sun","twMerge","OPTIONS","value","Icon","label","ThemeSwitch","horizontal","theme","isSystem","setTheme","select","val","isActive","map","e","key","getFolderStatus","folderPath","sortedFiles","file","path","startsWith","status","sortFilesByStatus","files","sort","a","b","statusOrder","indexOf","removeSuccessFiles","filter"],"sources":["../../src/connect/components/account-popover/account-popover.tsx","../../assets/connect-loader.mp4","../../src/connect/components/animated-loader/animated-loader.tsx","../../src/connect/components/node-input/node-input.tsx","../../src/connect/components/breadcrumbs/breadcrumbs.tsx","../../src/connect/components/combobox/combobox.tsx","../../src/connect/components/cookie-banner/cookie-banner.tsx","../../src/connect/components/modal/modal-button.tsx","../../src/connect/components/modal/confirmation-modal.tsx","../../src/connect/components/db-explorer/components/schema-tree-sidebar.tsx","../../src/connect/components/select/select.tsx","../../src/connect/components/db-explorer/components/filter-bar.tsx","../../src/connect/components/db-explorer/components/table-view.tsx","../../src/connect/components/db-explorer/db-explorer.tsx","../../src/connect/components/debug-inspector/debug-inspector.tsx","../../src/connect/components/logo-animation.tsx","../../src/connect/components/default-editor-loader/default-editor-loader.tsx","../../src/connect/components/disclosure/disclosure.tsx","../../src/connect/components/divider/divider.tsx","../../src/connect/components/tabs/tab-content.tsx","../../src/connect/components/tabs/tabs.tsx","../../src/connect/components/document-state-viewer/document-state-viewer.tsx","../../src/connect/components/tooltip/tooltip.tsx","../../src/connect/components/document-timeline/components/h-divider.tsx","../../src/connect/components/document-timeline/components/timeline-bar.tsx","../../src/connect/components/document-timeline/document-timeline.tsx","../../src/connect/components/document-toolbar/containers.tsx","../../src/connect/components/document-toolbar/use-document-undo-redo.ts","../../src/connect/components/document-toolbar/toolbar-button.tsx","../../src/connect/components/document-toolbar/toolbar-input.tsx","../../src/connect/components/document-toolbar/toolbar-name.tsx","../../src/connect/components/document-toolbar/constants.ts","../../src/connect/components/document-toolbar/utils.tsx","../../src/connect/components/document-toolbar/document-toolbar.tsx","../../src/connect/components/modal/replace-duplicate-modal.tsx","../../src/connect/components/upload-file-item/components/error-details.tsx","../../src/connect/components/upload-file-item/components/header.tsx","../../src/connect/components/upload-file-item/components/progress-bar.tsx","../../src/connect/components/upload-file-item/components/status-row.tsx","../../src/connect/components/upload-file-item/upload-file-item.tsx","../../src/connect/components/upload-file-list/utils.ts","../../src/connect/components/upload-file-list/upload-file-list.tsx","../../src/connect/components/drop-zone/utils.ts","../../src/connect/components/drop-zone/upload-file-list-container.tsx","../../src/connect/components/drop-zone/use-upload-tracker.ts","../../src/connect/components/drop-zone/drop-zone.tsx","../../src/connect/components/drop-zone/drop-zone-wrapper.tsx","../../src/connect/components/dropdown-menu/dropdown-menu.tsx","../../src/connect/components/editor-action-buttons/editor-action-buttons.tsx","../../src/connect/components/editor-undo-redo-buttons/editor-undo-redo-buttons.tsx","../../assets/powerhouse-rounded.png","../../src/connect/components/ens-avatar/ens-avatar.tsx","../../src/connect/constants/options.tsx","../../src/connect/constants/syncing.ts","../../src/connect/components/status-icon/sync-status-icon.tsx","../../src/connect/components/file-item/file-item.tsx","../../src/connect/components/folder-item/folder-item.tsx","../../src/connect/components/footer/footer-link.tsx","../../src/connect/components/footer/footer.tsx","../../src/connect/components/form-input/form-input.tsx","../../src/connect/components/form/inputs/app-form-input.tsx","../../src/connect/components/toggle/toggle.tsx","../../src/connect/components/form/inputs/available-offline-toggle.tsx","../../src/connect/components/form/inputs/label.tsx","../../src/connect/components/form/inputs/sharing-type-form-input.tsx","../../src/connect/components/form/add-local-drive-form.tsx","../../src/connect/components/form/inputs/drive-name.tsx","../../src/connect/components/form/inputs/location-info.tsx","../../src/connect/components/form/add-remote-drive-form.tsx","../../src/connect/components/formatted-json-viewer.tsx","../../src/connect/components/home-screen/home-background-image.tsx","../../src/connect/components/home-screen/home-screen-item.tsx","../../src/connect/components/home-screen/home-screen-add-drive-item.tsx","../../src/connect/components/home-screen/home-screen.tsx","../../src/connect/components/integrity-inspector/integrity-inspector.tsx","../../src/connect/components/loading-screen/loading-screen.tsx","../../src/connect/components/modal/add-drive-modal/add-drive-modal.tsx","../../src/connect/components/modal/create-document-modal.tsx","../../src/connect/components/modal/delete-drive-modal.tsx","../../src/connect/components/modal/delete-item-modal.tsx","../../src/connect/components/form/inputs/drive-name-input.tsx","../../src/connect/components/form/inputs/delete-drive.tsx","../../src/connect/components/form/drive-settings-form.tsx","../../src/connect/components/modal/drive-settings-modal.tsx","../../src/connect/components/object-inspector-modal/object-inspector-modal.tsx","../../src/connect/components/processors-inspector/processors-inspector.tsx","../../src/connect/components/queue-inspector/queue-inspector.tsx","../../src/connect/components/remotes-inspector/components/connection-state-badge.tsx","../../src/connect/components/remotes-inspector/utils.ts","../../src/connect/components/remotes-inspector/components/sort-icon.tsx","../../src/connect/components/remotes-inspector/components/mailbox-table.tsx","../../src/connect/components/remotes-inspector/components/channel-inspector.tsx","../../src/connect/components/remotes-inspector/remotes-inspector.tsx","../../src/connect/components/modal/inspector-modal/inspector-modal.tsx","../../src/connect/components/modal/missing-package-modal.tsx","../../src/connect/components/modal/read-required-modal.tsx","../../src/connect/components/modal/settings-modal/dependency-versions/dependency-versions.tsx","../../src/connect/components/modal/settings-modal-v2/about.tsx","../../src/connect/components/modal/settings-modal-v2/danger-zone.tsx","../../src/connect/components/modal/settings-modal-v2/default-editor.tsx","../../src/connect/components/modal/settings-modal-v2/package-manager/parse-package-spec.ts","../../src/connect/components/modal/settings-modal-v2/package-manager/version-picker.tsx","../../src/connect/components/modal/settings-modal-v2/package-manager/package-manager-input.tsx","../../src/connect/components/modal/settings-modal-v2/package-manager/package-manager-list.tsx","../../src/connect/components/modal/settings-modal-v2/package-manager/package-manager.tsx","../../src/connect/components/modal/settings-modal-v2/settings-modal.tsx","../../src/connect/components/modal/upgrade-drive-modal.tsx","../../src/connect/components/revision-history/header/branch.tsx","../../src/connect/components/revision-history/header/doc-id.tsx","../../src/connect/components/revision-history/header/document-state.tsx","../../src/connect/components/revision-history/header/scope.tsx","../../src/connect/components/revision-history/header/header.tsx","../../src/connect/hooks/use-ens.ts","../../src/connect/utils/address.ts","../../src/connect/components/code-popover.tsx","../../src/connect/components/revision-history/revision/address.tsx","../../src/connect/components/revision-history/revision/errors.tsx","../../src/connect/components/revision-history/revision/operation.tsx","../../src/connect/components/revision-history/revision/revision-number.tsx","../../src/connect/components/revision-history/revision/signature.tsx","../../src/connect/components/revision-history/revision/timestamp.tsx","../../src/connect/components/revision-history/revision/revision.tsx","../../src/connect/components/revision-history/skip/skip.tsx","../../src/connect/components/revision-history/utils.ts","../../src/connect/components/revision-history/timeline/day.tsx","../../src/connect/components/revision-history/timeline/timeline.tsx","../../src/connect/components/revision-history/revision-history.tsx","../../src/connect/components/search-bar/filter-item.tsx","../../src/connect/components/search-bar/search-bar.tsx","../../src/connect/components/sidebar/sidebar-item.tsx","../../src/connect/components/sidebar/sidebar-add-drive-item.tsx","../../assets/renown-short-dark.png","../../assets/renown-short-hover-dark.png","../../assets/renown-short-hover.png","../../assets/renown-short.png","../../src/connect/components/account-popover/account-popover-login.tsx","../../src/connect/components/sidebar/sidebar-login.tsx","../../src/connect/components/account-popover/account-popover-user.tsx","../../src/connect/components/sidebar/sidebar-user.tsx","../../src/connect/components/sidebar/sidebar-footer.tsx","../../src/connect/components/sidebar/sidebar-header.tsx","../../src/connect/components/sidebar/sidebar.tsx","../../src/connect/components/theme-switch.tsx","../../src/connect/utils/get-folder-status.ts"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"#design-system/ui\";\n\nexport interface AccountPopoverProps {\n children: ReactNode;\n content: ReactNode;\n}\n\nexport const AccountPopover = ({ children, content }: AccountPopoverProps) => {\n return (\n <Popover>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n aria-label=\"Open Account\"\n className=\"cursor-pointer\"\n >\n {children}\n </button>\n </PopoverTrigger>\n <PopoverContent className=\"w-52 p-0\" align=\"start\">\n {content}\n </PopoverContent>\n </Popover>\n );\n};\n","\"data:video/mp4;base64,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\"","import ConnectLoaderVideo from \"#assets/connect-loader.mp4\";\nimport type { Size } from \"#design-system\";\nimport { getDimensions } from \"#design-system\";\nimport type { ComponentPropsWithoutRef, CSSProperties } from \"react\";\n\ntype Props = ComponentPropsWithoutRef<\"video\"> & {\n readonly size?: Size;\n};\nexport function AnimatedLoader(props: Props) {\n const { style, size = 100, ...delegatedProps } = props;\n\n const dimensions = getDimensions(size);\n\n const _style: CSSProperties = {\n objectFit: \"contain\",\n pointerEvents: \"none\",\n ...dimensions,\n ...style,\n };\n\n const width = dimensions.width?.replace(\"px\", \"\");\n const height = dimensions.height?.replace(\"px\", \"\");\n\n return (\n <video\n autoPlay\n height={height}\n loop\n muted\n playsInline\n width={width}\n {...delegatedProps}\n style={_style}\n >\n <source src={ConnectLoaderVideo} type=\"video/mp4\" />\n </video>\n );\n}\n","import { useLayoutEffect, useRef, useState, type RefObject } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { useEventListener, useOnClickOutside } from \"usehooks-ts\";\n\ntype Props = {\n readonly name?: string;\n readonly defaultValue?: string;\n readonly placeholder?: string;\n readonly \"aria-label\"?: string;\n readonly className?: string;\n readonly minLength?: number;\n readonly onSubmit: (value: string) => void;\n readonly onCancel: () => void;\n};\nexport function NodeInput(props: Props) {\n const {\n onSubmit,\n onCancel,\n defaultValue,\n className,\n minLength = 1,\n ...inputProps\n } = props;\n const [value, setValue] = useState(defaultValue ?? \"\");\n\n const ref = useRef<HTMLInputElement>(null);\n\n function handleSubmit() {\n if (value.length >= minLength) {\n onSubmit(value);\n }\n }\n\n useOnClickOutside(ref as RefObject<HTMLElement>, handleSubmit);\n\n useEventListener(\"keyup\", (e) => {\n if (e.key === \"Enter\") {\n handleSubmit();\n }\n if (e.key === \"Escape\") {\n onCancel();\n }\n });\n\n useLayoutEffect(() => {\n setTimeout(() => {\n ref.current?.focus();\n ref.current?.select();\n ref.current?.scroll({ left: 9999 });\n }, 100);\n }, []);\n\n return (\n <input\n {...inputProps}\n autoFocus\n className={twMerge(\"bg-inherit text-inherit outline-none\", className)}\n minLength={minLength}\n onChange={(e) => setValue(e.target.value)}\n ref={ref}\n required\n type=\"text\"\n value={value}\n />\n );\n}\n","import { Icon } from \"#design-system\";\nimport {\n addFolder,\n setSelectedDrive,\n setSelectedNode,\n useDragNode,\n useDropNode,\n useSelectedDriveId,\n useSelectedDriveSafe,\n useSelectedNodePath,\n useUserPermissions,\n} from \"@powerhousedao/reactor-browser\";\nimport { Fragment, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { NodeInput } from \"../node-input/node-input.js\";\n\nexport function Breadcrumbs() {\n const { isAllowedToCreateDocuments } = useUserPermissions();\n const [selectedDrive] = useSelectedDriveSafe();\n const selectedDriveId = useSelectedDriveId();\n const selectedNodePath = useSelectedNodePath();\n const [isCreating, setIsCreating] = useState(false);\n function onAddNew() {\n setIsCreating(true);\n }\n\n function onSubmit(name: string) {\n if (!isAllowedToCreateDocuments || !selectedDriveId) return;\n\n addFolder(selectedDriveId, name, selectedNodePath.at(-1)?.id)\n .then((node) => {\n setSelectedNode(node);\n })\n .catch((error) => {\n console.error(error);\n })\n .finally(() => {\n setIsCreating(false);\n });\n }\n\n function onCancel() {\n setIsCreating(false);\n }\n\n const hasSelectedDrive = !!selectedDrive;\n const hasNodePath = !!selectedNodePath.length;\n\n return (\n <div className=\"flex h-9 flex-row items-center gap-2 p-6 text-gray-500 dark:text-slate-400\">\n {hasSelectedDrive && (\n <>\n <button\n type=\"button\"\n aria-label=\"Back to home\"\n title=\"Back to home\"\n className=\"flex items-center justify-center rounded-md p-1 text-gray-700 transition-colors hover:bg-gray-100 hover:text-gray-800 dark:text-slate-200 dark:hover:bg-slate-700 dark:hover:text-slate-100\"\n onClick={() => setSelectedDrive(undefined)}\n >\n <Icon name=\"ArrowLeft\" size={14} />\n </button>\n <Breadcrumb\n id={selectedDriveId}\n parentId={undefined}\n name={selectedDrive.state.global.name || selectedDrive.header.name}\n onClick={() => setSelectedDrive(selectedDrive)}\n />\n <span>/</span>\n </>\n )}\n {hasNodePath &&\n selectedNodePath.map((node) => (\n <Fragment key={node.id}>\n <Breadcrumb\n id={node.id}\n parentId={node.parentFolder}\n name={node.name}\n onClick={() => setSelectedNode(node)}\n />\n <span>/</span>\n </Fragment>\n ))}\n {isAllowedToCreateDocuments &&\n (isCreating ? (\n <NodeInput\n className=\"text-gray-900 dark:text-slate-100\"\n defaultValue=\"New Folder\"\n onCancel={onCancel}\n onSubmit={onSubmit}\n placeholder=\"New Folder\"\n />\n ) : (\n <button\n type=\"button\"\n className=\"ml-1 flex items-center justify-center gap-2 rounded-md bg-gray-50 px-2 py-1.5 text-gray-700 transition-colors hover:bg-gray-200 hover:text-gray-800 dark:bg-slate-800 dark:text-slate-200 dark:hover:bg-slate-600 dark:hover:text-slate-100\"\n onClick={onAddNew}\n >\n <Icon name=\"Plus\" size={14} />\n Add new\n </button>\n ))}\n </div>\n );\n}\n\nexport type BreadcrumbProps = {\n name: string;\n id: string | undefined;\n parentId: string | null | undefined;\n onClick: () => void;\n};\n\nexport function Breadcrumb(props: BreadcrumbProps) {\n const { name, id, parentId, onClick } = props;\n const { isDragging, ...dragProps } = useDragNode({\n srcId: id,\n parentId: parentId ?? undefined,\n });\n const { isDropTarget, ...dropProps } = useDropNode(id);\n\n const containerStyles = twMerge(\n \"cursor-pointer transition-colors last-of-type:text-gray-800 hover:text-gray-800 dark:text-slate-200 last-of-type:dark:text-slate-100 dark:hover:text-slate-100\",\n isDragging\n ? \"opacity-60\"\n : isDropTarget\n ? \"bg-blue-100 dark:bg-blue-800\"\n : \"\",\n );\n\n return (\n <div\n {...dragProps}\n {...dropProps}\n className={containerStyles}\n onClick={onClick}\n role=\"button\"\n >\n {name}\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { useTheme } from \"@powerhousedao/reactor-browser\";\nimport type { ComponentPropsWithoutRef, ReactNode } from \"react\";\nimport type {\n ClearIndicatorProps,\n DropdownIndicatorProps,\n MenuListProps,\n} from \"react-select\";\nimport Select, { components } from \"react-select\";\n\ntype SelectProps = ComponentPropsWithoutRef<typeof Select>;\n\ntype Props = Omit<SelectProps, \"components\" | \"styles\" | \"theme\"> & {\n readonly addItemButtonProps?: {\n label?: ReactNode;\n onClick?: () => void;\n };\n};\n\nfunction DropdownIndicator(props: DropdownIndicatorProps) {\n return (\n <components.DropdownIndicator {...props}>\n <Icon name=\"ChevronDown\" size={16} />\n </components.DropdownIndicator>\n );\n}\n\nfunction ClearIndicator(props: ClearIndicatorProps) {\n return (\n <components.ClearIndicator {...props}>\n <Icon name=\"Xmark\" size={16} />\n </components.ClearIndicator>\n );\n}\n\nfunction MenuList(\n props: MenuListProps & {\n readonly label?: ReactNode;\n readonly onClick?: () => void;\n },\n) {\n const { label, onClick, ...rest } = props;\n\n const hasAddItemButton = !!label && !!onClick;\n\n return (\n <components.MenuList {...rest}>\n {props.children}\n {hasAddItemButton ? (\n <button\n className=\"w-full px-2 py-3 hover:bg-gray-50 dark:hover:bg-slate-800\"\n onClick={onClick}\n >\n {label}\n </button>\n ) : null}\n </components.MenuList>\n );\n}\n\nexport function Combobox(props: Props) {\n const invalid = props[\"aria-invalid\"] === \"true\";\n const { addItemButtonProps, ...rest } = props;\n const { theme } = useTheme();\n const dark = theme === \"dark\";\n\n return (\n <Select\n {...rest}\n components={{\n DropdownIndicator,\n ClearIndicator,\n MenuList: (menuListProps) =>\n MenuList({ ...menuListProps, ...addItemButtonProps }),\n }}\n classNames={{\n menuList: () =>\n \"scrollbar-thin scrollbar-track-transparent scrollbar-thumb-rounded-md scrollbar-thumb-gray-300 dark:scrollbar-thumb-slate-600\",\n }}\n styles={{\n dropdownIndicator: () => {\n return {\n label: \"indicatorContainer\",\n display: \"flex\",\n transition: \"color 150ms\",\n color: dark ? \"var(--color-slate-50)\" : \"var(--color-gray-900)\",\n padding: 8,\n boxSizing: \"border-box\",\n };\n },\n clearIndicator: (baseStyles) => {\n return {\n ...baseStyles,\n color: dark ? \"var(--color-slate-50)\" : \"var(--color-gray-900)\",\n };\n },\n container: (baseStyles) => {\n return {\n ...baseStyles,\n borderColor: dark\n ? \"var(--color-slate-700)\"\n : \"var(--color-gray-200)\",\n fontSize: 12,\n };\n },\n placeholder: (baseStyles) => {\n return {\n ...baseStyles,\n color: invalid\n ? dark\n ? \"var(--color-red-400)\"\n : \"var(--color-red-800)\"\n : dark\n ? \"var(--color-slate-100)\"\n : \"var(--color-gray-500)\",\n };\n },\n control: () => {\n return {\n label: \"control\",\n alignItems: \"center\",\n cursor: \"default\",\n display: \"flex\",\n flexWrap: \"wrap\",\n justifyContent: \"space-between\",\n minHeight: 32,\n outline: \"0 !important\",\n position: \"relative\",\n transition: \"all 100ms\",\n backgroundColor: dark\n ? \"var(--color-slate-800)\"\n : \"var(--color-white)\",\n borderColor: invalid\n ? dark\n ? \"var(--color-red-400)\"\n : \"var(--color-red-900)\"\n : dark\n ? \"var(--color-slate-600)\"\n : \"var(--color-gray-200)\",\n borderStyle: \"solid\",\n borderWidth: 1,\n borderRadius: \"6px\",\n boxSizing: \"border-box\",\n };\n },\n option: (baseStyles, state) => {\n return {\n ...baseStyles,\n backgroundColor: state.isSelected\n ? dark\n ? \"var(--color-slate-700)\"\n : \"var(--color-slate-50)\"\n : dark\n ? \"var(--color-slate-800)\"\n : \"var(--color-white)\",\n color: dark ? \"var(--color-slate-50)\" : \"var(--color-gray-800)\",\n \":hover\": {\n backgroundColor: dark\n ? \"var(--color-slate-700)\"\n : \"var(--color-slate-50)\",\n },\n };\n },\n menuList: (baseStyles) => ({\n ...baseStyles,\n padding: 0,\n borderRadius: \"6px\",\n }),\n }}\n theme={(theme) => ({\n ...theme,\n colors: {\n ...theme.colors,\n primary: dark ? \"var(--color-slate-700)\" : \"var(--color-slate-100)\",\n primary25: dark ? \"var(--color-slate-800)\" : \"var(--color-slate-50)\",\n primary50: dark ? \"var(--color-slate-700)\" : \"var(--color-slate-100)\",\n primary75: dark ? \"var(--color-slate-700)\" : \"var(--color-slate-100)\",\n danger: dark ? \"var(--color-red-400)\" : \"var(--color-red-900)\",\n dangerLight: dark ? \"var(--color-red-900)\" : \"var(--color-red-100)\",\n neutral0: dark ? \"var(--color-slate-800)\" : \"var(--color-white)\",\n neutral5: dark ? \"var(--color-slate-800)\" : \"var(--color-gray-50)\",\n neutral10: dark ? \"var(--color-slate-700)\" : \"var(--color-gray-100)\",\n neutral20: dark ? \"var(--color-slate-600)\" : \"var(--color-gray-200)\",\n neutral30: dark ? \"var(--color-slate-600)\" : \"var(--color-gray-300)\",\n neutral40: dark ? \"var(--color-slate-400)\" : \"var(--color-gray-400)\",\n neutral50: dark ? \"var(--color-slate-300)\" : \"var(--color-gray-500)\",\n neutral60: dark ? \"var(--color-slate-200)\" : \"var(--color-gray-600)\",\n neutral70: dark ? \"var(--color-slate-100)\" : \"var(--color-gray-700)\",\n neutral80: dark ? \"var(--color-slate-50)\" : \"var(--color-gray-800)\",\n neutral90: dark ? \"var(--color-slate-50)\" : \"var(--color-gray-900)\",\n },\n })}\n />\n );\n}\n","import { PowerhouseButton } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\nimport { useState } from \"react\";\n\nexport type CookieInput = {\n id: string;\n label: string;\n value: boolean;\n};\n\nexport interface CookieBannerProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n \"onSubmit\"\n> {\n cookies: CookieInput[];\n submitLabel?: string;\n rejectLabel?: string;\n onSubmit?: (cookies: CookieInput[]) => void;\n onReject?: () => void;\n}\n\nexport const CookieBanner: React.FC<CookieBannerProps> = (props) => {\n const {\n children,\n cookies,\n submitLabel,\n rejectLabel,\n onSubmit = () => {},\n onReject = () => {},\n className,\n ...divProps\n } = props;\n\n const [cookiesValue, setCookiesValue] = useState(cookies);\n\n const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const { id, checked } = event.target;\n\n setCookiesValue((prevState) =>\n prevState.map((cookie) =>\n cookie.id === id ? { ...cookie, value: checked } : cookie,\n ),\n );\n };\n\n const buttonStyles = \"min-w-64 h-8 text-base\";\n\n return (\n <div\n className={twMerge(\n \"flex flex-col items-center\",\n typeof className === \"string\" && className,\n )}\n {...divProps}\n >\n <div className=\"text-center\">{children}</div>\n <div className=\"my-8 flex gap-x-16 text-sm font-medium\">\n {cookiesValue.map((cookie, i) => (\n <div className=\"cursor-pointer\" key={i}>\n <input\n checked={cookie.value}\n className=\"mr-1 size-3 cursor-pointer rounded-sm border-2 border-gray-900 accent-gray-900 focus:outline-none dark:border-slate-50\"\n id={cookie.id}\n onChange={handleOnChange}\n type=\"checkbox\"\n />\n <label\n className=\"cursor-pointer text-gray-900 select-none dark:text-slate-50\"\n htmlFor={cookie.id}\n >\n {cookie.label}\n </label>\n </div>\n ))}\n </div>\n <div className=\"flex gap-x-8\">\n <PowerhouseButton\n className={buttonStyles}\n color=\"light\"\n onClick={() => onReject()}\n size=\"small\"\n key={\"button-reject\"}\n >\n {rejectLabel}\n </PowerhouseButton>\n <PowerhouseButton\n className={buttonStyles}\n onClick={() => onSubmit(cookiesValue)}\n size=\"small\"\n key={\"button-submit\"}\n >\n {submitLabel}\n </PowerhouseButton>\n </div>\n </div>\n );\n};\n","import type { ComponentProps } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\nconst defaultStyle =\n \"min-h-12 min-w-35.5 flex-1 transform place-items-center rounded-xl px-6 py-3 text-base font-semibold transition-all outline-none hover:scale-105 active:opacity-75 disabled:cursor-not-allowed disabled:hover:scale-none\";\n\nexport function ModalButton(\n props: ComponentProps<\"button\"> & { variant: \"confirm\" | \"cancel\" },\n) {\n const { variant, className, ...rest } = props;\n const confirmStyle = twMerge(\n defaultStyle,\n \"bg-gray-800 text-gray-50 dark:bg-slate-100 dark:text-slate-900\",\n );\n const cancelStyle = twMerge(\n defaultStyle,\n \"bg-gray-400 text-gray-50 dark:bg-slate-400 dark:text-slate-900\",\n );\n const variantStyle = twMerge(\n variant === \"confirm\" ? confirmStyle : cancelStyle,\n className,\n );\n return <button className={variantStyle} {...rest} />;\n}\n","import { Modal } from \"#design-system\";\nimport type { ComponentPropsWithoutRef, ReactNode } from \"react\";\nimport { ModalButton } from \"./modal-button.js\";\n\ntype ModalProps = ComponentPropsWithoutRef<typeof Modal>;\n\nexport type ConfirmationModalProps = {\n readonly open?: boolean;\n readonly onOpenChange?: (open: boolean) => void;\n readonly header: ReactNode;\n readonly body?: ReactNode;\n readonly cancelLabel: string;\n readonly continueLabel: string;\n readonly onCancel: () => void;\n readonly onContinue: () => void;\n readonly continueDisabled?: boolean;\n readonly overlayProps?: ModalProps[\"overlayProps\"];\n readonly contentProps?: ModalProps[\"contentProps\"];\n};\n\nexport function ConnectConfirmationModal(props: ConfirmationModalProps) {\n const {\n open,\n onOpenChange,\n header,\n body,\n cancelLabel,\n continueLabel,\n onCancel,\n onContinue,\n continueDisabled,\n overlayProps,\n contentProps,\n } = props;\n\n return (\n <Modal\n open={open}\n onOpenChange={onOpenChange}\n overlayProps={overlayProps}\n contentProps={contentProps}\n >\n <div className=\"w-[400px] p-6\">\n <div className=\"pb-2 text-2xl font-bold text-gray-900 dark:text-slate-100\">\n {header}\n </div>\n <div className=\"my-6 rounded-md bg-gray-50 p-4 text-center text-gray-900 dark:bg-slate-700 dark:text-slate-100\">\n {body}\n </div>\n <div className=\"mt-8 flex justify-between gap-3\">\n <ModalButton variant=\"cancel\" onClick={onCancel}>\n {cancelLabel}\n </ModalButton>\n <ModalButton\n variant=\"confirm\"\n disabled={continueDisabled}\n onClick={onContinue}\n >\n {continueLabel}\n </ModalButton>\n </div>\n </div>\n </Modal>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport type { ColumnInfo } from \"./table-view.js\";\n\nexport type TableInfo = {\n readonly name: string;\n readonly columns: ColumnInfo[];\n};\n\ntype TreeExpandedState = Record<string, boolean>;\n\nexport type SchemaTreeSidebarProps = {\n readonly schema: string;\n readonly tables: TableInfo[];\n readonly selectedTable?: string;\n readonly onSelectTable: (table: string) => void;\n readonly onRefresh?: () => void | Promise<void>;\n readonly loading?: boolean;\n};\n\ntype TreeItemProps = {\n readonly label: React.ReactNode;\n readonly depth: number;\n readonly expanded?: boolean;\n readonly selected?: boolean;\n readonly hasChildren?: boolean;\n readonly icon?: React.ReactNode;\n readonly onToggle?: () => void;\n readonly onClick?: () => void;\n readonly children?: React.ReactNode;\n};\n\nconst INDENT_PX = 16;\n\nfunction TreeItem({\n label,\n depth,\n expanded,\n selected,\n hasChildren,\n icon,\n onToggle,\n onClick,\n children,\n}: TreeItemProps) {\n const handleChevronClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n onToggle?.();\n };\n\n return (\n <div>\n <div\n className={twMerge(\n \"flex cursor-pointer items-center gap-1 py-1 pr-2 text-sm hover:bg-gray-100 dark:hover:bg-slate-700\",\n selected && \"bg-blue-50 dark:bg-blue-900\",\n )}\n style={{ paddingLeft: depth * INDENT_PX + 4 }}\n onClick={onClick}\n >\n {hasChildren ? (\n <button\n className=\"flex size-4 shrink-0 items-center justify-center text-gray-500 hover:text-gray-700 dark:text-slate-200 dark:hover:text-slate-100\"\n onClick={handleChevronClick}\n type=\"button\"\n >\n <Icon\n className={twMerge(\n \"transition-transform\",\n expanded && \"rotate-90\",\n )}\n name=\"CaretRight\"\n size={12}\n />\n </button>\n ) : (\n <span className=\"w-4 shrink-0\" />\n )}\n {icon && (\n <span className=\"shrink-0 text-gray-500 dark:text-slate-400\">\n {icon}\n </span>\n )}\n <span className=\"min-w-0 flex-1 truncate text-gray-700 dark:text-slate-200\">\n {label}\n </span>\n {selected && (\n <span className=\"ml-auto size-2 shrink-0 rounded-full bg-blue-500 dark:bg-blue-400\" />\n )}\n </div>\n {expanded && children}\n </div>\n );\n}\n\nfunction ColumnItem({\n column,\n depth,\n}: {\n readonly column: ColumnInfo;\n readonly depth: number;\n}) {\n const typeLabel =\n column.dataType.length > 10\n ? column.dataType.slice(0, 10) + \"…\"\n : column.dataType;\n\n return (\n <div\n className=\"flex items-center gap-1 py-0.5 pr-2 text-xs text-gray-500 dark:text-slate-200\"\n style={{ paddingLeft: depth * INDENT_PX + 4 }}\n >\n <span className=\"w-4 shrink-0\" />\n <span className=\"truncate\">{column.name}</span>\n <span className=\"ml-auto shrink-0 text-gray-400 dark:text-slate-200\">\n ({typeLabel})\n </span>\n </div>\n );\n}\n\nexport function SchemaTreeSidebar({\n schema,\n tables,\n selectedTable,\n onSelectTable,\n onRefresh,\n loading,\n}: SchemaTreeSidebarProps) {\n const [expandedNodes, setExpandedNodes] = useState<TreeExpandedState>({\n [schema]: true,\n });\n\n const toggleNode = (nodeId: string) => {\n setExpandedNodes((prev) => ({\n ...prev,\n [nodeId]: !prev[nodeId],\n }));\n };\n\n const handleTableClick = (tableName: string) => {\n onSelectTable(tableName);\n setExpandedNodes((prev) => ({\n ...prev,\n [tableName]: !prev[tableName],\n }));\n };\n\n const isSchemaExpanded = expandedNodes[schema] ?? false;\n\n const handleRefreshClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n void onRefresh?.();\n };\n\n return (\n <div className=\"flex flex-col overflow-auto pt-4 text-sm\">\n <TreeItem\n depth={0}\n expanded={isSchemaExpanded}\n hasChildren={tables.length > 0}\n icon={\n <Icon\n name={isSchemaExpanded ? \"FolderOpen\" : \"FolderClose\"}\n size={16}\n />\n }\n label={\n <div className=\"flex flex-1 items-center\">\n <span className=\"truncate\">{schema}</span>\n {onRefresh && (\n <button\n className=\"ml-auto p-0.5 text-gray-400 hover:text-gray-600 dark:text-slate-200 dark:hover:text-slate-100\"\n onClick={handleRefreshClick}\n type=\"button\"\n disabled={loading}\n >\n <Icon\n name=\"Reload\"\n size={14}\n className={loading ? \"animate-spin\" : undefined}\n />\n </button>\n )}\n </div>\n }\n onClick={() => toggleNode(schema)}\n onToggle={() => toggleNode(schema)}\n >\n {tables.map((table) => {\n const isTableExpanded = expandedNodes[table.name] ?? false;\n const isSelected = selectedTable === table.name;\n\n return (\n <TreeItem\n key={table.name}\n depth={1}\n expanded={isTableExpanded}\n hasChildren={table.columns.length > 0}\n icon={<Icon name=\"TreeViewSlash\" size={16} />}\n label={table.name}\n selected={isSelected}\n onClick={() => handleTableClick(table.name)}\n onToggle={() => toggleNode(table.name)}\n >\n {table.columns.map((col) => (\n <ColumnItem key={col.name} column={col} depth={2} />\n ))}\n </TreeItem>\n );\n })}\n </TreeItem>\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport type {\n CSSProperties,\n ForwardedRef,\n ReactNode,\n Ref,\n RefAttributes,\n} from \"react\";\nimport { forwardRef, useState } from \"react\";\nimport { twJoin, twMerge } from \"tailwind-merge\";\n\nexport type ConnectSelectItem<TValue extends string> = {\n readonly value: TValue;\n readonly displayValue?: React.ReactNode;\n readonly description?: React.ReactNode;\n readonly icon?: React.JSX.Element;\n readonly disabled?: boolean;\n};\n\nexport type ConnectSelectProps<TValue extends string> = {\n items: readonly ConnectSelectItem<TValue>[];\n value: TValue;\n id: string;\n onChange: (value: TValue) => void;\n containerClassName?: string;\n menuClassName?: string;\n itemClassName?: string;\n borderRadius?: CSSProperties[\"borderRadius\"];\n absolutePositionMenu?: boolean;\n};\n\nfunction fixedForwardRef<T, P = Record<string, never>>(\n render: (props: P, ref: Ref<T>) => ReactNode,\n): (props: P & RefAttributes<T>) => ReactNode {\n // @ts-expect-error - This is a hack to make the types work\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return forwardRef(render) as any;\n}\n\nexport const ConnectSelect = /* @__PURE__ */ fixedForwardRef(function Select<\n TValue extends string,\n>(props: ConnectSelectProps<TValue>, ref: ForwardedRef<HTMLDivElement>) {\n const {\n items,\n value,\n id,\n onChange,\n containerClassName,\n menuClassName,\n itemClassName,\n absolutePositionMenu = false,\n borderRadius = \"6px\",\n } = props;\n const [showItems, setShowItems] = useState(false);\n const selectedItem = getItemByValue(value) ?? items[0];\n function onItemClick(item: ConnectSelectItem<TValue>) {\n if (item.disabled) return;\n onChange(item.value);\n setShowItems(false);\n }\n function getItemByValue(value: TValue) {\n return items.find((item) => item.value === value);\n }\n\n const itemsToShow = items.filter((item) => item.value !== value);\n\n return (\n <div\n className={twMerge(\n \"border border-gray-200 bg-gray-50 text-gray-900 transition-[border-radius] dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n absolutePositionMenu && \"relative\",\n containerClassName,\n )}\n data-open={showItems}\n ref={ref}\n style={{\n borderRadius: borderRadius,\n }}\n >\n <div\n className={twMerge(\n \"flex min-w-[360px] cursor-pointer items-center justify-between pr-3 text-gray-900 outline-none dark:text-slate-100\",\n menuClassName,\n )}\n id={id}\n onClick={() => setShowItems(!showItems)}\n >\n <ItemContainer {...selectedItem} className={itemClassName} />\n <Icon\n className={twJoin(\"transition\", showItems ? \"\" : \"-rotate-90\")}\n name=\"ChevronDown\"\n />\n </div>\n <div\n className={twMerge(\n \"max-h-0 w-full overflow-hidden bg-inherit transition-[max-height] ease-in-out\",\n showItems && \"max-h-screen\",\n absolutePositionMenu && \"absolute\",\n )}\n style={{\n borderRadius: `0 0 ${borderRadius} ${borderRadius}`,\n }}\n >\n {itemsToShow.map((item) => (\n <ItemContainer\n key={item.value}\n {...item}\n className={itemClassName}\n onItemClick={() => onItemClick(item)}\n />\n ))}\n </div>\n </div>\n );\n});\n\nfunction ItemContainer<TValue extends string>(\n props: ConnectSelectItem<TValue> & {\n readonly onItemClick?: () => void;\n readonly className?: string;\n },\n) {\n const {\n className,\n disabled,\n onItemClick,\n icon,\n displayValue,\n value,\n description,\n } = props;\n\n return (\n <div\n className={twMerge(\n disabled\n ? \"cursor-not-allowed text-gray-500 dark:text-slate-400\"\n : \"text-gray-900 dark:text-slate-100\",\n \"flex size-full cursor-pointer items-center gap-2 bg-inherit py-3 pl-3 text-start outline-none\",\n className,\n )}\n onClick={onItemClick}\n >\n {icon}\n <div>\n <p className=\"text-inherit capitalize\">\n {displayValue ?? value.toLowerCase()}\n </p>\n <p className=\"text-xs text-gray-700 dark:text-slate-200\">\n {description}\n </p>\n </div>\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ConnectSelect } from \"../../select/select.js\";\nimport type {\n ColumnInfo,\n FilterClause,\n FilterGroup,\n FilterOperator,\n} from \"./table-view.js\";\n\nexport type FilterBarProps = {\n readonly columns: ColumnInfo[];\n readonly filters: FilterGroup | undefined;\n readonly onFiltersChange: (filters: FilterGroup | undefined) => void;\n};\n\nfunction getAvailableOperators(column: ColumnInfo): FilterOperator[] {\n const baseOperators: FilterOperator[] = [\n \"=\",\n \"!=\",\n \">\",\n \"<\",\n \">=\",\n \"<=\",\n \"IS NULL\",\n \"IS NOT NULL\",\n ];\n\n const dataType = column.dataType.toLowerCase();\n\n // Text types get LIKE and ILIKE\n if (\n dataType.includes(\"varchar\") ||\n dataType.includes(\"text\") ||\n dataType.includes(\"char\")\n ) {\n return [...baseOperators, \"LIKE\", \"ILIKE\"];\n }\n\n // Numeric types don't get LIKE/ILIKE\n if (\n dataType.includes(\"int\") ||\n dataType.includes(\"decimal\") ||\n dataType.includes(\"numeric\") ||\n dataType.includes(\"real\") ||\n dataType.includes(\"double\") ||\n dataType.includes(\"float\") ||\n dataType.includes(\"bigint\") ||\n dataType.includes(\"smallint\")\n ) {\n return baseOperators;\n }\n\n // Default: all operators except LIKE/ILIKE\n return baseOperators;\n}\n\nfunction getInputType(\n column: ColumnInfo,\n operator: FilterOperator,\n): \"text\" | \"number\" | \"datetime-local\" {\n if (operator === \"IS NULL\" || operator === \"IS NOT NULL\") {\n return \"text\"; // Will be hidden anyway\n }\n\n const dataType = column.dataType.toLowerCase();\n\n if (\n dataType.includes(\"int\") ||\n dataType.includes(\"decimal\") ||\n dataType.includes(\"numeric\") ||\n dataType.includes(\"real\") ||\n dataType.includes(\"double\") ||\n dataType.includes(\"float\") ||\n dataType.includes(\"bigint\") ||\n dataType.includes(\"smallint\")\n ) {\n return \"number\";\n }\n\n if (\n dataType.includes(\"timestamp\") ||\n dataType.includes(\"date\") ||\n dataType.includes(\"time\")\n ) {\n return \"datetime-local\";\n }\n\n return \"text\";\n}\n\nfunction FilterClauseComponent({\n clause,\n columns,\n onUpdate,\n onRemove,\n showConnector,\n connector,\n onConnectorChange,\n}: {\n readonly clause: FilterClause;\n readonly columns: ColumnInfo[];\n readonly onUpdate: (clause: FilterClause) => void;\n readonly onRemove: () => void;\n readonly showConnector: boolean;\n readonly connector: \"AND\" | \"OR\";\n readonly onConnectorChange: (connector: \"AND\" | \"OR\") => void;\n}) {\n const column = columns.find((c) => c.name === clause.column);\n const availableOperators = column\n ? getAvailableOperators(column)\n : ([\"=\", \"!=\"] as FilterOperator[]);\n const inputType = column ? getInputType(column, clause.operator) : \"text\";\n const showValueInput =\n clause.operator !== \"IS NULL\" && clause.operator !== \"IS NOT NULL\";\n\n const columnItems = useMemo(\n (): Array<{ value: string; displayValue: string }> =>\n columns.map((col) => ({\n value: col.name,\n displayValue: col.name,\n })),\n [columns],\n );\n\n const operatorItems = useMemo(\n (): Array<{ value: FilterOperator; displayValue: string }> =>\n availableOperators.map((op) => ({\n value: op,\n displayValue: op,\n })),\n [availableOperators],\n );\n\n const connectorItems = useMemo(\n (): Array<{ value: \"AND\" | \"OR\"; displayValue: string }> => [\n { value: \"AND\", displayValue: \"AND\" },\n { value: \"OR\", displayValue: \"OR\" },\n ],\n [],\n );\n\n const handleColumnChange = useCallback(\n (columnName: string) => {\n const newColumn = columns.find((c) => c.name === columnName);\n if (!newColumn) return;\n\n const newAvailableOperators = getAvailableOperators(newColumn);\n const newOperator = newAvailableOperators.includes(clause.operator)\n ? clause.operator\n : newAvailableOperators[0];\n\n onUpdate({\n ...clause,\n column: columnName,\n operator: newOperator,\n value: \"\",\n });\n },\n [clause, columns, onUpdate],\n );\n\n const handleOperatorChange = useCallback(\n (operator: FilterOperator) => {\n onUpdate({\n ...clause,\n operator,\n value:\n operator === \"IS NULL\" || operator === \"IS NOT NULL\"\n ? \"\"\n : clause.value,\n });\n },\n [clause, onUpdate],\n );\n\n const handleValueChange = useCallback(\n (value: string) => {\n onUpdate({\n ...clause,\n value,\n });\n },\n [clause, onUpdate],\n );\n\n return (\n <div className=\"flex items-center gap-2\">\n {showConnector && (\n <ConnectSelect<\"AND\" | \"OR\">\n absolutePositionMenu\n borderRadius=\"4px\"\n containerClassName=\"min-w-[80px]\"\n id={`connector-${clause.id}`}\n items={connectorItems}\n itemClassName=\"px-2 py-1 text-xs\"\n menuClassName=\"px-2 py-1 text-xs min-w-[80px]\"\n value={connector}\n onChange={onConnectorChange}\n />\n )}\n <ConnectSelect<string>\n absolutePositionMenu\n borderRadius=\"4px\"\n containerClassName=\"min-w-[150px]\"\n id={`column-${clause.id}`}\n items={columnItems}\n itemClassName=\"px-2 py-1 text-xs\"\n menuClassName=\"px-2 py-1 text-xs min-w-[150px]\"\n value={clause.column}\n onChange={handleColumnChange}\n />\n <ConnectSelect<FilterOperator>\n absolutePositionMenu\n borderRadius=\"4px\"\n containerClassName=\"min-w-[100px]\"\n id={`operator-${clause.id}`}\n items={operatorItems}\n itemClassName=\"px-2 py-1 text-xs\"\n menuClassName=\"px-2 py-1 text-xs min-w-[100px]\"\n value={clause.operator}\n onChange={handleOperatorChange}\n />\n {showValueInput && (\n <input\n className=\"min-w-[150px] rounded-sm border border-gray-300 bg-gray-50 px-2 py-1 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\"\n type={inputType}\n value={clause.value}\n onChange={(e) => handleValueChange(e.target.value)}\n />\n )}\n <button\n className=\"flex items-center justify-center rounded-sm p-1 text-gray-500 hover:bg-gray-200 hover:text-gray-700 dark:text-slate-400 dark:hover:bg-slate-600 dark:hover:text-slate-100\"\n onClick={onRemove}\n title=\"Remove filter\"\n type=\"button\"\n >\n <Icon name=\"Xmark\" size={14} />\n </button>\n </div>\n );\n}\n\nexport function FilterBar({\n columns,\n filters,\n onFiltersChange,\n}: FilterBarProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const handleAddFilter = useCallback(() => {\n const newClause: FilterClause = {\n id: `filter-${Date.now()}-${Math.random()}`,\n column: columns[0]?.name ?? \"\",\n operator: \"=\",\n value: \"\",\n };\n\n if (!filters) {\n onFiltersChange({\n clauses: [newClause],\n connectors: [],\n });\n } else {\n onFiltersChange({\n clauses: [...filters.clauses, newClause],\n connectors: [\n ...filters.connectors,\n filters.clauses.length > 0 ? \"AND\" : (\"AND\" as const),\n ],\n });\n }\n setIsExpanded(true);\n }, [columns, filters, onFiltersChange]);\n\n const handleUpdateClause = useCallback(\n (index: number, clause: FilterClause) => {\n if (!filters) return;\n\n const newClauses = [...filters.clauses];\n newClauses[index] = clause;\n\n onFiltersChange({\n ...filters,\n clauses: newClauses,\n });\n },\n [filters, onFiltersChange],\n );\n\n const handleRemoveClause = useCallback(\n (index: number) => {\n if (!filters) return;\n\n const newClauses = filters.clauses.filter((_, i) => i !== index);\n const newConnectors = filters.connectors.filter(\n (_, i) => i !== index - 1,\n );\n\n if (newClauses.length === 0) {\n onFiltersChange(undefined);\n } else {\n onFiltersChange({\n clauses: newClauses,\n connectors: newConnectors,\n });\n }\n },\n [filters, onFiltersChange],\n );\n\n const handleConnectorChange = useCallback(\n (index: number, connector: \"AND\" | \"OR\") => {\n if (!filters) return;\n\n const newConnectors = [...filters.connectors];\n newConnectors[index] = connector;\n\n onFiltersChange({\n ...filters,\n connectors: newConnectors,\n });\n },\n [filters, onFiltersChange],\n );\n\n const hasFilters = filters && filters.clauses.length > 0;\n\n return (\n <div className=\"flex shrink-0 flex-col gap-2 rounded-lg border border-gray-300 bg-gray-50 p-2 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <div className=\"flex items-center justify-between\">\n <button\n className=\"flex items-center gap-1 text-xs text-gray-700 hover:text-gray-900 dark:text-slate-200 dark:hover:text-slate-50\"\n onClick={() => setIsExpanded(!isExpanded)}\n type=\"button\"\n >\n <Icon\n className={twMerge(\n \"transition-transform\",\n isExpanded && \"rotate-90\",\n )}\n name=\"ChevronDown\"\n size={12}\n />\n <span>Filters</span>\n {hasFilters && (\n <span className=\"rounded-sm bg-blue-100 px-1.5 py-0.5 text-xs text-blue-700 dark:bg-blue-800 dark:text-blue-100\">\n {filters.clauses.length}\n </span>\n )}\n </button>\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-2 py-1 text-xs text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={handleAddFilter}\n type=\"button\"\n >\n <Icon name=\"Plus\" size={12} />\n Add Filter\n </button>\n </div>\n\n {isExpanded && hasFilters && (\n <div className=\"flex flex-col gap-2\">\n {filters.clauses.map((clause, index) => (\n <FilterClauseComponent\n key={clause.id}\n clause={clause}\n columns={columns}\n connector={\n index > 0 ? (filters.connectors[index - 1] ?? \"AND\") : \"AND\"\n }\n onConnectorChange={(connector) =>\n handleConnectorChange(index - 1, connector)\n }\n onRemove={() => handleRemoveClause(index)}\n onUpdate={(updatedClause) =>\n handleUpdateClause(index, updatedClause)\n }\n showConnector={index > 0}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { FilterBar } from \"./filter-bar.js\";\n\nexport type ColumnInfo = {\n readonly name: string;\n readonly dataType: string;\n readonly isNullable: boolean;\n};\n\nexport type SortDirection = \"asc\" | \"desc\";\n\nexport type SortOptions = {\n readonly column: string;\n readonly direction: SortDirection;\n};\n\nexport type FilterOperator =\n | \"=\"\n | \"!=\"\n | \">\"\n | \"<\"\n | \">=\"\n | \"<=\"\n | \"LIKE\"\n | \"ILIKE\"\n | \"IS NULL\"\n | \"IS NOT NULL\";\n\nexport type FilterClause = {\n readonly id: string;\n readonly column: string;\n readonly operator: FilterOperator;\n readonly value: string;\n};\n\nexport type FilterGroup = {\n readonly clauses: FilterClause[];\n readonly connectors: (\"AND\" | \"OR\")[]; // connectors[i] connects clauses[i] and clauses[i+1]\n};\n\nexport type PaginationState = {\n readonly offset: number;\n readonly limit: number;\n readonly total: number | null;\n};\n\nexport type TableViewProps = {\n readonly columns: ColumnInfo[];\n readonly rows: Record<string, unknown>[];\n readonly pagination: PaginationState;\n readonly onPageChange: (offset: number) => void;\n readonly onSort?: (sort: SortOptions) => void;\n readonly currentSort?: SortOptions;\n readonly loading?: boolean;\n readonly filters?: FilterGroup;\n readonly onFiltersChange?: (filters: FilterGroup | undefined) => void;\n /** Callback to get all rows as CSV. If provided, \"Copy All\" copies all pages. */\n readonly onCopyAll?: () => Promise<string>;\n};\n\nfunction formatCellValue(value: unknown): string {\n if (value === null) return \"NULL\";\n if (value === undefined) return \"\";\n if (typeof value === \"object\") return JSON.stringify(value);\n if (typeof value === \"function\") return \"[function]\";\n if (typeof value === \"symbol\") return value.toString();\n return String(value as string | number | boolean | bigint);\n}\n\nfunction escapeCsvValue(value: string): string {\n // If the value contains comma, newline, or double quote, wrap it in quotes and escape quotes\n if (value.includes(\",\") || value.includes(\"\\n\") || value.includes('\"')) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n }\n return value;\n}\n\nfunction rowToCsv(row: Record<string, unknown>, columns: ColumnInfo[]): string {\n return columns\n .map((column) => {\n const value = formatCellValue(row[column.name]);\n return escapeCsvValue(value);\n })\n .join(\",\");\n}\n\nexport function rowsToCsv(\n rows: Record<string, unknown>[],\n columns: ColumnInfo[],\n): string {\n const header = columns.map((col) => escapeCsvValue(col.name)).join(\",\");\n const dataRows = rows.map((row) => rowToCsv(row, columns));\n return [header, ...dataRows].join(\"\\n\");\n}\n\nasync function copyToClipboard(text: string): Promise<void> {\n await navigator.clipboard.writeText(text);\n}\n\nfunction SortIcon({\n direction,\n active,\n}: {\n readonly direction: SortDirection;\n readonly active: boolean;\n}) {\n if (!active) {\n return (\n <Icon\n className=\"opacity-0 group-hover:opacity-50\"\n name=\"CaretSort\"\n size={12}\n />\n );\n }\n\n return (\n <Icon\n className={direction === \"asc\" ? \"rotate-180\" : undefined}\n name=\"TriangleDown\"\n size={12}\n />\n );\n}\n\nexport function TableView({\n columns,\n rows,\n pagination,\n onPageChange,\n onSort,\n currentSort,\n loading = false,\n filters,\n onFiltersChange,\n onCopyAll,\n}: TableViewProps) {\n const { offset, limit, total } = pagination;\n\n const currentPage = Math.floor(offset / limit);\n const totalPages = total !== null ? Math.ceil(total / limit) : 0;\n const startItem = total === 0 ? 0 : offset + 1;\n const endItem =\n total !== null ? Math.min(offset + limit, total) : offset + rows.length;\n\n const goToPage = (page: number) => {\n onPageChange(page * limit);\n };\n\n const handleSort = (columnName: string) => {\n if (!onSort) return;\n\n const newDirection: SortDirection =\n currentSort?.column === columnName && currentSort.direction === \"asc\"\n ? \"desc\"\n : \"asc\";\n\n onSort({ column: columnName, direction: newDirection });\n };\n\n const getVisiblePages = (): number[] => {\n const maxVisible = 3;\n\n if (totalPages <= maxVisible) {\n return Array.from({ length: totalPages }, (_, i) => i);\n }\n\n const start = Math.max(\n 0,\n Math.min(currentPage - 1, totalPages - maxVisible),\n );\n const end = Math.min(totalPages - 1, start + maxVisible - 1);\n\n const pages: number[] = [];\n for (let i = start; i <= end; i++) {\n pages.push(i);\n }\n\n return pages;\n };\n\n const visiblePages = getVisiblePages();\n const [copying, setCopying] = useState(false);\n const [copiedRowIndex, setCopiedRowIndex] = useState<number | null>(null);\n\n const handleCopyAll = async () => {\n if (rows.length === 0) return;\n setCopying(true);\n try {\n // If onCopyAll is provided, use it to get all rows; otherwise copy visible rows\n const csv = onCopyAll ? await onCopyAll() : rowsToCsv(rows, columns);\n await copyToClipboard(csv);\n setTimeout(() => setCopying(false), 1000);\n } catch (err) {\n console.error(\"Failed to copy to clipboard:\", err);\n setCopying(false);\n }\n };\n\n const handleCopyRow = async (rowIndex: number) => {\n if (rowIndex < 0 || rowIndex >= rows.length) return;\n setCopiedRowIndex(rowIndex);\n try {\n const csv = rowToCsv(rows[rowIndex], columns);\n await copyToClipboard(csv);\n setTimeout(() => setCopiedRowIndex(null), 1000);\n } catch (err) {\n console.error(\"Failed to copy to clipboard:\", err);\n setCopiedRowIndex(null);\n }\n };\n\n return (\n <div className=\"flex h-full flex-col gap-2\">\n {onFiltersChange && (\n <FilterBar\n columns={columns}\n filters={filters}\n onFiltersChange={onFiltersChange}\n />\n )}\n <div className=\"flex shrink-0 items-center justify-between text-sm\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-gray-700 dark:text-slate-200\">\n {loading\n ? \"Loading...\"\n : total !== null\n ? `Showing ${startItem.toLocaleString()}-${endItem.toLocaleString()} of ${total.toLocaleString()}`\n : `Showing ${rows.length.toLocaleString()} rows`}\n </span>\n {rows.length > 0 && (\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-2 py-1 text-xs text-gray-700 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={loading || copying}\n onClick={() => void handleCopyAll()}\n title=\"Copy all rows as CSV\"\n type=\"button\"\n >\n <Icon name={copying ? \"Check\" : \"Copy\"} size={14} />\n {copying ? \"Copied!\" : \"Copy All\"}\n </button>\n )}\n </div>\n\n {total !== null && total > limit && (\n <div className=\"flex gap-1\">\n <button\n className=\"rounded-sm border border-gray-300 bg-gray-50 px-2 py-1 text-xs text-gray-700 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={currentPage === 0}\n onClick={() => goToPage(0)}\n type=\"button\"\n >\n First\n </button>\n <button\n className=\"rounded-sm border border-gray-300 bg-gray-50 px-2 py-1 text-xs text-gray-700 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={currentPage === 0}\n onClick={() => goToPage(currentPage - 1)}\n type=\"button\"\n >\n <Icon className=\"rotate-90\" name=\"ChevronDown\" size={14} />\n </button>\n\n {visiblePages[0] > 0 && (\n <span className=\"flex items-center px-1 text-xs text-gray-500 dark:text-slate-400\">\n ...\n </span>\n )}\n\n {visiblePages.map((page) => (\n <button\n key={page}\n className={twMerge(\n \"min-w-8 rounded-sm border px-2 py-1 text-xs\",\n page === currentPage\n ? \"border-blue-500 bg-blue-50 text-blue-700 dark:border-blue-400 dark:bg-blue-900 dark:text-blue-100\"\n : \"border-gray-300 bg-gray-50 text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\",\n )}\n onClick={() => goToPage(page)}\n type=\"button\"\n >\n {page + 1}\n </button>\n ))}\n\n {visiblePages[visiblePages.length - 1] < totalPages - 1 && (\n <span className=\"flex items-center px-1 text-xs text-gray-500 dark:text-slate-400\">\n ...\n </span>\n )}\n\n <button\n className=\"rounded-sm border border-gray-300 bg-gray-50 px-2 py-1 text-xs text-gray-700 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={currentPage >= totalPages - 1}\n onClick={() => goToPage(currentPage + 1)}\n type=\"button\"\n >\n <Icon className=\"-rotate-90\" name=\"ChevronDown\" size={14} />\n </button>\n <button\n className=\"rounded-sm border border-gray-300 bg-gray-50 px-2 py-1 text-xs text-gray-700 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={currentPage >= totalPages - 1}\n onClick={() => goToPage(totalPages - 1)}\n type=\"button\"\n >\n Last\n </button>\n </div>\n )}\n </div>\n\n <div\n className={twMerge(\n \"max-h-full overflow-auto rounded-lg border border-gray-300 transition-opacity dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n \"scrollbar-thin scrollbar-thumb-rounded-md scrollbar-track-transparent\",\n \"scrollbar-thumb-gray-300 dark:scrollbar-thumb-slate-600\",\n loading && \"pointer-events-none opacity-50\",\n )}\n >\n <table className=\"w-full border-collapse\">\n <thead className=\"sticky top-0 bg-gray-100 dark:bg-slate-700\">\n <tr>\n <th className=\"w-12 p-2 text-center text-xs font-medium text-gray-700 dark:text-slate-200\">\n <span className=\"sr-only\">Copy</span>\n </th>\n {columns.map((column, index) => {\n const isActive = currentSort?.column === column.name;\n const sortDirection = isActive ? currentSort.direction : \"asc\";\n\n return (\n <th\n key={column.name}\n className={twMerge(\n \"group px-3 py-2 text-left text-xs font-medium text-gray-700 dark:text-slate-200\",\n index > 0 &&\n \"border-l border-gray-300 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n onSort &&\n \"cursor-pointer hover:bg-gray-200 hover:text-gray-900 dark:hover:bg-slate-600 dark:hover:text-slate-100\",\n )}\n onClick={() => onSort && handleSort(column.name)}\n >\n <div className=\"flex items-center gap-1\">\n <span className=\"truncate\">{column.name}</span>\n {onSort && (\n <SortIcon active={isActive} direction={sortDirection} />\n )}\n </div>\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {rows.length === 0 ? (\n <tr>\n <td\n className=\"px-3 py-8 text-center text-sm text-gray-500 dark:text-slate-400\"\n colSpan={columns.length + 1}\n >\n No data\n </td>\n </tr>\n ) : (\n rows.map((row, rowIndex) => (\n <tr\n key={rowIndex}\n className=\"odd:bg-white even:bg-gray-50 hover:bg-blue-50 dark:odd:bg-slate-800 dark:even:bg-slate-800 dark:hover:bg-blue-900\"\n >\n <td className=\"p-2 text-center\">\n <button\n className=\"flex items-center justify-center rounded-sm p-1 text-gray-500 hover:bg-gray-200 hover:text-gray-700 dark:text-slate-400 dark:hover:bg-slate-600 dark:hover:text-slate-100\"\n onClick={() => void handleCopyRow(rowIndex)}\n title=\"Copy row as CSV\"\n type=\"button\"\n >\n <Icon\n name={copiedRowIndex === rowIndex ? \"Check\" : \"Copy\"}\n size={14}\n />\n </button>\n </td>\n {columns.map((column, colIndex) => (\n <td\n key={column.name}\n className={twMerge(\n \"px-3 py-2 text-xs text-gray-900 dark:text-slate-50\",\n colIndex > 0 &&\n \"border-l border-gray-300 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n )}\n >\n <span\n className={twMerge(\n \"block truncate\",\n row[column.name] === null &&\n \"text-gray-400 italic dark:text-slate-500\",\n )}\n title={formatCellValue(row[column.name])}\n >\n {formatCellValue(row[column.name])}\n </span>\n </td>\n ))}\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n </div>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { ConnectConfirmationModal } from \"../modal/confirmation-modal.js\";\nimport {\n SchemaTreeSidebar,\n type TableInfo,\n} from \"./components/schema-tree-sidebar.js\";\nimport {\n TableView,\n rowsToCsv,\n type ColumnInfo,\n type FilterGroup,\n type PaginationState,\n type SortOptions,\n} from \"./components/table-view.js\";\n\n// Re-export types\nexport type { TableInfo } from \"./components/schema-tree-sidebar.js\";\nexport type {\n ColumnInfo,\n FilterClause,\n FilterGroup,\n SortOptions,\n} from \"./components/table-view.js\";\n\nexport type GetTableRowsOptions = {\n readonly schema?: string;\n readonly limit: number;\n readonly offset: number;\n readonly sort?: SortOptions;\n readonly filters?: FilterGroup;\n};\n\nexport type TablePage = {\n readonly columns: string[];\n readonly rows: Record<string, unknown>[];\n readonly total: number | null;\n};\nexport interface DbClient {\n readonly kind: string;\n listTables(schema?: string): Promise<string[]>;\n getTableSchema(table: string, schema?: string): Promise<ColumnInfo[]>;\n getTableRows(table: string, options: GetTableRowsOptions): Promise<TablePage>;\n}\n\nexport type PgVersionControl = {\n readonly currentPgVersion: number | null;\n readonly supportedPgVersions: readonly number[];\n readonly onResetToPgVersion: (major: number) => void | Promise<void>;\n};\n\n/** Props for the main DBExplorer component */\nexport type DBExplorerProps = {\n readonly schema: string;\n readonly getTables: () => Promise<TableInfo[]>;\n readonly getTableRows: (\n table: string,\n options: GetTableRowsOptions,\n ) => Promise<TablePage>;\n readonly getDefaultSort?: (table: string) => SortOptions | undefined;\n readonly pageSize?: number;\n readonly onImportDb?: (sqlContent: string) => void | Promise<void>;\n readonly onExportDb?: () => void | Promise<void>;\n readonly pgVersionControl?: PgVersionControl;\n};\n\nconst DEFAULT_PAGE_SIZE = 50;\n\nexport function DBExplorer({\n schema,\n getTables,\n getTableRows,\n getDefaultSort,\n pageSize = DEFAULT_PAGE_SIZE,\n onImportDb,\n onExportDb,\n pgVersionControl,\n}: DBExplorerProps) {\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [tables, setTables] = useState<TableInfo[]>([]);\n const [tablesLoading, setTablesLoading] = useState(true);\n const [selectedTable, setSelectedTable] = useState<string | undefined>();\n const [tableData, setTableData] = useState<TablePage | null>(null);\n const [pagination, setPagination] = useState<PaginationState>({\n offset: 0,\n limit: pageSize,\n total: null,\n });\n const [sort, setSort] = useState<SortOptions | undefined>();\n const [filters, setFilters] = useState<FilterGroup | undefined>();\n const [loading, setLoading] = useState(false);\n const [pendingImport, setPendingImport] = useState<string | null>(null);\n const [pendingResetMajor, setPendingResetMajor] = useState<number | null>(\n null,\n );\n const [resetting, setResetting] = useState(false);\n\n const columns = tables.find((t) => t.name === selectedTable)?.columns ?? [];\n\n const loadTableData = useCallback(async () => {\n if (!selectedTable) return;\n\n setLoading(true);\n const data = await getTableRows(selectedTable, {\n schema,\n limit: pagination.limit,\n offset: pagination.offset,\n sort,\n filters,\n });\n setTableData(data);\n setPagination((prev) => ({ ...prev, total: data.total }));\n setLoading(false);\n }, [\n selectedTable,\n schema,\n pagination.limit,\n pagination.offset,\n sort,\n filters,\n getTableRows,\n ]);\n\n const handleCopyAll = useCallback(async (): Promise<string> => {\n if (!selectedTable) return \"\";\n\n // Fetch all rows by using total as limit (or a large number if unknown)\n const limit = pagination.total ?? 1000000;\n const data = await getTableRows(selectedTable, {\n schema,\n limit,\n offset: 0,\n sort,\n filters,\n });\n\n return rowsToCsv(data.rows, columns);\n }, [\n selectedTable,\n schema,\n pagination.total,\n sort,\n filters,\n getTableRows,\n columns,\n ]);\n\n const loadTables = useCallback(async () => {\n setTablesLoading(true);\n const data = await getTables();\n setTables(data);\n setTablesLoading(false);\n return data;\n }, [getTables]);\n\n const handleRefresh = useCallback(async () => {\n const newTables = await loadTables();\n\n // Clear selection if selected table no longer exists\n if (selectedTable && !newTables.some((t) => t.name === selectedTable)) {\n setSelectedTable(undefined);\n setTableData(null);\n return;\n }\n\n // Reload current table data if a table is selected\n if (selectedTable) {\n await loadTableData();\n }\n }, [loadTables, selectedTable, loadTableData]);\n\n // Load tables on mount\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n void loadTables();\n }, [loadTables]);\n\n useEffect(() => {\n if (selectedTable) {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n void loadTableData();\n }\n }, [selectedTable, pagination.offset, sort, filters, loadTableData]);\n\n const handleSelectTable = (table: string) => {\n if (table === selectedTable) return;\n\n setSelectedTable(table);\n setPagination((prev) => ({ ...prev, offset: 0, total: null }));\n setSort(getDefaultSort?.(table));\n setFilters(undefined);\n setTableData(null);\n };\n\n const handlePageChange = (offset: number) => {\n setPagination((prev) => ({ ...prev, offset }));\n };\n\n const handleSort = (newSort: SortOptions) => {\n setSort(newSort);\n setPagination((prev) => ({ ...prev, offset: 0 }));\n };\n\n const handleImportClick = () => {\n fileInputRef.current?.click();\n };\n\n const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n\n void file.text().then((content) => {\n setPendingImport(content);\n });\n\n e.target.value = \"\";\n };\n\n const handleImportConfirm = async () => {\n if (pendingImport) {\n // Clear selection before import to prevent stale queries\n setSelectedTable(undefined);\n setTableData(null);\n\n await onImportDb?.(pendingImport);\n setPendingImport(null);\n await loadTables();\n }\n };\n\n const handleImportCancel = () => {\n setPendingImport(null);\n };\n\n const handleExportClick = () => {\n void onExportDb?.();\n };\n\n const resetTargetMajor = pgVersionControl\n ? (pgVersionControl.supportedPgVersions.find(\n (m) => m !== pgVersionControl.currentPgVersion,\n ) ?? null)\n : null;\n\n const handleResetConfirm = async () => {\n if (pendingResetMajor === null || !pgVersionControl) return;\n setResetting(true);\n try {\n await pgVersionControl.onResetToPgVersion(pendingResetMajor);\n } finally {\n setResetting(false);\n setPendingResetMajor(null);\n }\n };\n\n return (\n <div className=\"flex h-full\">\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".sql,.txt,text/plain\"\n className=\"hidden\"\n onChange={handleFileChange}\n />\n\n <ConnectConfirmationModal\n open={!!pendingImport}\n onOpenChange={(open) => !open && setPendingImport(null)}\n header=\"Replace Database?\"\n body=\"This will delete all existing data and replace it with the imported file. This action cannot be undone.\"\n cancelLabel=\"Cancel\"\n continueLabel=\"Replace Data\"\n onCancel={handleImportCancel}\n onContinue={() => void handleImportConfirm()}\n />\n\n <ConnectConfirmationModal\n open={pendingResetMajor !== null}\n onOpenChange={(open) => !open && setPendingResetMajor(null)}\n header={`Reset to Postgres ${pendingResetMajor ?? \"\"}?`}\n body={`This will permanently delete all local reactor data and recreate an empty database under Postgres ${pendingResetMajor ?? \"\"}. The page will reload.`}\n cancelLabel=\"Cancel\"\n continueLabel={`Reset to PG${pendingResetMajor ?? \"\"}`}\n onCancel={() => setPendingResetMajor(null)}\n onContinue={() => void handleResetConfirm()}\n />\n\n <div className=\"flex w-64 shrink-0 flex-col border-r border-gray-200 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <div className=\"flex-1 overflow-auto\">\n <SchemaTreeSidebar\n schema={schema}\n tables={tables}\n selectedTable={selectedTable}\n onSelectTable={handleSelectTable}\n onRefresh={handleRefresh}\n loading={tablesLoading || loading}\n />\n </div>\n\n {(onImportDb || onExportDb || pgVersionControl) && (\n <div className=\"flex shrink-0 flex-col gap-2 border-t border-gray-200 p-2 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {onImportDb && (\n <button\n className=\"rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={handleImportClick}\n type=\"button\"\n >\n Import DB\n </button>\n )}\n {onExportDb && (\n <button\n className=\"rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={handleExportClick}\n type=\"button\"\n >\n Export DB\n </button>\n )}\n {pgVersionControl && (\n <div className=\"flex flex-col gap-1 border-t border-gray-200 pt-2 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <div className=\"flex items-center justify-between text-xs text-gray-700 dark:text-slate-200\">\n <span>Postgres version</span>\n <span className=\"font-semibold text-gray-900 dark:text-slate-50\">\n {pgVersionControl.currentPgVersion === null\n ? \"—\"\n : `PG${pgVersionControl.currentPgVersion}`}\n </span>\n </div>\n {resetTargetMajor !== null && (\n <button\n className=\"rounded-sm border border-red-300 bg-red-50 px-3 py-1.5 text-sm text-red-700 hover:bg-red-100 disabled:opacity-50 dark:border-red-600 dark:bg-red-900 dark:text-red-100 dark:hover:bg-red-800\"\n onClick={() => setPendingResetMajor(resetTargetMajor)}\n disabled={resetting}\n type=\"button\"\n >\n {resetting\n ? `Resetting to PG${resetTargetMajor}…`\n : `Reset to PG${resetTargetMajor}`}\n </button>\n )}\n </div>\n )}\n </div>\n )}\n </div>\n\n <div className=\"flex-1 overflow-auto p-4\">\n {!selectedTable ? (\n <div className=\"text-sm text-gray-500 dark:text-slate-400\">\n Select a table to view data\n </div>\n ) : !tableData && loading ? (\n <div className=\"text-sm text-gray-500 dark:text-slate-400\">\n Loading...\n </div>\n ) : tableData ? (\n <TableView\n columns={columns}\n rows={tableData.rows}\n pagination={pagination}\n onPageChange={handlePageChange}\n onSort={handleSort}\n currentSort={sort}\n loading={loading}\n filters={filters}\n onFiltersChange={(newFilters) => {\n setFilters(newFilters);\n setPagination((prev) => ({ ...prev, offset: 0 }));\n }}\n onCopyAll={handleCopyAll}\n />\n ) : null}\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\n\nexport type DebugInspectorProps = {\n readonly supportedPgVersions: readonly number[];\n readonly currentPgVersion: number | null;\n readonly onResetToPgVersion: (major: number) => Promise<void>;\n};\n\ntype Status = \"idle\" | \"running\" | \"error\";\n\nexport function DebugInspector({\n supportedPgVersions,\n currentPgVersion,\n onResetToPgVersion,\n}: DebugInspectorProps) {\n const [status, setStatus] = useState<Status>(\"idle\");\n const [pendingMajor, setPendingMajor] = useState<number | null>(null);\n const [confirmMajor, setConfirmMajor] = useState<number | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const handleReset = async (major: number) => {\n setError(null);\n setConfirmMajor(null);\n setPendingMajor(major);\n setStatus(\"running\");\n try {\n await onResetToPgVersion(major);\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n setStatus(\"error\");\n setPendingMajor(null);\n }\n };\n\n const running = status === \"running\";\n\n return (\n <div className=\"flex h-full flex-col gap-4 overflow-auto p-4\">\n <div>\n <h2 className=\"text-lg font-semibold text-gray-900 dark:text-slate-50\">\n PGlite data dir\n </h2>\n <p className=\"mt-1 text-sm text-gray-700 dark:text-slate-200\">\n Kill the reactor, delete the local IndexedDB, initialize a fresh\n Postgres cluster at the chosen major version, then reload. Useful for\n testing version-detection and migration flows.\n </p>\n <div className=\"mt-2 inline-flex items-center gap-2 rounded-sm bg-gray-100 px-3 py-1 text-sm dark:bg-slate-700\">\n <span className=\"text-gray-700 dark:text-slate-200\">\n Current version:\n </span>\n <span className=\"font-semibold text-gray-900 dark:text-slate-50\">\n {currentPgVersion === null\n ? \"None (no data dir)\"\n : `Postgres ${currentPgVersion}`}\n </span>\n </div>\n </div>\n\n <div className=\"flex flex-wrap gap-2\">\n {supportedPgVersions.map((major) => {\n const isPending = pendingMajor === major && running;\n return (\n <button\n key={major}\n type=\"button\"\n disabled={running}\n onClick={() => setConfirmMajor(major)}\n className=\"flex items-center gap-1 rounded-sm border border-red-300 bg-red-50 px-3 py-1.5 text-sm text-red-700 hover:bg-red-100 disabled:opacity-50 dark:border-red-600 dark:bg-red-900 dark:text-red-100 dark:hover:bg-red-800\"\n >\n {isPending ? `Resetting to PG${major}…` : `Reset to PG${major}`}\n </button>\n );\n })}\n </div>\n\n {confirmMajor !== null && (\n <div className=\"flex shrink-0 items-center gap-3 rounded-sm border border-yellow-400 bg-yellow-50 px-3 py-2 dark:border-yellow-500 dark:bg-yellow-900\">\n <span className=\"text-sm text-yellow-900 dark:text-yellow-100\">\n This will permanently delete all local reactor data and recreate an\n empty database under Postgres {confirmMajor}. The page will reload.\n </span>\n <button\n type=\"button\"\n onClick={() => void handleReset(confirmMajor)}\n className=\"rounded-sm bg-yellow-600 px-3 py-1 text-sm text-white hover:bg-yellow-700 dark:bg-yellow-300 dark:text-slate-900 dark:hover:bg-yellow-200\"\n >\n Confirm reset to PG{confirmMajor}\n </button>\n <button\n type=\"button\"\n onClick={() => setConfirmMajor(null)}\n className=\"rounded-sm border border-gray-300 bg-gray-50 px-3 py-1 text-sm text-gray-700 hover:bg-gray-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-800\"\n >\n Cancel\n </button>\n </div>\n )}\n\n {error && (\n <div className=\"rounded-sm border border-red-300 bg-red-50 px-3 py-2 text-sm text-red-800 dark:border-red-600 dark:bg-red-900 dark:text-red-100\">\n {error}\n </div>\n )}\n </div>\n );\n}\n","import { useEffect, useRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\n// Each brick: its id, drop delay (ms), fall delay (ms)\n// Drop order: bottom → top. Fall order: bottom → top (same).\nconst SEQUENCE = [\n { id: \"b3\", dropDelay: 0, fallDelay: 0 },\n { id: \"b4\", dropDelay: 100, fallDelay: 80 },\n { id: \"b7\", dropDelay: 280, fallDelay: 240 },\n { id: \"b5\", dropDelay: 380, fallDelay: 320 },\n { id: \"b8\", dropDelay: 560, fallDelay: 480 },\n { id: \"b6\", dropDelay: 660, fallDelay: 560 },\n { id: \"b9\", dropDelay: 840, fallDelay: 720 },\n { id: \"b2\", dropDelay: 940, fallDelay: 800 },\n { id: \"b10\", dropDelay: 1120, fallDelay: 960 },\n { id: \"b1\", dropDelay: 1220, fallDelay: 1040 },\n];\n\nconst ANIM_DUR = 460; // ms — both drop and fall duration\nconst HOLD = 800; // ms logo stays complete before falling\nconst LAST_DROP = 1220;\nconst LAST_FALL = 1040;\nconst LOOP_TOTAL = LAST_DROP + ANIM_DUR + HOLD + LAST_FALL + ANIM_DUR + 400;\n\nconst DROP_STYLE = `brickDrop ${ANIM_DUR}ms cubic-bezier(0.28, 1.08, 0.58, 1) forwards`;\nconst FALL_STYLE = `brickFall ${ANIM_DUR}ms cubic-bezier(0.28, 1.08, 0.58, 1) forwards`;\n\n// SVG path data keyed by brick id\nconst PATHS: Record<string, string> = {\n b1: \"M22.4861 7.36555C22.7622 7.36554 22.9861 7.14169 22.9861 6.86556L22.9863 -5.98095e-06C16.584 0.265497 10.8298 3.03817 6.679 7.36592L22.4861 7.36555Z\",\n b2: \"M15.9859 17.2641C15.9859 17.5403 15.762 17.7641 15.4859 17.7641L0.812049 17.7646C1.63552 14.6865 3.05564 11.8512 4.93889 9.39228L15.486 9.39189C15.7621 9.39188 15.986 9.61575 15.986 9.8919L15.9859 17.2641Z\",\n b3: \"M41.3219 40.5904C37.1727 44.9165 31.4185 47.6892 25.0147 47.9563L25.0148 41.0908C25.0148 40.8146 25.2387 40.5908 25.5148 40.5908L41.3219 40.5904Z\",\n b4: \"M22.9867 47.9547C16.5845 47.6895 10.8289 44.9156 6.67982 40.5896L22.4869 40.5892C22.763 40.5892 22.9869 40.8131 22.9869 41.0893L22.9867 47.9547Z\",\n b5: \"M16.7309 30.6891C16.7309 30.413 16.9548 30.1892 17.2309 30.1892L47.1889 30.1885C46.3654 33.2666 44.9469 36.1002 43.0621 38.5608L17.2308 38.5614C16.9546 38.5614 16.7307 38.3376 16.7307 38.0614L16.7309 30.6891Z\",\n b6: \"M36.1809 20.2901C36.1809 20.014 36.4048 19.7901 36.6809 19.7901L47.6394 19.7899C47.879 21.1488 48.0044 22.5479 48.0044 23.976C48.0043 25.404 47.8788 26.8032 47.6392 28.1621L36.6821 28.1608C36.406 28.1608 36.1822 27.937 36.1822 27.661L36.1809 23.721V20.2901Z\",\n b7: \"M15.0193 38.0631C15.0193 38.3392 14.7954 38.5631 14.5193 38.5631L4.93982 38.5633C3.05508 36.1028 1.63671 33.2692 0.813384 30.1912L14.5195 30.1908C14.7956 30.1908 15.0195 30.4147 15.0195 30.6908L15.0193 38.0631Z\",\n b8: \"M0.364936 19.791L33.613 19.7902C33.8892 19.7902 34.1131 20.014 34.1131 20.2902L34.1129 27.6625C34.1129 27.9386 33.889 28.1624 33.6129 28.1624L0.364728 28.1632C0.12514 26.8043 -0.00024171 25.4052 -0.000207992 23.9771C-0.000174275 22.549 0.125283 21.1499 0.364936 19.791Z\",\n b9: \"M18.0156 9.8918C18.0156 9.61566 18.2394 9.39181 18.5155 9.39181L43.0627 9.39138C44.9475 11.8519 46.3659 14.6855 47.1892 17.7635L18.5154 17.7641C18.2392 17.7641 18.0154 17.5402 18.0154 17.2641L18.0156 9.8918Z\",\n b10: \"M25.0158 -2.51999e-05C31.418 0.265176 37.1737 3.03916 41.3227 7.36511L25.5156 7.36547C25.2395 7.36547 25.0156 7.14161 25.0156 6.86546L25.0158 -2.51999e-05Z\",\n};\n\nexport function LogoAnimation({ size = 48, className = \"\" }) {\n const refsMap = useRef<Record<string, (SVGPathElement | null)[] | undefined>>(\n {},\n ); // id → array of path DOM nodes\n const timers = useRef<NodeJS.Timeout[]>([]);\n\n function getEls(id: string) {\n return refsMap.current[id] ?? [];\n }\n\n function clearTimers() {\n timers.current.forEach(clearTimeout);\n timers.current = [];\n }\n\n function schedule(fn: () => void, delay: number) {\n timers.current.push(setTimeout(fn, delay));\n }\n\n function resetAll() {\n Object.values(refsMap.current)\n .flat()\n .forEach((el) => {\n if (!el) return;\n el.style.animation = \"none\";\n el.style.opacity = \"0\";\n });\n }\n\n useEffect(() => {\n function runDrop(id: string, delay: number) {\n schedule(() => {\n getEls(id).forEach((el) => {\n if (el === null) return;\n el.style.animation = \"none\";\n el.style.opacity = \"\";\n el.style.animation = DROP_STYLE;\n });\n }, delay);\n }\n\n function runFall(id: string, delay: number) {\n schedule(() => {\n getEls(id).forEach((el) => {\n if (!el) return;\n el.style.animation = \"none\";\n el.style.animation = FALL_STYLE;\n });\n }, delay);\n }\n function startLoop() {\n clearTimers();\n resetAll();\n\n SEQUENCE.forEach(({ id, dropDelay }) => runDrop(id, dropDelay));\n\n const fallStart = LAST_DROP + ANIM_DUR + HOLD;\n SEQUENCE.forEach(({ id, fallDelay }) =>\n runFall(id, fallStart + fallDelay),\n );\n\n schedule(startLoop, LOOP_TOTAL);\n }\n startLoop();\n return () => clearTimers();\n }, []);\n\n // Register a path ref by brick id\n function refFor(id: string) {\n return (el: SVGPathElement | null) => {\n if (!refsMap.current[id]) refsMap.current[id] = [];\n if (el && !refsMap.current[id].includes(el)) {\n refsMap.current[id].push(el);\n }\n };\n }\n\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"-1 -2 50 52\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={twMerge(\"text-gray-900 dark:text-slate-50\", className)}\n aria-label=\"Animated logo\"\n >\n {SEQUENCE.map(({ id }) => (\n <path\n key={id}\n ref={refFor(id)}\n d={PATHS[id]}\n fill=\"currentColor\"\n style={{ opacity: 0 }}\n />\n ))}\n </svg>\n );\n}\n","import type { DivProps } from \"#design-system\";\nimport { LogoAnimation } from \"../logo-animation.js\";\n\ntype DefaultEditorLoaderProps = DivProps & {\n readonly message?: string;\n};\n\nexport function DefaultEditorLoader(props: DefaultEditorLoaderProps) {\n const { message = \"Loading editor\", ...divProps } = props;\n return (\n <div\n className=\"grid h-full place-items-center text-gray-800 dark:text-slate-100\"\n {...divProps}\n >\n <div className=\"-mt-20 grid place-items-center\">\n <h3 className=\"mb-4 text-xl\">{message}</h3>\n <LogoAnimation />\n </div>\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport type { ReactNode } from \"react\";\nimport { twJoin, twMerge } from \"tailwind-merge\";\n\ntype DisclosureProps = {\n title: ReactNode;\n isOpen: boolean;\n onOpenChange: () => void;\n children: ReactNode;\n containerClassName?: string;\n toggleClassName?: string;\n contentClassName?: string;\n};\nexport function Disclosure(props: DisclosureProps) {\n const {\n title,\n isOpen,\n onOpenChange,\n children,\n containerClassName,\n toggleClassName,\n contentClassName,\n } = props;\n return (\n <div className={twMerge(containerClassName)}>\n <div\n className={twMerge(\n \"flex cursor-pointer justify-between text-gray-500 dark:text-slate-400\",\n toggleClassName,\n )}\n onClick={onOpenChange}\n >\n <h2 className=\"font-semibold text-inherit\">{title}</h2>\n <Icon\n className={twJoin(\"transition\", isOpen ? \"\" : \"-rotate-90\")}\n size={16}\n name=\"ChevronDown\"\n />\n </div>\n <div\n className={twMerge(\n \"max-h-0 overflow-hidden transition-[max-height] duration-300 ease-in-out\",\n isOpen && \"max-h-screen\",\n contentClassName,\n )}\n >\n {children}\n </div>\n </div>\n );\n}\n","import type { DivProps } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function Divider(props: DivProps) {\n return (\n <div\n {...props}\n className={twMerge(\n \"h-px bg-gray-200 dark:bg-slate-600 dark:text-slate-100\",\n props.className,\n )}\n />\n );\n}\n","import type { ReactNode } from \"react\";\n\nexport type TabContentProps = {\n readonly label: ReactNode;\n readonly description: ReactNode;\n readonly children: ReactNode;\n readonly disabled?: boolean;\n};\nexport function TabContent(props: TabContentProps) {\n const { label: _label, children } = props;\n\n return <div className=\"h-full\">{children}</div>;\n}\n","import { Content, List, Root, Trigger } from \"@radix-ui/react-tabs\";\nimport React from \"react\";\nimport type { TabContentProps } from \"./tab-content.js\";\n\nexport function Tabs({\n children,\n defaultValue,\n}: {\n children: React.ReactNode;\n defaultValue: string;\n}) {\n return (\n <Root\n defaultValue={defaultValue}\n className=\"flex min-h-0 flex-1 flex-col gap-2\"\n >\n <div className=\"flex w-full shrink-0 justify-between\">\n <List className=\"flex w-full gap-x-2 rounded-xl p-1 text-sm font-semibold text-gray-700 outline-none dark:text-slate-200\">\n {React.Children.map(children, (child, _i) => {\n if (!React.isValidElement(child)) return;\n const { label, disabled } = child.props as TabContentProps;\n return (\n <Trigger\n className=\"flex min-h-7 flex-1 items-center justify-center rounded-lg border border-gray-100 bg-gray-50 py-2 text-gray-900 transition duration-300 data-disabled:cursor-not-allowed data-disabled:text-gray-400 data-[state='active']:bg-gray-100 data-[state='active']:text-gray-900 dark:border-slate-600 dark:bg-slate-600 dark:text-slate-200 dark:data-disabled:text-slate-500 dark:data-[state='active']:bg-slate-500 dark:data-[state='active']:text-slate-100\"\n key={label as string}\n value={label as string}\n disabled={disabled ?? false}\n >\n {label as string}\n </Trigger>\n );\n })}\n </List>\n </div>\n <div className=\"mt-3 min-h-0 flex-1 rounded-md bg-gray-50 dark:bg-slate-800\">\n {React.Children.map(children, (child, i) => {\n if (!React.isValidElement(child)) return;\n const { label } = child.props as TabContentProps;\n return (\n <Content className=\"h-full\" value={label as string} key={i}>\n {child}\n </Content>\n );\n })}\n </div>\n </Root>\n );\n}\n","import { JsonViewer } from \"#design-system/ui/components/json-viewer/json-viewer.js\";\nimport { useMemo } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { TabContent } from \"../tabs/tab-content.js\";\nimport { Tabs } from \"../tabs/tabs.js\";\n\ninterface DocumentStateViewerProps {\n state: Record<string, unknown>;\n ignoredScopes?: string[];\n defaultScope?: string;\n className?: string;\n}\n\nfunction formatScopeLabel(text: string) {\n if (!text) return \"\"; // Handle empty strings or null\n return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();\n}\n\nexport function DocumentStateViewer({\n state,\n ignoredScopes = [\"auth\", \"document\"],\n defaultScope,\n className,\n}: DocumentStateViewerProps) {\n const scopes = useMemo(\n () => Object.keys(state).filter((scope) => !ignoredScopes.includes(scope)),\n [state, ignoredScopes],\n );\n\n const initialScope = defaultScope || scopes.at(0) || \"global\";\n\n if (scopes.length === 0) {\n return (\n <div className=\"text-sm text-gray-500 dark:text-slate-400\">\n No state data\n </div>\n );\n }\n\n return (\n <Tabs defaultValue={formatScopeLabel(initialScope)}>\n {scopes.map((scope) => (\n <TabContent\n key={scope}\n label={formatScopeLabel(scope)}\n description={scope}\n >\n <div\n className={twMerge(\n \"-mt-2 rounded-md border border-gray-300 bg-gray-50 p-3 font-mono text-sm dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n className,\n )}\n >\n <JsonViewer data={state[scope] as object} />\n </div>\n </TabContent>\n ))}\n </Tabs>\n );\n}\n","import type { TooltipProps } from \"@radix-ui/react-tooltip\";\nimport {\n Content,\n Portal,\n Provider,\n Root,\n Trigger,\n} from \"@radix-ui/react-tooltip\";\nimport type { ReactNode } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\ntype Props = TooltipProps & {\n readonly className?: string;\n readonly content: ReactNode;\n readonly side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n readonly sideOffset?: number;\n};\n\nexport function ConnectTooltip(props: Props) {\n const {\n children,\n content,\n open,\n defaultOpen,\n onOpenChange,\n className,\n side = \"top\",\n sideOffset = 5,\n delayDuration,\n ...rest\n } = props;\n\n return (\n <Root\n defaultOpen={defaultOpen}\n delayDuration={delayDuration}\n onOpenChange={onOpenChange}\n open={open}\n >\n <Trigger asChild>{children}</Trigger>\n <Portal>\n <Content\n {...rest}\n side={side}\n sideOffset={sideOffset}\n className={twMerge(\n \"z-50 rounded-lg border border-gray-200 bg-gray-50 p-2 text-xs shadow-tooltip dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n className,\n )}\n >\n {content}\n </Content>\n </Portal>\n </Root>\n );\n}\n\nexport const ConnectTooltipProvider = Provider;\n","import { Icon } from \"#design-system\";\nimport { formatDistanceToNow } from \"date-fns\";\nimport { useEffect, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ConnectTooltip } from \"../../tooltip/tooltip.js\";\n\nexport interface HDividerProps {\n className?: string;\n timestampUtcMs?: string;\n title?: string;\n subtitle?: string;\n onClick?: () => void;\n isSelected?: boolean;\n}\n\nexport const HDivider = (props: HDividerProps) => {\n const {\n className,\n timestampUtcMs: timestamp,\n title,\n subtitle,\n onClick,\n isSelected = false,\n } = props;\n const [open, setOpen] = useState<boolean>(false);\n const hasContent = !!title || !!subtitle || !!timestamp;\n\n // Force update tooltips when props change\n useEffect(() => {\n // Force close and re-open if already open to refresh content\n if (open) {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setOpen(false);\n setTimeout(() => hasContent && setOpen(true), 50);\n }\n }, [title, subtitle, timestamp, hasContent]);\n\n const formatTimestamp = (isoString?: string) => {\n if (!isoString) return \"\";\n try {\n return formatDistanceToNow(new Date(isoString), { addSuffix: true });\n } catch {\n return isoString;\n }\n };\n\n const tooltipContent = (\n <div className=\"flex flex-col text-xs\">\n {!!title && <div>{title}</div>}\n {!!subtitle && (\n <div className=\"text-gray-300 dark:text-slate-600\">{subtitle}</div>\n )}\n {!!timestamp && <div>{formatTimestamp(timestamp)}</div>}\n </div>\n );\n\n const handleMouseEnter = () => {\n if (hasContent) {\n setOpen(true);\n }\n };\n\n const handleMouseLeave = () => {\n setOpen(false);\n };\n\n return (\n <div\n className=\"relative\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {isSelected && (\n <Icon\n name=\"TimelineCaret\"\n color=\"#4EA9FF\"\n size={10}\n className=\"absolute top-[-11px] z-40\"\n />\n )}\n <ConnectTooltip\n className=\"rounded-md bg-gray-900 text-white dark:bg-slate-50 dark:text-slate-900\"\n content={tooltipContent}\n open={open && hasContent}\n onOpenChange={setOpen}\n delayDuration={0}\n side=\"bottom\"\n sideOffset={5}\n >\n <div\n className={twMerge(\n \"mx-0.5 flex h-6.25 w-1.5 cursor-pointer flex-col items-center justify-center rounded-xs hover:bg-blue-300 dark:hover:bg-blue-600\",\n isSelected && \"bg-blue-300 dark:bg-blue-600\",\n className,\n )}\n onClick={onClick}\n data-title={title}\n data-subtitle={subtitle}\n data-timestamp={timestamp}\n >\n <div className=\"h-0.5 w-1 rounded-full bg-gray-500 dark:bg-slate-400\" />\n </div>\n </ConnectTooltip>\n </div>\n );\n};\n","import { Icon } from \"#design-system\";\nimport type { TimelineBarItem } from \"@powerhousedao/reactor-browser\";\nimport { format, parseISO } from \"date-fns\";\nimport { useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ConnectTooltip } from \"../../tooltip/tooltip.js\";\n\nexport interface TimelineBarProps extends Omit<\n TimelineBarItem,\n \"id\" | \"type\" | \"revision\" | \"startDate\" | \"endDate\"\n> {\n readonly className?: string;\n onClick?: () => void;\n isSelected?: boolean;\n}\n\nconst getBarHeight = (size = 0) => {\n switch (true) {\n case size <= 0:\n return \"h-[1px]\";\n case size === 1:\n return \"h-[3px]\";\n case size === 2:\n return \"h-[6px]\";\n case size === 3:\n return \"h-[9px]\";\n case size >= 4:\n return \"h-[12px]\";\n default:\n return \"h-[1px]\";\n }\n};\n\nconst formatTimestamp = (isoString?: string) => {\n if (!isoString) return \"\";\n try {\n const date = parseISO(isoString);\n return format(date, \"HH:mm, dd, MMMM\");\n } catch {\n return isoString;\n }\n};\n\nexport const TimelineBar: React.FC<TimelineBarProps> = ({\n onClick,\n className,\n timestampUtcMs: timestamp,\n additions,\n deletions,\n addSize = 0,\n delSize = 0,\n isSelected = false,\n}) => {\n const [open, setOpen] = useState<boolean>(false);\n const noChanges = addSize === 0 && delSize === 0;\n\n const addBarHeight = getBarHeight(addSize);\n const delBarHeight = getBarHeight(delSize);\n\n const tooltipContent = (\n <div className=\"flex flex-col text-xs\">\n <div>{formatTimestamp(timestamp)}</div>\n <div className=\"text-green-900 dark:text-green-100\">{`${additions} additions +`}</div>\n <div className=\"text-red-700 dark:text-red-100\">{`${deletions} deletions -`}</div>\n </div>\n );\n\n const handleMouseEnter = () => {\n if (!noChanges) {\n setOpen(true);\n }\n };\n\n const handleMouseLeave = () => {\n setOpen(false);\n };\n\n return (\n <div\n className=\"relative\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {isSelected && (\n <Icon\n name=\"TimelineCaret\"\n color=\"#4EA9FF\"\n size={10}\n className=\"absolute top-[-11px] left-[-2px] z-40\"\n />\n )}\n {noChanges ? (\n <div\n className={twMerge(\n \"flex h-[25px] w-1.5 cursor-pointer flex-col items-center justify-center rounded-[2px] hover:bg-blue-300 dark:hover:bg-blue-600\",\n className,\n )}\n data-timestamp={timestamp}\n onClick={onClick}\n >\n <div className=\"size-[3px] rounded-full bg-gray-500 dark:bg-slate-400\" />\n </div>\n ) : (\n <ConnectTooltip\n className=\"rounded-md bg-gray-900 text-white dark:bg-slate-50 dark:text-slate-900\"\n content={tooltipContent}\n open={open}\n onOpenChange={setOpen}\n delayDuration={0}\n side=\"bottom\"\n sideOffset={5}\n >\n <div\n className={twMerge(\n \"flex h-[25px] w-1.5 cursor-pointer flex-col items-center justify-center rounded-[2px] hover:bg-blue-300 dark:hover:bg-blue-600\",\n className,\n isSelected && \"bg-blue-300 dark:bg-blue-600\",\n )}\n data-timestamp={timestamp}\n onClick={onClick}\n >\n <div className=\"flex h-3 w-0.5 items-end\">\n <div\n className={twMerge(\n \"h-3 w-0.5 rounded-t-full bg-green-600 dark:bg-green-300\",\n addBarHeight,\n )}\n ></div>\n </div>\n <div className=\"flex h-3 w-0.5 items-start\">\n <div\n className={twMerge(\n \"h-3 w-0.5 rounded-b-full bg-red-600 dark:bg-red-300\",\n delBarHeight,\n )}\n ></div>\n </div>\n </div>\n </ConnectTooltip>\n )}\n </div>\n );\n};\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { ConnectTooltipProvider } from \"../tooltip/tooltip.js\";\nimport { HDivider } from \"./components/h-divider.js\";\nimport { TimelineBar } from \"./components/timeline-bar.js\";\n\nexport type TimelineBarItem = {\n id: string;\n type: \"bar\";\n addSize?: 0 | 1 | 2 | 3 | 4;\n delSize?: 0 | 1 | 2 | 3 | 4;\n timestampUtcMs?: string;\n additions?: number;\n deletions?: number;\n revision?: number;\n startDate?: Date;\n endDate?: Date;\n};\n\nexport type TimelineDividerItem = {\n id: string;\n type: \"divider\";\n timestampUtcMs?: string;\n title?: string;\n subtitle?: string;\n revision?: number;\n startDate?: Date;\n endDate?: Date;\n};\n\nexport type TimelineItem = TimelineBarItem | TimelineDividerItem;\n\nexport interface DocumentTimelineProps {\n onItemClick?: (item: TimelineItem | null) => void;\n timeline?: Array<TimelineItem>;\n}\n\nconst defaultTimeLineItem: TimelineBarItem = {\n id: \"default\",\n type: \"bar\",\n addSize: 0,\n delSize: 0,\n};\n\nexport const DocumentTimeline = (props: DocumentTimelineProps) => {\n const { timeline = [], onItemClick } = props;\n const [selectedItem, setSelectedItem] = useState<null | string>(null);\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n\n const handleClick = (item: TimelineItem) => {\n if (item.id === selectedItem || item.id === defaultTimeLineItem.id) {\n onItemClick?.(null);\n setSelectedItem(null);\n } else {\n onItemClick?.(item);\n setSelectedItem(item.id);\n }\n };\n\n const mergedTimelineItems = [...timeline, defaultTimeLineItem];\n const [unselectedItems, selectedItems] = useMemo(() => {\n const indexSelected = mergedTimelineItems.findIndex(\n (item) => item.id === selectedItem,\n );\n\n return indexSelected === -1\n ? [mergedTimelineItems, []]\n : [\n mergedTimelineItems.slice(0, indexSelected),\n mergedTimelineItems.slice(indexSelected),\n ];\n }, [mergedTimelineItems, selectedItem]);\n\n const renderTimelineItems = useCallback(\n (items: Array<TimelineBarItem | TimelineDividerItem>) => {\n return items.map((item) => {\n if (item.type === \"divider\") {\n const { timestampUtcMs, title, subtitle } = item;\n return (\n <HDivider\n key={item.id}\n timestampUtcMs={timestampUtcMs}\n title={title}\n subtitle={subtitle}\n onClick={() => handleClick(item)}\n isSelected={item.id === selectedItem}\n />\n );\n }\n\n return (\n <TimelineBar\n key={item.id}\n timestampUtcMs={item.timestampUtcMs}\n addSize={item.addSize}\n delSize={item.delSize}\n additions={item.additions}\n deletions={item.deletions}\n isSelected={item.id === selectedItem}\n onClick={() => handleClick(item)}\n />\n );\n });\n },\n [handleClick, selectedItem],\n );\n\n const unselectedContent = useMemo(\n () => renderTimelineItems(unselectedItems),\n [unselectedItems, renderTimelineItems],\n );\n\n const selectedContent = useMemo(\n () => renderTimelineItems(selectedItems),\n [selectedItems, renderTimelineItems],\n );\n\n // Scroll to the end by default\n useEffect(() => {\n if (scrollContainerRef.current) {\n scrollContainerRef.current.scrollLeft =\n scrollContainerRef.current.scrollWidth;\n }\n }, []);\n\n return (\n <ConnectTooltipProvider delayDuration={0} skipDelayDuration={0}>\n <div className=\"relative h-[36px] w-full\">\n <div className=\"absolute left-0 z-20 h-[17px] w-[6px] bg-gray-50 dark:bg-slate-800\">\n <div className=\"mt-[11px] h-[6px] w-[6px] rounded-tl-md bg-gray-50 dark:bg-slate-800\" />\n </div>\n\n <div className=\"absolute top-[11px] right-0 z-20 h-[6px] w-[6px] bg-gray-50 dark:bg-slate-800\">\n <div className=\"h-[6px] w-[6px] rounded-tr-md bg-gray-50 dark:bg-slate-800\" />\n </div>\n <div className=\"absolute inset-x-0 bottom-0 h-[25px] rounded-md bg-gray-50 dark:bg-slate-800\" />\n\n <div className=\"absolute inset-x-0 bottom-0 h-[36px]\">\n <div\n ref={scrollContainerRef}\n className=\"h-full overflow-x-auto rounded-md\"\n >\n <div className=\"ml-auto flex h-[36px] w-max items-end px-2 pb-0\">\n <div className=\"flex\">{unselectedContent}</div>\n <div className=\"flex rounded-sm bg-blue-200 dark:bg-blue-700\">\n {selectedContent}\n </div>\n </div>\n </div>\n </div>\n <div className=\"pointer-events-none absolute bottom-0 left-0 z-10 h-[25px] w-2 rounded-l-md bg-gray-50 dark:bg-slate-800\" />\n <div className=\"pointer-events-none absolute right-0 bottom-0 z-10 h-[25px] w-2 rounded-r-md bg-gray-50 dark:bg-slate-800\" />\n </div>\n </ConnectTooltipProvider>\n );\n};\n","import type { ComponentProps } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Default outer container for `DocumentToolbar`.\n *\n * This component provides the toolbar's base layout and visual styling while\n * still accepting standard `div` props. Pass a custom container to\n * `DocumentToolbar` when you need to replace this wrapper.\n */\nexport function ToolbarContainer(props: ComponentProps<\"div\">) {\n const { children, className, ...rest } = props;\n\n return (\n <div\n {...rest}\n className={twMerge(\n \"flex h-12 w-full items-center justify-between rounded-xl border border-gray-200 bg-gray-50 px-4 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\n/**\n * Default container for a group of toolbar controls.\n *\n * `DocumentToolbar` renders one controls container per toolbar slot. This\n * component provides the default horizontal layout for the controls in that\n * slot while still accepting standard `div` props.\n */\nexport function ToolbarControlsContainer(props: ComponentProps<\"div\">) {\n const { children, className, ...rest } = props;\n\n return (\n <div className={twMerge(\"flex items-center gap-x-2\", className)} {...rest}>\n {children}\n </div>\n );\n}\n","import { useDocumentById } from \"@powerhousedao/reactor-browser\";\nimport {\n redo,\n undo,\n type PHDocument,\n} from \"@powerhousedao/shared/document-model\";\nimport {\n defaultTo,\n filter,\n hasAtLeast,\n isTruthy,\n merge,\n pipe,\n prop,\n values,\n} from \"remeda\";\n\n/**\n * Checks whether a document has at least one non-zero revision count.\n *\n * Revision scopes are dynamic document-model keys, so this checks the values of\n * the document's revision object instead of relying on a fixed list of scope\n * names.\n */\nfunction hasRevisions(document: PHDocument | undefined) {\n return pipe(\n prop(document, \"header\", \"revision\"),\n defaultTo({}),\n values(),\n filter(isTruthy),\n hasAtLeast(1),\n );\n}\n\n/**\n * Returns undo state and an undo dispatcher for a document.\n *\n * `canUndo` is true when the document has at least one non-zero revision count\n * across any revision scope.\n */\nexport function useUndo(documentId: string | undefined) {\n const [document, dispatch] = useDocumentById(documentId);\n const canUndo = hasRevisions(document);\n\n return {\n canUndo,\n undo: () => dispatch(undo()),\n };\n}\n\n/**\n * Returns redo state and a redo dispatcher for a document.\n *\n * `canRedo` is true when the document clipboard contains at least one operation\n * that can be reapplied.\n */\nexport function useRedo(documentId: string | undefined) {\n const [document, dispatch] = useDocumentById(documentId);\n const canRedo = hasAtLeast(document?.clipboard ?? [], 1);\n\n return {\n canRedo,\n redo: () => dispatch(redo()),\n };\n}\n\n/**\n * Returns combined undo and redo state for a document.\n */\nexport function useDocumentUndoRedo(documentId?: string) {\n const undoProps = useUndo(documentId);\n const redoProps = useRedo(documentId);\n return merge(undoProps, redoProps);\n}\n","import {\n setSelectedNode,\n showRevisionHistory,\n useDownloadDocument,\n useGetSwitchboardLink,\n useNodeParentFolderById,\n} from \"@powerhousedao/reactor-browser\";\nimport type { PHDocument } from \"@powerhousedao/shared/document-model\";\nimport type { ComponentProps } from \"react\";\nimport { isDefined } from \"remeda\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Icon } from \"../../../powerhouse/components/icon/icon.js\";\nimport type { ToolbarButtonClickHandler, ToolbarButtonProps } from \"./types.js\";\nimport { useRedo, useUndo } from \"./use-document-undo-redo.js\";\n\n/**\n * Base button component used by the built-in toolbar controls.\n *\n * This component provides the default toolbar button styling and disabled-state\n * behavior while accepting standard `button` props.\n */\nexport function ToolbarButton(props: ComponentProps<\"button\">) {\n const { className, children, disabled, ...rest } = props;\n return (\n <button\n {...rest}\n disabled={disabled}\n className={twMerge(\n \"grid size-fit place-items-center rounded-lg border border-gray-200 bg-gray-50 p-1 text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n disabled\n ? \"cursor-not-allowed text-gray-500 dark:text-slate-400\"\n : \"cursor-pointer active:opacity-70\",\n className,\n )}\n >\n {children}\n </button>\n );\n}\n\n/**\n * Toolbar control for undoing the latest document revision.\n *\n * The button is disabled when there are no revisions available to undo.\n * Provide `children` to replace the default icon, or `onClick` to override the\n * default undo behavior.\n */\nexport function ToolbarUndoButton(props: ToolbarButtonProps) {\n const {\n className,\n onClick: onClickOverride,\n document,\n children = <Icon name=\"ArrowCouterclockwise\" size={16} />,\n } = props;\n const { undo, canUndo } = useUndo(document?.header.id);\n const disabled = !canUndo;\n const onClick = makeOnClick(document, onClickOverride, undo);\n\n return (\n <ToolbarButton\n data-testid=\"toolbar-undo-button\"\n aria-label=\"Undo\"\n className={className}\n disabled={disabled}\n onClick={onClick}\n >\n {children}\n </ToolbarButton>\n );\n}\n\n/**\n * Toolbar control for redoing the latest undone document revision.\n *\n * The button is disabled when there are no revisions available to redo.\n * Provide `children` to replace the default icon, or `onClick` to override the\n * default redo behavior.\n */\nexport function ToolbarRedoButton(props: ToolbarButtonProps) {\n const {\n className,\n onClick: onClickOverride,\n document,\n children = (\n <Icon name=\"ArrowCouterclockwise\" className=\"-scale-x-100\" size={16} />\n ),\n } = props;\n const { redo, canRedo } = useRedo(document?.header.id);\n const onClick = makeOnClick(document, onClickOverride, redo);\n const disabled = !canRedo;\n\n return (\n <ToolbarButton\n data-testid=\"toolbar-redo-button\"\n aria-label=\"Redo\"\n className={className}\n disabled={disabled}\n onClick={onClick}\n >\n {children}\n </ToolbarButton>\n );\n}\n\n/**\n * Toolbar control for downloading the current document.\n *\n * Provide `children` to replace the default label, or `onClick` to override the\n * default download behavior.\n */\nexport function ToolbarDownloadButton(props: ToolbarButtonProps) {\n const {\n className,\n onClick: onClickOverride,\n document,\n children = <span className=\"px-1 text-xs\">Download</span>,\n } = props;\n const downloadDocument = useDownloadDocument(document?.header.id);\n const onClick = makeOnClick(document, onClickOverride, downloadDocument);\n\n return (\n <ToolbarButton\n data-testid=\"toolbar-download-button\"\n aria-label=\"Download\"\n className={className}\n onClick={onClick}\n >\n {children}\n </ToolbarButton>\n );\n}\n\n/**\n * Toolbar control for opening the current document in Switchboard.\n *\n * Provide `children` to replace the default icon, or `onClick` to override the\n * default behavior.\n */\nexport function ToolbarSwitchboardButton(props: ToolbarButtonProps) {\n const {\n className,\n onClick: onClickOverride,\n document,\n children = <Icon name=\"Drive\" size={16} />,\n } = props;\n const getSwitchboardLink = useGetSwitchboardLink(document);\n\n const onClick = makeOnClick(document, onClickOverride, () => {\n getSwitchboardLink?.()\n .then((url) => window.open(url, \"_blank\"))\n .catch((error) =>\n console.error(\"Error opening switchboard link:\", error),\n );\n });\n\n return (\n <ToolbarButton\n data-testid=\"toolbar-switchboard-button\"\n aria-label=\"Open link in Switchboard\"\n className={className}\n onClick={onClick}\n >\n {children}\n </ToolbarButton>\n );\n}\n\n/**\n * Toolbar control for showing the current document's revision history.\n *\n * Provide `children` to replace the default icon, or `onClick` to override the\n * default revision-history behavior.\n */\nexport function ToolbarHistoryButton(props: ToolbarButtonProps) {\n const {\n className,\n onClick: onClickOverride,\n document,\n children = <Icon name=\"History\" size={16} />,\n } = props;\n const onClick = makeOnClick(document, onClickOverride, showRevisionHistory);\n\n return (\n <ToolbarButton\n data-testid=\"toolbar-history-button\"\n aria-label=\"Open document revision history\"\n className={className}\n onClick={onClick}\n >\n {children}\n </ToolbarButton>\n );\n}\n\n/**\n * Toolbar control for closing the current document view.\n *\n * By default, this selects the current document's parent folder. Provide\n * `children` to replace the default icon, or `onClick` to override the default\n * close behavior.\n */\nexport function ToolbarCloseButton(props: ToolbarButtonProps) {\n const {\n className,\n onClick: onClickOverride,\n document,\n children = <Icon name=\"XmarkLight\" size={16} />,\n } = props;\n const parentFolder = useNodeParentFolderById(document?.header.id);\n const onClick = makeOnClick(document, onClickOverride, () =>\n setSelectedNode(parentFolder),\n );\n\n return (\n <ToolbarButton\n data-testid=\"toolbar-close-button\"\n aria-label=\"Close document\"\n className={className}\n onClick={onClick}\n >\n {children}\n </ToolbarButton>\n );\n}\n\n/**\n * Creates a toolbar button click handler.\n *\n * If an override is provided, it is called with the current document. Otherwise,\n * the built-in handler is called with the current document.\n */\nfunction makeOnClick(\n document: PHDocument | undefined,\n onClickOverride: ToolbarButtonClickHandler | undefined,\n defaultOnClick: ToolbarButtonClickHandler,\n) {\n if (isDefined(onClickOverride)) return () => onClickOverride(document);\n return () => defaultOnClick(document);\n}\n","import { twMerge } from \"tailwind-merge\";\nimport { NodeInput } from \"../node-input/node-input.js\";\n\n/**\n * Text input styled for use inside a toolbar.\n *\n * This wraps `NodeInput` with toolbar-specific text styling. Use it for inline\n * toolbar editing flows where the user can submit a value or cancel editing.\n */\nexport function ToolbarInput(props: {\n /**\n * Initial value to show in the input.\n */\n defaultValue?: string;\n /**\n * Additional CSS class names to apply to the input.\n */\n className?: string;\n /**\n * Accessible label for the input.\n */\n \"aria-label\"?: string;\n /**\n * Called when the user submits the input value.\n */\n onSubmit: (value: string) => void;\n /**\n * Called when the user cancels editing.\n */\n onCancel: () => void;\n}) {\n const {\n defaultValue,\n className,\n onSubmit,\n onCancel,\n \"aria-label\": ariaLabel,\n } = props;\n return (\n <NodeInput\n defaultValue={defaultValue}\n className={twMerge(\n \"text-center text-sm font-medium text-gray-500 dark:text-slate-400\",\n className,\n )}\n aria-label={ariaLabel}\n onCancel={onCancel}\n onSubmit={onSubmit}\n />\n );\n}\n","import { useNodeActions, useNodeById } from \"@powerhousedao/reactor-browser\";\nimport type { PHDocument } from \"@powerhousedao/shared/document-model\";\nimport { useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ToolbarInput } from \"./toolbar-input.js\";\n\n/**\n * Toolbar control for displaying and renaming the current document.\n *\n * By default, the component renders the document name as a clickable heading.\n * When clicked, it switches to an inline input. Submitting the input renames\n * both the node and the corresponding drive node entry.\n */\nexport function ToolbarName(props: {\n document?: PHDocument | undefined;\n inputClassName?: string;\n titleClassName?: string;\n}) {\n const { document, inputClassName, titleClassName } = props;\n const [isEditing, setIsEditing] = useState(false);\n const node = useNodeById(document?.header.id);\n const { onRenameNode, onRenameDriveNodes } = useNodeActions();\n\n const documentName = document?.header.name;\n const documentId = document?.header.id;\n\n const activateEditing = () => setIsEditing(true);\n const cancelEditing = () => setIsEditing(false);\n\n const onSubmit = (newName: string) => {\n cancelEditing();\n if (!documentId || !node) return;\n\n Promise.all([\n onRenameNode(newName, node),\n onRenameDriveNodes(newName, documentId),\n ]).catch(console.error);\n };\n\n if (!documentName) return null;\n\n if (isEditing)\n return (\n <ToolbarInput\n className={inputClassName}\n onSubmit={onSubmit}\n onCancel={cancelEditing}\n defaultValue={documentName}\n aria-label=\"Document name\"\n />\n );\n\n return (\n <h1\n className={twMerge(\n \"cursor-pointer text-sm font-medium text-gray-500 hover:text-gray-700 dark:text-slate-400 dark:hover:text-slate-200\",\n titleClassName,\n )}\n onClick={activateEditing}\n title={\"Click to edit\"}\n >\n {documentName}\n </h1>\n );\n}\n","import { keys } from \"remeda\";\nimport {\n ToolbarCloseButton,\n ToolbarDownloadButton,\n ToolbarHistoryButton,\n ToolbarRedoButton,\n ToolbarSwitchboardButton,\n ToolbarUndoButton,\n} from \"./toolbar-button.js\";\nimport { ToolbarName } from \"./toolbar-name.js\";\nimport type { DefaultToolbarControlComponents } from \"./types.js\";\n\n/**\n * Default slot layout for the built-in document toolbar controls.\n *\n * The toolbar is divided into three control groups:\n *\n * - `first`: primary document actions.\n * - `second`: document identity/display controls.\n * - `third`: secondary document actions.\n */\nexport const defaultControlSlots = {\n first: [\"undo\", \"redo\", \"download\"],\n second: [\"name\"],\n third: [\"history\", \"switchboard\", \"close\"],\n} as const;\n\n/**\n * Ordered list of toolbar slot names.\n */\nexport const controlSlots = keys(defaultControlSlots);\n\n/**\n * Ordered list of all built-in document toolbar control names.\n *\n * The order is derived from `defaultControlSlots`.\n */\nexport const documentToolbarControls = [\n ...defaultControlSlots.first,\n ...defaultControlSlots.second,\n ...defaultControlSlots.third,\n] as const;\n\n/**\n * Default component implementation for each built-in toolbar control.\n *\n * These components are used unless a matching entry is provided through\n * `componentOverrides`.\n */\nexport const defaultControlComponents: DefaultToolbarControlComponents = {\n undo: ToolbarUndoButton,\n redo: ToolbarRedoButton,\n download: ToolbarDownloadButton,\n name: ToolbarName,\n switchboard: ToolbarSwitchboardButton,\n history: ToolbarHistoryButton,\n close: ToolbarCloseButton,\n};\n","import type { PHDocument } from \"@powerhousedao/shared/document-model\";\nimport {\n defaultTo,\n filter,\n hasAtLeast,\n isArray,\n isDefined,\n isIncludedIn,\n map,\n pipe,\n prop,\n} from \"remeda\";\nimport {\n defaultControlComponents,\n defaultControlSlots,\n documentToolbarControls,\n} from \"./constants.js\";\nimport type {\n ControlPosition,\n ControlSlot,\n CustomToolbarControl,\n CustomToolbarControlList,\n CustomToolbarControls,\n DocumentToolbarControlName,\n ToolbarControlComponents,\n} from \"./types.js\";\n\n/**\n * Creates a predicate for checking whether a built-in toolbar control should render.\n *\n * A control renders when it is included in `enabledControls` and absent from\n * `disabledControls`. When `enabledControls` is omitted, all built-in controls\n * are considered enabled. When a control appears in both lists,\n * `disabledControls` takes precedence.\n */\nexport function makeIsEnabledChecker(args: {\n enabledControls: DocumentToolbarControlName[] | undefined;\n disabledControls: DocumentToolbarControlName[] | undefined;\n}) {\n const { enabledControls = documentToolbarControls, disabledControls = [] } =\n args;\n\n return (control: DocumentToolbarControlName) =>\n isIncludedIn(control, enabledControls) &&\n !isIncludedIn(control, disabledControls);\n}\n\n/**\n * Creates a getter for rendering the built-in toolbar controls in a slot.\n *\n * The returned function resolves the controls assigned to a slot, filters them\n * through the enabled/disabled control lists, applies any component overrides,\n * and renders each control with the current document.\n */\nexport function makeToolbarControlsRenderer(args: {\n document: PHDocument | undefined;\n enabledControls?: DocumentToolbarControlName[];\n disabledControls?: DocumentToolbarControlName[];\n componentOverrides?: ToolbarControlComponents;\n}) {\n const { document, enabledControls, disabledControls, componentOverrides } =\n args;\n\n const checkIsEnabled = makeIsEnabledChecker({\n enabledControls,\n disabledControls,\n });\n\n const renderComponent = (control: DocumentToolbarControlName) =>\n pipe(\n prop(componentOverrides, control),\n defaultTo(prop(defaultControlComponents, control)),\n (Component) => <Component document={document} key={control} />,\n );\n\n return (slot: ControlSlot) =>\n pipe(\n prop(defaultControlSlots, slot),\n filter(checkIsEnabled),\n map(renderComponent),\n );\n}\n\n/**\n * Checks whether a custom control should render in the requested position.\n *\n * Controls without an explicit position are treated as `\"start\"`.\n */\nfunction isControlInPosition(\n control: Pick<CustomToolbarControl, \"position\">,\n position: ControlPosition,\n) {\n return defaultTo(control.position, \"start\") === position;\n}\n\n/**\n * Creates a getter for rendering custom controls in a slot and position.\n *\n * The returned function resolves the custom control or controls assigned to a\n * slot, then renders only the controls that belong in the requested position.\n */\nexport function makeCustomControlsRenderer(args: {\n document: PHDocument | undefined;\n customControls: CustomToolbarControls | undefined;\n}) {\n const { document, customControls = {} } = args;\n\n return (slot: ControlSlot, pos: ControlPosition) => {\n const controlOrControlList = prop(customControls, slot);\n\n if (!isDefined(controlOrControlList)) return null;\n\n if (isArray(controlOrControlList))\n return renderCustomControlList(controlOrControlList, pos, document);\n return renderCustomControl(controlOrControlList, pos, document);\n };\n}\n\n/**\n * Renders a single custom control when it belongs in the requested position.\n */\nfunction renderCustomControl(\n control: CustomToolbarControl,\n pos: ControlPosition,\n document: PHDocument | undefined,\n) {\n if (!isControlInPosition(control, pos)) return null;\n\n const Component = control.component;\n return <Component document={document} />;\n}\n\n/**\n * Renders a list of custom controls for the requested position.\n *\n * Returns `null` when no controls in the list belong in that position.\n */\nfunction renderCustomControlList(\n controls: CustomToolbarControlList,\n pos: ControlPosition,\n document: PHDocument | undefined,\n) {\n const controlsInPosition = filter(controls, (control) =>\n isControlInPosition(control, pos),\n );\n\n if (!hasAtLeast(controlsInPosition, 1)) return null;\n\n return (\n <>\n {map(controlsInPosition, ({ component: Component, key }) => (\n <Component key={key} document={document} />\n ))}\n </>\n );\n}\n","import { useSelectedDocumentSafe } from \"@powerhousedao/reactor-browser\";\nimport { map } from \"remeda\";\nimport { controlSlots } from \"./constants.js\";\nimport { ToolbarContainer, ToolbarControlsContainer } from \"./containers.js\";\nimport type {\n ControlsContainerSlotProps,\n DocumentToolbarProps,\n} from \"./types.js\";\nimport {\n makeCustomControlsRenderer,\n makeToolbarControlsRenderer,\n} from \"./utils.js\";\n\n/**\n * Renders a document toolbar.\n *\n * By default, the toolbar renders the built-in document controls grouped into\n * toolbar slots. The controls operate on the provided `document`, or on the\n * currently selected document when no document is provided.\n *\n * Use `enabledControls` and `disabledControls` to control which built-in\n * controls are shown. Use `componentOverrides` to replace individual built-in\n * controls while keeping the default toolbar layout. Use `customControls` to\n * insert additional controls before or after the built-in controls in a slot.\n *\n * To take over the toolbar contents completely, pass `children`.\n */\nexport function DocumentToolbar(props: DocumentToolbarProps) {\n const [selectedDocument] = useSelectedDocumentSafe();\n const {\n toolbarClassName,\n document = selectedDocument,\n toolbarContainer: Container = ToolbarContainer,\n } = props;\n\n if (\"children\" in props) {\n return <Container className={toolbarClassName}>{props.children}</Container>;\n }\n\n return (\n <Container className={toolbarClassName}>\n {map(controlSlots, (slot) => (\n <ControlsContainerSlot\n {...props}\n document={document}\n slot={slot}\n key={slot}\n />\n ))}\n </Container>\n );\n}\n\n/**\n * Renders one toolbar controls slot.\n *\n * Custom controls with position `\"start\"` are rendered before the built-in\n * controls for the slot. Custom controls with position `\"end\"` are rendered\n * after them.\n */\nfunction ControlsContainerSlot(props: ControlsContainerSlotProps) {\n const {\n slot,\n document,\n controlsContainerClassName,\n enabledControls,\n disabledControls,\n componentOverrides,\n customControls,\n controlsContainer: ControlsContainer = ToolbarControlsContainer,\n } = props;\n\n const renderToolbarControls = makeToolbarControlsRenderer({\n document,\n enabledControls,\n disabledControls,\n componentOverrides,\n });\n\n const renderCustomControls = makeCustomControlsRenderer({\n document,\n customControls,\n });\n\n return (\n <ControlsContainer className={controlsContainerClassName}>\n {renderCustomControls(slot, \"start\")}\n {renderToolbarControls(slot)}\n {renderCustomControls(slot, \"end\")}\n </ControlsContainer>\n );\n}\n","import { Icon, Modal } from \"#design-system\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { ModalButton } from \"./modal-button.js\";\n\ntype ModalProps = ComponentPropsWithoutRef<typeof Modal>;\n\nexport type ConnectReplaceDuplicateModalProps = {\n readonly open?: boolean;\n readonly onOpenChange?: (open: boolean) => void;\n readonly title?: string;\n readonly fileName?: string;\n readonly message?: string;\n readonly duplicateLabel?: string;\n readonly onDuplicate: () => void;\n readonly overlayProps?: ModalProps[\"overlayProps\"];\n readonly contentProps?: ModalProps[\"contentProps\"];\n};\n\nexport function ConnectReplaceDuplicateModal(\n props: ConnectReplaceDuplicateModalProps,\n) {\n const {\n open,\n onOpenChange,\n title = \"Document Already Exists\",\n fileName,\n message,\n duplicateLabel = \"Create Copy\",\n onDuplicate,\n overlayProps,\n contentProps,\n } = props;\n\n const defaultMessage = fileName\n ? `A document named \"${fileName}\" already exists in this location. Would you like to replace it or create a copy?`\n : \"A document with the same name already exists in this location. Would you like to replace it or create a copy?\";\n\n return (\n <Modal\n open={open}\n onOpenChange={onOpenChange}\n overlayProps={overlayProps}\n contentProps={contentProps}\n >\n <div className=\"w-[450px] p-6\">\n <div className=\"flex items-center justify-between pb-2\">\n <div className=\"text-2xl font-bold text-gray-900 dark:text-slate-100\">\n {title}\n </div>\n <button\n type=\"button\"\n className=\"flex size-6 items-center justify-center rounded-md outline-none hover:bg-gray-100 dark:hover:bg-slate-700\"\n onClick={() => onOpenChange?.(false)}\n >\n <Icon name=\"XmarkLight\" size={24} />\n </button>\n </div>\n <div className=\"my-6 rounded-md bg-gray-50 p-4 text-center text-gray-900 dark:bg-slate-700 dark:text-slate-100\">\n {message || defaultMessage}\n </div>\n <div className=\"mt-8 flex\">\n <ModalButton variant=\"confirm\" onClick={onDuplicate}>\n {duplicateLabel}\n </ModalButton>\n </div>\n </div>\n </Modal>\n );\n}\n","import type { UploadFileItemStatus } from \"../upload-file-item.js\";\n\ntype ErrorDetailsProps = {\n readonly status: UploadFileItemStatus;\n readonly errorDetails?: string;\n};\n\nexport function UploadFileItemErrorDetails(props: ErrorDetailsProps) {\n const { status, errorDetails } = props;\n\n if (\n !(\n (status === \"failed\" || status === \"unsupported-document-type\") &&\n errorDetails\n )\n )\n return null;\n\n return (\n <div className=\"text-xs leading-[18px] wrap-break-word text-gray-500 dark:text-slate-400\">\n {errorDetails}\n </div>\n );\n}\n","import type { IconName } from \"#design-system\";\nimport { Icon } from \"#design-system\";\nimport type { DocumentTypeIcon } from \"@powerhousedao/reactor-browser\";\nimport type { ComponentPropsWithoutRef } from \"react\";\ntype HeaderProps = ComponentPropsWithoutRef<\"div\"> & {\n readonly fileName: string;\n readonly fileSize: string;\n readonly documentType?: DocumentTypeIcon;\n readonly onClose?: () => void;\n};\n\nfunction getDocumentIcon(documentType?: DocumentTypeIcon): IconName {\n switch (documentType) {\n case \"analytics-processor\":\n return \"AnalyticsProcessorModule\";\n case \"relational-processor\":\n return \"RelationalProcessorModule\";\n case \"codegen-processor\":\n return \"CodegenProcessorModule\";\n case \"app\":\n return \"AppModule\";\n case \"document-model\":\n return \"DocumentModelModule\";\n case \"editor\":\n return \"EditorModule\";\n case \"package\":\n return \"PackageModule\";\n case \"subgraph\":\n return \"SubgraphModule\";\n default:\n return \"PowerhouseDocumentModule\";\n }\n}\n\nexport function UploadFileItemHeader(props: HeaderProps) {\n const { fileName, fileSize, documentType, onClose, ...delegatedProps } =\n props;\n\n return (\n <div className=\"flex items-center gap-2\" {...delegatedProps}>\n <div className=\"flex h-9 w-7 shrink-0 items-center justify-center\">\n <Icon\n name={getDocumentIcon(documentType)}\n size={48}\n className=\"text-gray-700 dark:text-slate-200\"\n />\n </div>\n\n <div className=\"flex flex-1 flex-col gap-0.5\">\n <div className=\"text-xs leading-[18px] font-medium text-gray-900 dark:text-slate-50\">\n {fileName}\n </div>\n <div className=\"text-xs leading-[18px] font-medium text-gray-500 dark:text-slate-400\">\n {fileSize}\n </div>\n </div>\n\n {onClose && (\n <div className=\"flex h-9 w-[18px] shrink-0 items-start justify-center\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"flex h-[18px] w-[18px] items-center justify-center text-gray-700 hover:text-gray-800 dark:text-slate-200 dark:hover:text-slate-100\"\n aria-label=\"Close\"\n >\n <Icon name=\"XmarkLight\" size={18} />\n </button>\n </div>\n )}\n </div>\n );\n}\n","import type { UploadFileItemStatus } from \"../upload-file-item.js\";\n\ntype ProgressBarProps = {\n readonly status: UploadFileItemStatus;\n readonly progress?: number;\n};\n\nexport function UploadFileItemProgressBar(props: ProgressBarProps) {\n const { status, progress = 0 } = props;\n\n if (status !== \"uploading\") return null;\n\n const clamped = Math.min(100, Math.max(0, progress));\n\n return (\n <div className=\"h-2 w-full overflow-hidden rounded-sm bg-gray-200 dark:bg-slate-600 dark:text-slate-100\">\n <div\n className=\"h-full bg-blue-900 transition-all duration-300 ease-out dark:bg-blue-50\"\n style={{ width: `${clamped}%` }}\n />\n </div>\n );\n}\n","import { twMerge } from \"tailwind-merge\";\nimport type { UploadFileItemStatus } from \"../upload-file-item.js\";\n\ntype StatusRowProps = {\n readonly status: UploadFileItemStatus;\n readonly progress?: number;\n readonly onOpenDocument?: () => void;\n readonly onFindResolution?: () => void;\n};\n\nfunction getStatusText(status: UploadFileItemStatus): string {\n switch (status) {\n case \"success\":\n return \"Upload successful\";\n case \"failed\":\n return \"Upload failed\";\n case \"unsupported-document-type\":\n return \"Document not supported by this drive\";\n case \"pending\":\n return \"Pending resolution\";\n case \"conflict\":\n return \"Pending Resolution\";\n case \"uploading\":\n return \"Uploading...\";\n default:\n return \"\";\n }\n}\n\nfunction getStatusColor(status: UploadFileItemStatus): string {\n switch (status) {\n case \"success\":\n return \"text-green-700 dark:text-green-100\";\n case \"failed\":\n case \"unsupported-document-type\":\n case \"pending\":\n case \"conflict\":\n return \"text-red-900 dark:text-red-400\";\n case \"uploading\":\n return \"text-gray-900 dark:text-slate-50\";\n default:\n return \"text-gray-900 dark:text-slate-50\";\n }\n}\n\nfunction shouldShowCTA(\n status: UploadFileItemStatus,\n onOpenDocument?: () => void,\n onFindResolution?: () => void,\n): boolean {\n return (\n (status === \"success\" && Boolean(onOpenDocument)) ||\n (status === \"pending\" && Boolean(onFindResolution)) ||\n (status === \"conflict\" && Boolean(onFindResolution))\n );\n}\n\nfunction getCTAText(status: UploadFileItemStatus): string {\n if (status === \"success\") return \"Open Document\";\n if (status === \"pending\") return \"Find resolution\";\n if (status === \"conflict\") return \"Find resolution\";\n return \"\";\n}\n\nexport function UploadFileItemStatusRow(props: StatusRowProps) {\n const { status, progress = 0, onOpenDocument, onFindResolution } = props;\n\n const handleCTAClick = () => {\n if (status === \"success\" && onOpenDocument) onOpenDocument();\n else if (\n (status === \"pending\" || status === \"conflict\") &&\n onFindResolution\n )\n onFindResolution();\n };\n\n return (\n <div className=\"flex items-center justify-between gap-2\">\n <div\n className={twMerge(\"text-xs leading-[18px]\", getStatusColor(status))}\n >\n {getStatusText(status)}\n </div>\n\n {status === \"uploading\" && (\n <div className=\"text-xs leading-[18px] font-medium text-gray-900 dark:text-slate-50\">\n {Math.round(progress)}%\n </div>\n )}\n\n {shouldShowCTA(status, onOpenDocument, onFindResolution) && (\n <button\n type=\"button\"\n onClick={handleCTAClick}\n className=\"text-xs leading-[18px] text-blue-900 hover:opacity-80 dark:text-blue-100\"\n >\n {getCTAText(status)}\n </button>\n )}\n </div>\n );\n}\n","import type { DocumentTypeIcon } from \"@powerhousedao/reactor-browser\";\nimport { type ComponentPropsWithoutRef, forwardRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { UploadFileItemErrorDetails } from \"./components/error-details.js\";\nimport { UploadFileItemHeader } from \"./components/header.js\";\nimport { UploadFileItemProgressBar } from \"./components/progress-bar.js\";\nimport { UploadFileItemStatusRow } from \"./components/status-row.js\";\n\nexport type UploadFileItemStatus =\n | \"success\"\n | \"failed\"\n | \"pending\"\n | \"uploading\"\n | \"conflict\"\n | \"unsupported-document-type\";\n\nexport type UploadFileItemProps = ComponentPropsWithoutRef<\"div\"> & {\n readonly fileName: string;\n readonly fileSize: string;\n readonly status: UploadFileItemStatus;\n readonly documentType?: DocumentTypeIcon;\n readonly progress?: number;\n readonly errorDetails?: string;\n readonly onClose?: () => void;\n readonly onOpenDocument?: () => void;\n readonly onFindResolution?: () => void;\n};\n\nexport const UploadFileItem = forwardRef<HTMLDivElement, UploadFileItemProps>(\n function UploadFileItem(props, ref) {\n const {\n fileName,\n fileSize,\n status,\n documentType,\n progress = 0,\n errorDetails,\n onClose,\n onOpenDocument,\n onFindResolution,\n className,\n ...delegatedProps\n } = props;\n\n return (\n <div\n ref={ref}\n className={twMerge(\n \"flex w-full flex-col gap-0.5 rounded-md border border-gray-100 bg-gray-50 p-2 shadow-sidebar dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n className,\n )}\n {...delegatedProps}\n >\n <UploadFileItemHeader\n fileName={fileName}\n fileSize={fileSize}\n documentType={documentType}\n onClose={onClose}\n />\n\n <div className=\"flex flex-col gap-1\">\n <UploadFileItemStatusRow\n status={status}\n progress={progress}\n onOpenDocument={onOpenDocument}\n onFindResolution={onFindResolution}\n />\n <UploadFileItemProgressBar status={status} progress={progress} />\n <UploadFileItemErrorDetails\n status={status}\n errorDetails={errorDetails}\n />\n </div>\n </div>\n );\n },\n);\n","export function getUploadListTitle(\n count: number,\n explicitTitle?: string,\n): string {\n if (explicitTitle) return explicitTitle;\n return `Uploading ${count} document${count === 1 ? \"\" : \"s\"}`;\n}\n","import { Icon } from \"#design-system\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { useMemo, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport {\n type UploadFileItemProps,\n UploadFileItem,\n} from \"../upload-file-item/upload-file-item.js\";\nimport { getUploadListTitle } from \"./utils.js\";\n\nexport type UploadFileListProps = ComponentPropsWithoutRef<\"div\"> & {\n readonly items: ReadonlyArray<UploadFileItemProps>;\n readonly title?: string;\n readonly defaultCollapsed?: boolean;\n readonly onClose?: () => void;\n};\n\nexport function UploadFileList(props: UploadFileListProps) {\n const {\n items,\n title,\n defaultCollapsed = false,\n onClose,\n className,\n ...delegatedProps\n } = props;\n\n const [isCollapsed, setIsCollapsed] = useState<boolean>(defaultCollapsed);\n\n const computedTitle = useMemo(\n () => getUploadListTitle(items.length, title),\n [items.length, title],\n );\n\n return (\n <div\n className={twMerge(\n \"w-89.5 rounded-md border border-gray-100 bg-gray-50 p-4 shadow-charcoal dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n className,\n )}\n {...delegatedProps}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <button\n type=\"button\"\n aria-expanded={!isCollapsed}\n aria-label={isCollapsed ? \"Expand list\" : \"Collapse list\"}\n onClick={() => setIsCollapsed((v) => !v)}\n className=\"min-w-0 flex-1 text-left text-sm/4 font-medium text-gray-900 hover:opacity-80 dark:text-slate-50\"\n >\n {computedTitle}\n </button>\n\n <div className=\"flex shrink-0 items-center gap-4\">\n {/* Collapse / Expand Toggle */}\n <button\n type=\"button\"\n aria-label={isCollapsed ? \"Expand\" : \"Collapse\"}\n onClick={() => setIsCollapsed((v) => !v)}\n className=\"text-gray-900 hover:opacity-80 dark:text-slate-50\"\n >\n <span\n className={twMerge(\n \"inline-block size-4 transition-transform select-none\",\n isCollapsed ? \"-rotate-90\" : \"rotate-0\",\n )}\n >\n <Icon name=\"CaretDown\" size={16} aria-hidden=\"true\" />\n </span>\n </button>\n\n {/* Close Button */}\n {onClose && (\n <button\n type=\"button\"\n aria-label=\"Close\"\n onClick={onClose}\n className=\"text-gray-900 hover:opacity-80 dark:text-slate-50\"\n >\n <span className=\"inline-block size-4 select-none\">\n <Icon name=\"XmarkLight\" size={16} aria-hidden=\"true\" />\n </span>\n </button>\n )}\n </div>\n </div>\n\n {/* Body (collapsible) */}\n {!isCollapsed && (\n <div className=\"mt-4 flex max-h-[404px] flex-col gap-4 overflow-x-visible overflow-y-auto p-2\">\n {items.map((item, idx) => (\n <UploadFileItem key={`${item.fileName}-${idx}`} {...item} />\n ))}\n </div>\n )}\n </div>\n );\n}\n","import type {\n ConflictResolution,\n DocumentTypeIcon,\n FileUploadProgress,\n} from \"@powerhousedao/reactor-browser\";\nimport type { Node } from \"@powerhousedao/shared/document-drive\";\nimport type { UploadFileItemProps } from \"../upload-file-item/upload-file-item.js\";\n\n// Upload tracking types\nexport type UploadTracker = {\n id: string;\n fileName: string;\n fileSize: string;\n status:\n | \"pending\"\n | \"uploading\"\n | \"success\"\n | \"failed\"\n | \"conflict\"\n | \"unsupported-document-type\";\n progress: number;\n errorDetails?: string;\n fileNode?: Node;\n documentType?: DocumentTypeIcon;\n // Store upload context for re-processing conflicts\n file?: File;\n parentNode?: Node;\n duplicateType?: \"id\" | \"name\";\n};\n\nexport type OnAddFileWithProgress = (\n file: File,\n parent: Node | undefined,\n onProgress?: (progress: FileUploadProgress) => void,\n resolveConflict?: ConflictResolution,\n) => Promise<Node | undefined> | Node | undefined;\n\n// Utility functions\nexport function generateId(): string {\n return `upload_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n}\n\nexport function formatFileSize(bytes: number): string {\n if (bytes === 0) return \"0 Bytes\";\n const k = 1024;\n const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\n}\n\nexport function mapProgressStageToStatus(\n stage: FileUploadProgress[\"stage\"],\n): UploadTracker[\"status\"] {\n switch (stage) {\n case \"loading\":\n case \"initializing\":\n return \"pending\";\n case \"uploading\":\n return \"uploading\";\n case \"complete\":\n return \"success\";\n case \"failed\":\n return \"failed\";\n case \"conflict\":\n return \"conflict\";\n case \"unsupported-document-type\":\n return \"unsupported-document-type\";\n default:\n return \"pending\";\n }\n}\n\nexport function mapUploadsToFileItems(\n uploadsArray: (UploadTracker | undefined)[],\n removeUpload: (uploadId: string) => void,\n setSelectedNodeFn?: (nodeOrNodeSlug: Node | string | undefined) => void,\n onConflictResolution?: (uploadId: string) => void,\n): UploadFileItemProps[] {\n return uploadsArray\n .filter(\n (upload): upload is NonNullable<typeof upload> => upload !== undefined,\n )\n .map((upload) => ({\n fileName: upload.fileName,\n fileSize: upload.fileSize,\n status: upload.status,\n progress: upload.progress,\n errorDetails: upload.errorDetails,\n documentType: upload.documentType,\n onClose: () => {\n removeUpload(upload.id);\n },\n onOpenDocument:\n upload.status === \"success\"\n ? () => {\n if (upload.fileNode && setSelectedNodeFn) {\n setSelectedNodeFn(upload.fileNode);\n } else {\n console.error(\n \"Opening document for upload:\",\n upload.id,\n \"- fileNode not available or setSelectedNode not provided\",\n );\n }\n }\n : undefined,\n onFindResolution:\n upload.status === \"failed\"\n ? () => {\n console.log(\"Finding resolution for upload:\", upload.id);\n }\n : upload.status === \"conflict\"\n ? () => {\n console.log(\n \"Finding conflict resolution for upload:\",\n upload.id,\n );\n onConflictResolution?.(upload.id);\n }\n : undefined,\n }));\n}\n","import type { Node } from \"@powerhousedao/shared/document-drive\";\nimport { type ComponentPropsWithoutRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { UploadFileList } from \"../upload-file-list/upload-file-list.js\";\nimport { mapUploadsToFileItems, type UploadTracker } from \"./utils.js\";\n\nexport type UploadFileListContainerProps = ComponentPropsWithoutRef<\"div\"> & {\n readonly uploadsArray: (UploadTracker | undefined)[];\n readonly uploadsCount: number;\n readonly removeUpload: (uploadId: string) => void;\n readonly clearAllUploads: () => void;\n readonly setSelectedNode?: (\n nodeOrNodeSlug: Node | string | undefined,\n ) => void;\n readonly onClose?: () => void;\n readonly onConflictResolution?: (uploadId: string) => void;\n};\n\nexport function UploadFileListContainer(props: UploadFileListContainerProps) {\n const {\n uploadsArray,\n uploadsCount,\n removeUpload,\n clearAllUploads,\n setSelectedNode,\n onClose,\n onConflictResolution,\n className,\n ...delegatedProps\n } = props;\n\n // Don't render if there are no uploads\n if (uploadsCount === 0) return null;\n\n const items = mapUploadsToFileItems(\n uploadsArray,\n removeUpload,\n setSelectedNode,\n onConflictResolution,\n );\n\n const handleClose = onClose ?? clearAllUploads;\n\n return (\n <div\n className={twMerge(\"fixed right-4 bottom-4 z-1001\", className)}\n {...delegatedProps}\n >\n <UploadFileList items={items} onClose={handleClose} />\n </div>\n );\n}\n","import type {\n ConflictResolution,\n FileUploadProgress,\n} from \"@powerhousedao/reactor-browser\";\nimport type { Node } from \"@powerhousedao/shared/document-drive\";\nimport { useCallback, useEffect, useReducer } from \"react\";\nimport {\n type OnAddFileWithProgress,\n type UploadTracker,\n formatFileSize,\n generateId,\n mapProgressStageToStatus,\n} from \"./utils.js\";\n\n// State type\ntype UploadsState = {\n [uploadId: string]: UploadTracker | undefined;\n};\n\n// Action types\ntype UploadAction =\n | {\n type: \"ADD_UPLOAD\";\n payload: {\n id: string;\n fileName: string;\n fileSize: string;\n };\n }\n | {\n type: \"UPDATE_PROGRESS\";\n payload: {\n id: string;\n progress: FileUploadProgress;\n };\n }\n | {\n type: \"SET_FILE_NODE\";\n payload: {\n id: string;\n fileNode?: Node;\n };\n }\n | {\n type: \"SET_ERROR\";\n payload: {\n id: string;\n error: string;\n };\n }\n | {\n type: \"REMOVE_UPLOAD\";\n payload: {\n id: string;\n };\n }\n | {\n type: \"CLEAR_ALL_UPLOADS\";\n }\n | {\n type: \"SET_CONFLICT_DATA\";\n payload: {\n id: string;\n file: File;\n parentNode?: Node;\n };\n }\n | {\n type: \"CLEAR_CONFLICTED_UPLOADS\";\n };\n\n// Reducer function\nfunction uploadsReducer(\n state: UploadsState,\n action: UploadAction,\n): UploadsState {\n switch (action.type) {\n case \"ADD_UPLOAD\":\n return {\n ...state,\n [action.payload.id]: {\n id: action.payload.id,\n fileName: action.payload.fileName,\n fileSize: action.payload.fileSize,\n status: \"pending\",\n progress: 0,\n fileNode: undefined,\n },\n };\n\n case \"UPDATE_PROGRESS\": {\n const currentUpload = state[action.payload.id];\n if (!currentUpload) return state;\n\n return {\n ...state,\n [action.payload.id]: {\n ...currentUpload,\n status: mapProgressStageToStatus(action.payload.progress.stage),\n progress: action.payload.progress.progress,\n errorDetails: action.payload.progress.error,\n // Update documentType if provided\n ...(action.payload.progress.documentType && {\n documentType: action.payload.progress.documentType,\n }),\n // Update duplicateType if provided (for conflicts)\n ...(action.payload.progress.duplicateType && {\n duplicateType: action.payload.progress.duplicateType,\n }),\n // Update fileNode if provided (for deferred uploads after discovery)\n ...(action.payload.progress.fileNode && {\n fileNode: action.payload.progress.fileNode,\n }),\n },\n };\n }\n\n case \"SET_FILE_NODE\": {\n const uploadToUpdate = state[action.payload.id];\n if (!uploadToUpdate) return state;\n\n return {\n ...state,\n [action.payload.id]: {\n ...uploadToUpdate,\n fileNode: action.payload.fileNode,\n },\n };\n }\n\n case \"SET_ERROR\": {\n const failedUpload = state[action.payload.id];\n if (!failedUpload) return state;\n\n return {\n ...state,\n [action.payload.id]: {\n ...failedUpload,\n status: failedUpload.status || \"failed\",\n errorDetails: action.payload.error,\n },\n };\n }\n\n case \"REMOVE_UPLOAD\": {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { [action.payload.id]: removed, ...rest } = state;\n return rest;\n }\n\n case \"CLEAR_ALL_UPLOADS\": {\n return {};\n }\n\n case \"SET_CONFLICT_DATA\": {\n const conflictUpload = state[action.payload.id];\n if (!conflictUpload) return state;\n\n return {\n ...state,\n [action.payload.id]: {\n ...conflictUpload,\n file: action.payload.file,\n parentNode: action.payload.parentNode,\n },\n };\n }\n\n case \"CLEAR_CONFLICTED_UPLOADS\": {\n // Filter out all uploads with status \"conflict\"\n const filteredUploads: UploadsState = {};\n for (const [id, upload] of Object.entries(state)) {\n if (upload && upload.status !== \"conflict\") {\n filteredUploads[id] = upload;\n }\n }\n return filteredUploads;\n }\n\n default:\n return state;\n }\n}\n\n// Hook\nexport function useUploadTracker(useLocalStorage = false, driveId?: string) {\n const getInitialState = useCallback((): UploadsState => {\n if (useLocalStorage && driveId) {\n try {\n const stored = localStorage.getItem(`uploadTracker_${driveId}`);\n if (stored) {\n const parsed = JSON.parse(stored) as UploadsState;\n return parsed;\n }\n return {};\n } catch (error) {\n console.error(\n \"Failed to load upload tracker from localStorage:\",\n error,\n );\n return {};\n }\n }\n return {};\n }, [useLocalStorage, driveId]);\n\n const [uploads, dispatch] = useReducer(uploadsReducer, getInitialState());\n\n // Save to localStorage whenever uploads change\n useEffect(() => {\n if (useLocalStorage && driveId) {\n try {\n localStorage.setItem(\n `uploadTracker_${driveId}`,\n JSON.stringify(uploads),\n );\n } catch (error) {\n console.error(\"Failed to save upload tracker to localStorage:\", error);\n }\n }\n }, [uploads, useLocalStorage, driveId]);\n\n const createUploadHandler = useCallback(\n (onAddFile?: OnAddFileWithProgress) => {\n if (!onAddFile) return undefined;\n\n return async (file: File, parent: Node | undefined) => {\n const fileId = generateId();\n\n // Add upload to tracking\n dispatch({\n type: \"ADD_UPLOAD\",\n payload: {\n id: fileId,\n fileName: file.name,\n fileSize: formatFileSize(file.size),\n },\n });\n\n // Create progress callback for this specific file\n const progressCallback = (progress: FileUploadProgress) => {\n dispatch({\n type: \"UPDATE_PROGRESS\",\n payload: {\n id: fileId,\n progress,\n },\n });\n\n // Store file and parent data when conflict is detected\n if (progress.stage === \"conflict\") {\n dispatch({\n type: \"SET_CONFLICT_DATA\",\n payload: {\n id: fileId,\n file,\n parentNode: parent,\n },\n });\n }\n };\n\n try {\n // Call the original onAddFile with our progress callback\n const fileNode = await onAddFile(file, parent, progressCallback);\n\n // Store the FileNode\n dispatch({\n type: \"SET_FILE_NODE\",\n payload: {\n id: fileId,\n fileNode: fileNode || undefined,\n },\n });\n } catch (error) {\n dispatch({\n type: \"SET_ERROR\",\n payload: {\n id: fileId,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n });\n }\n };\n },\n [],\n );\n\n const removeUpload = useCallback((uploadId: string) => {\n dispatch({\n type: \"REMOVE_UPLOAD\",\n payload: {\n id: uploadId,\n },\n });\n }, []);\n\n const clearAllUploads = useCallback(() => {\n dispatch({\n type: \"CLEAR_ALL_UPLOADS\",\n });\n }, []);\n\n const clearConflictedUploads = useCallback(() => {\n dispatch({\n type: \"CLEAR_CONFLICTED_UPLOADS\",\n });\n }, []);\n\n const getUploadsArray = useCallback(() => {\n return Object.values(uploads);\n }, [uploads]);\n\n const getUploadsCount = useCallback(() => {\n return Object.keys(uploads).length;\n }, [uploads]);\n\n const resolveConflict = useCallback(\n (\n uploadId: string,\n resolution: ConflictResolution,\n onAddFile?: OnAddFileWithProgress,\n ) => {\n const upload = uploads[uploadId];\n if (!upload?.file || !onAddFile) {\n console.error(\n \"Cannot resolve conflict: missing upload data or onAddFile function\",\n );\n return;\n }\n\n // Re-call onAddFile with the conflict resolution\n const progressCallback = (progress: FileUploadProgress) => {\n dispatch({\n type: \"UPDATE_PROGRESS\",\n payload: {\n id: uploadId,\n progress,\n },\n });\n };\n\n const result = onAddFile(\n upload.file,\n upload.parentNode,\n progressCallback,\n resolution,\n );\n\n // Handle both Promise and direct return values\n Promise.resolve(result)\n .then((fileNode: Node | undefined) => {\n if (fileNode) {\n dispatch({\n type: \"SET_FILE_NODE\",\n payload: {\n id: uploadId,\n fileNode,\n },\n });\n }\n })\n .catch((error: unknown) => {\n dispatch({\n type: \"SET_ERROR\",\n payload: {\n id: uploadId,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n });\n });\n },\n [uploads],\n );\n\n return {\n uploads,\n uploadsArray: getUploadsArray(),\n uploadsCount: getUploadsCount(),\n createUploadHandler,\n removeUpload,\n clearAllUploads,\n clearConflictedUploads,\n resolveConflict,\n };\n}\n","import { Icon } from \"#design-system\";\nimport { setSelectedNode, useDropFile } from \"@powerhousedao/reactor-browser\";\nimport type { Node } from \"@powerhousedao/shared/document-drive\";\nimport {\n type ComponentPropsWithoutRef,\n type ReactNode,\n useEffect,\n useState,\n} from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ConnectReplaceDuplicateModal } from \"../modal/replace-duplicate-modal.js\";\nimport { UploadFileListContainer } from \"./upload-file-list-container.js\";\nimport { useUploadTracker } from \"./use-upload-tracker.js\";\nimport { type OnAddFileWithProgress } from \"./utils.js\";\n\nexport type DropZoneProps = ComponentPropsWithoutRef<\"div\"> & {\n readonly title?: string;\n readonly subtitle?: string;\n readonly node?: Node;\n readonly enable?: boolean;\n readonly children?: ReactNode;\n readonly onAddFile?: OnAddFileWithProgress;\n readonly useLocalStorage?: boolean;\n readonly driveId?: string;\n readonly acceptedFileExtensions?: string[];\n};\n\nexport function DropZone(props: DropZoneProps) {\n const {\n title = \"Drag your documents\",\n subtitle = \"to drop them in the currently selected folder.\",\n node: _node,\n enable = true,\n children,\n onAddFile,\n useLocalStorage = false,\n driveId,\n acceptedFileExtensions: _acceptedFileExtensions = [\".zip\", \".phd\", \".phdm\"],\n className,\n ...delegatedProps\n } = props;\n\n // Modal state for conflict resolution\n const [modalOpen, setModalOpen] = useState(false);\n const [conflictUploadId, setConflictUploadId] = useState<string | null>(null);\n\n // Upload tracking with the new hook\n const {\n uploadsArray,\n uploadsCount,\n createUploadHandler,\n clearAllUploads,\n clearConflictedUploads,\n removeUpload,\n resolveConflict,\n } = useUploadTracker(useLocalStorage, driveId);\n\n // Clear conflicted uploads on mount\n useEffect(() => {\n clearConflictedUploads();\n }, []);\n\n // Create the upload handler from the hook\n const handleAddFile = createUploadHandler(onAddFile) ?? (async () => {});\n\n // Handle conflict resolution modal\n const handleConflictResolution = (uploadId: string) => {\n setConflictUploadId(uploadId);\n setModalOpen(true);\n };\n\n const handleDuplicate = () => {\n if (conflictUploadId && onAddFile) {\n resolveConflict(conflictUploadId, \"duplicate\", onAddFile);\n }\n setModalOpen(false);\n setConflictUploadId(null);\n };\n\n const handleModalClose = () => {\n setModalOpen(false);\n setConflictUploadId(null);\n };\n\n const { isDropTarget, ...dropProps } = useDropFile(handleAddFile);\n\n return (\n <div\n className={twMerge(\"relative\", className)}\n {...(enable ? dropProps : {})}\n {...delegatedProps}\n >\n {children}\n\n {enable && isDropTarget && (\n <div className=\"pointer-events-none fixed inset-0 z-1000 flex min-h-screen w-screen items-center justify-center bg-gray-900/50 dark:bg-slate-900/50\">\n <div className=\"rounded-3xl bg-gray-50 p-6 shadow-charcoal dark:bg-slate-800\">\n <div className=\"relative flex h-32.5 w-100 flex-col items-center justify-start overflow-visible rounded-lg border border-dashed border-gray-900 px-4 py-6\">\n <div className=\"text-center text-base/5 text-gray-500 dark:text-slate-400\">\n {title}\n </div>\n <div className=\"text-center text-base/5 text-gray-500 dark:text-slate-400\">\n {subtitle}\n </div>\n\n <span className=\"pointer-events-none absolute -bottom-16 left-1/2 z-10 -translate-x-1/2\">\n <Icon name=\"DocumentIcons\" size={144} aria-hidden=\"true\" />\n </span>\n </div>\n </div>\n </div>\n )}\n\n {/* Upload File List - positioned at bottom right */}\n <UploadFileListContainer\n uploadsArray={uploadsArray}\n uploadsCount={uploadsCount}\n removeUpload={removeUpload}\n clearAllUploads={clearAllUploads}\n setSelectedNode={setSelectedNode}\n onConflictResolution={handleConflictResolution}\n />\n\n {/* Conflict Resolution Modal */}\n <ConnectReplaceDuplicateModal\n open={modalOpen}\n onOpenChange={handleModalClose}\n fileName={\n conflictUploadId\n ? uploadsArray.find((u) => u?.id === conflictUploadId)?.fileName\n : undefined\n }\n onDuplicate={handleDuplicate}\n />\n </div>\n );\n}\n","import {\n useIsDragAndDropEnabled,\n useOnDropFile,\n useSelectedDriveId,\n} from \"@powerhousedao/reactor-browser\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { DropZone } from \"./drop-zone.js\";\nimport type { OnAddFileWithProgress } from \"./utils.js\";\n\nexport function DropZoneWrapper({\n children,\n ...props\n}: { children: React.ReactNode } & ComponentPropsWithoutRef<\"div\">) {\n const isDragAndDropEnabled = useIsDragAndDropEnabled();\n const selectedDriveId = useSelectedDriveId();\n\n const onDropFile = useOnDropFile();\n\n const onAddFile: OnAddFileWithProgress = async (\n file,\n parent,\n onProgress,\n resolveConflict,\n ) => {\n return await onDropFile(file, onProgress, resolveConflict);\n };\n\n if (!isDragAndDropEnabled || !selectedDriveId) {\n return <>{children}</>;\n }\n\n return (\n <DropZone\n onAddFile={onAddFile}\n driveId={selectedDriveId}\n useLocalStorage={true}\n {...props}\n >\n {children}\n </DropZone>\n );\n}\n","import {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"#design-system\";\nimport type { ReactNode } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport type ConnectDropdownMenuItem<TItemId extends string> = {\n id: TItemId;\n label: ReactNode;\n icon?: React.JSX.Element;\n className?: string;\n};\n\nexport interface ConnectDropdownMenuProps<TItemId extends string> {\n readonly children: ReactNode;\n readonly items: ConnectDropdownMenuItem<TItemId>[];\n readonly open?: boolean;\n readonly onItemClick: (id: TItemId) => void;\n readonly onOpenChange?: (open: boolean) => void;\n readonly menuClassName?: string;\n}\n\nexport function ConnectDropdownMenu<TItemId extends string>(\n props: ConnectDropdownMenuProps<TItemId>,\n) {\n const { children, items, open, onItemClick, onOpenChange, menuClassName } =\n props;\n\n return (\n <DropdownMenu onOpenChange={onOpenChange} open={open}>\n <DropdownMenuTrigger asChild className=\"outline-none\">\n {children}\n </DropdownMenuTrigger>\n <DropdownMenuContent\n className={twMerge(\n \"cursor-pointer rounded-2xl border border-gray-200 bg-gray-50 text-sm font-medium text-gray-500 shadow-lg dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n menuClassName,\n )}\n >\n {items.map(({ id, label, icon, className }) => (\n <DropdownMenuItem\n className={twMerge(\n \"flex items-center px-5 py-2 outline-none first-of-type:rounded-t-2xl first-of-type:pt-3 last-of-type:rounded-b-2xl last-of-type:pb-3 hover:bg-gray-50 dark:hover:bg-slate-800\",\n className,\n )}\n key={id}\n onClick={(e) => e.stopPropagation()}\n onSelect={() => onItemClick(id)}\n >\n {icon ? <span className=\"mr-2 inline-block\">{icon}</span> : null}\n {label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n","import { Icon } from \"#design-system\";\n\nexport type EditorActionButtonsProps = {\n readonly onSwitchboardLinkClick?: (() => void) | undefined;\n readonly onDownloadDocument?: (() => void) | undefined;\n readonly onClose: () => void;\n readonly onShowRevisionHistory?: (() => void) | undefined;\n readonly onShowTimeline?: (() => void) | undefined;\n};\n\nexport function EditorActionButtons(props: EditorActionButtonsProps) {\n const {\n onSwitchboardLinkClick,\n onDownloadDocument: _onDownloadDocument,\n onClose,\n onShowRevisionHistory,\n onShowTimeline,\n } = props;\n\n return (\n <div className=\"flex items-center gap-x-2\">\n {onSwitchboardLinkClick && (\n <button\n className=\"grid size-8 place-items-center rounded-lg border border-gray-200 bg-gray-50 text-gray-900 disabled:cursor-not-allowed disabled:text-gray-500 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:disabled:text-slate-400\"\n onClick={onSwitchboardLinkClick}\n disabled={!onSwitchboardLinkClick}\n >\n <Icon name=\"Drive\" size={16} />\n </button>\n )}\n {onShowRevisionHistory && (\n <button\n className=\"grid size-8 place-items-center rounded-lg border border-gray-200 bg-gray-50 text-gray-900 disabled:cursor-not-allowed disabled:text-gray-500 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:disabled:text-slate-400\"\n onClick={onShowRevisionHistory}\n disabled={!onShowRevisionHistory}\n >\n <Icon name=\"History\" size={16} />\n </button>\n )}\n {onShowTimeline && (\n <button\n className=\"grid size-8 place-items-center rounded-lg border border-gray-200 bg-gray-50 text-gray-900 disabled:cursor-not-allowed disabled:text-gray-500 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:disabled:text-slate-400\"\n onClick={onShowTimeline}\n disabled={!onShowTimeline}\n >\n <Icon name=\"Timeline\" size={16} />\n </button>\n )}\n <button\n className=\"grid size-8 place-items-center rounded-lg border border-gray-200 bg-gray-50 text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\"\n onClick={onClose}\n >\n <Icon name=\"XmarkLight\" size={16} />\n </button>\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport type EditorUndoRedoButtonsProps = {\n readonly canUndo: boolean;\n readonly canRedo: boolean;\n readonly undo: () => void;\n readonly redo: () => void;\n};\nexport function EditorUndoRedoButtons(props: EditorUndoRedoButtonsProps) {\n const { canUndo, canRedo, undo, redo } = props;\n const buttonStyles =\n \"w-8 h-8 rounded-lg flex justify-center items-center rounded border border-gray-200 bg-gray-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\";\n return (\n <div className=\"flex gap-x-2 text-gray-500 dark:text-slate-400\">\n <button className={buttonStyles} disabled={!canUndo} onClick={undo}>\n <Icon\n className={twMerge(\n \"-scale-x-100\",\n canUndo\n ? \"text-gray-900 active:opacity-50 dark:text-slate-50\"\n : \"text-gray-500 dark:text-slate-400\",\n )}\n name=\"RedoArrow\"\n size={18}\n />\n </button>\n <button className={buttonStyles} disabled={!canRedo} onClick={redo}>\n <Icon\n className={twMerge(\n canRedo\n ? \"text-gray-900 active:opacity-50 dark:text-slate-50\"\n : \"text-gray-500 dark:text-slate-400\",\n )}\n name=\"RedoArrow\"\n size={18}\n />\n </button>\n </div>\n );\n}\n","\"data:image/png;base64,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\"","import ImgPowerhouse from \"#assets/powerhouse-rounded.png\";\nimport type { CSSProperties } from \"react\";\n\ntype Props = {\n readonly address: `0x${string}`;\n readonly chainId?: number;\n readonly avatarUrl?: string;\n readonly size?: CSSProperties[\"width\"];\n};\nexport function ENSAvatar(props: Props) {\n const { avatarUrl = ImgPowerhouse, size = \"14px\" } = props;\n const style = {\n width: size,\n height: size,\n };\n\n return (\n <img\n alt=\"ENS Avatar\"\n className=\"flex-none rounded-full object-contain\"\n src={avatarUrl}\n style={style}\n />\n );\n}\n","import { Icon } from \"../../powerhouse/components/icon/icon.js\";\n\nexport const defaultDriveOptions = [\n \"NEW_FOLDER\",\n \"RENAME\",\n \"SETTINGS\",\n] as const;\n\nexport const defaultNodeOptions = [\"RENAME\", \"DELETE\", \"DUPLICATE\"] as const;\n\nexport const normalNodeOptions = [\n \"DUPLICATE\",\n \"RENAME\",\n \"DELETE\",\n \"SETTINGS\",\n] as const;\n\nexport const debugNodeOptions = [\n \"ADD_TRIGGER\",\n \"REMOVE_TRIGGER\",\n \"ADD_INVALID_TRIGGER\",\n] as const;\n\nexport const nodeOptions = [...normalNodeOptions, ...debugNodeOptions] as const;\n\nexport const sharingTypeOptions = [\n {\n value: \"LOCAL\",\n icon: <Icon name=\"Lock\" size={16} />,\n description: \"Only available to you\",\n },\n {\n value: \"CLOUD\",\n icon: <Icon name=\"People\" size={16} />,\n description: \"Only available to people in this drive\",\n },\n {\n value: \"PUBLIC\",\n icon: <Icon name=\"Globe\" size={16} />,\n description: \"Available to everyone\",\n disabled: true,\n },\n] as const;\n\nexport const locationInfoByLocation = {\n CLOUD: {\n title: \"Secure cloud\",\n description: \"End to end encryption between members.\",\n icon: <Icon name=\"Lock\" size={16} />,\n },\n LOCAL: {\n title: \"Local\",\n description: \"Private and only available to you.\",\n icon: <Icon name=\"Hdd\" size={16} />,\n },\n SWITCHBOARD: {\n title: \"Switchboard\",\n description: \"Public and available to everyone.\",\n icon: <Icon name=\"Drive\" size={16} />,\n },\n} as const;\n\nexport const debugNodeOptionsMap = {\n ADD_TRIGGER: {\n label: \"Add Trigger\",\n icon: (\n <Icon\n className=\"text-orange-900 dark:text-orange-100\"\n name=\"Plus\"\n size={16}\n />\n ),\n },\n REMOVE_TRIGGER: {\n label: \"Remove Trigger\",\n icon: (\n <Icon\n className=\"text-orange-900 dark:text-orange-100\"\n name=\"Xmark\"\n size={16}\n />\n ),\n },\n ADD_INVALID_TRIGGER: {\n label: \"Add Trigger\",\n icon: (\n <Icon\n className=\"text-orange-900 dark:text-orange-100\"\n name=\"Exclamation\"\n size={16}\n />\n ),\n },\n} as const;\n\nexport const folderNodeDropdownOptions = {\n DUPLICATE: {\n label: \"Duplicate\",\n icon: <Icon name=\"FilesEarmark\" size={16} />,\n },\n RENAME: {\n label: \"Rename\",\n icon: <Icon name=\"Pencil\" size={16} />,\n },\n DELETE: {\n label: \"Delete\",\n icon: <Icon name=\"Trash\" size={16} />,\n className: \"text-red-900 dark:text-red-400\",\n },\n} as const;\n\nexport const fileNodeDropdownOptions = {\n DOWNLOAD: {\n label: \"Download\",\n icon: <Icon name=\"DownloadFile\" size={16} />,\n },\n ...folderNodeDropdownOptions,\n};\n","export const SYNCING = \"SYNCING\";\nexport const SUCCESS = \"SUCCESS\";\nexport const CONFLICT = \"CONFLICT\";\nexport const MISSING = \"MISSING\";\nexport const ERROR = \"ERROR\";\nexport const INITIAL_SYNC = \"INITIAL_SYNC\";\n\nexport const syncStatuses = [\n INITIAL_SYNC,\n SYNCING,\n SUCCESS,\n CONFLICT,\n MISSING,\n ERROR,\n] as const;\n","import type { IconName, SyncStatus } from \"#design-system\";\nimport { Icon } from \"#design-system\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport {\n CONFLICT,\n ERROR,\n INITIAL_SYNC,\n MISSING,\n SUCCESS,\n SYNCING,\n} from \"../../constants/syncing.js\";\n\nconst syncIcons: Record<SyncStatus, IconName> = {\n SYNCING: \"Syncing\",\n SUCCESS: \"Synced\",\n CONFLICT: \"Error\",\n MISSING: \"Circle\",\n ERROR: \"Error\",\n INITIAL_SYNC: \"Syncing\",\n};\n\nexport type SyncStatusIconProps = Omit<\n ComponentPropsWithoutRef<typeof Icon>,\n \"name\"\n> & {\n syncStatus: SyncStatus;\n overrideSyncIcons?: Partial<Record<SyncStatus, IconName>>;\n};\nexport function SyncStatusIcon(props: SyncStatusIconProps) {\n const { syncStatus, className, overrideSyncIcons = {}, ...iconProps } = props;\n\n const icons = { ...syncIcons, ...overrideSyncIcons };\n\n const syncStatusIcons = {\n [INITIAL_SYNC]: (\n <Icon\n size={16}\n {...iconProps}\n className={twMerge(\"text-blue-900 dark:text-blue-100\", className)}\n name={icons[INITIAL_SYNC]}\n />\n ),\n [SYNCING]: (\n <Icon\n size={16}\n {...iconProps}\n className={twMerge(\"text-blue-900 dark:text-blue-100\", className)}\n name={icons[SYNCING]}\n />\n ),\n [SUCCESS]: (\n <Icon\n size={16}\n {...iconProps}\n className={twMerge(\"text-green-900 dark:text-green-100\", className)}\n name={icons[SUCCESS]}\n />\n ),\n [CONFLICT]: (\n <Icon\n size={16}\n {...iconProps}\n className={twMerge(\"text-orange-900 dark:text-orange-100\", className)}\n name={icons[CONFLICT]}\n />\n ),\n [MISSING]: (\n <Icon\n size={16}\n {...iconProps}\n className={twMerge(\"text-red-900 dark:text-red-400\", className)}\n name={icons[MISSING]}\n />\n ),\n [ERROR]: (\n <Icon\n size={16}\n {...iconProps}\n className={twMerge(\"text-red-900 dark:text-red-400\", className)}\n name={icons[ERROR]}\n />\n ),\n } as const;\n\n return syncStatusIcons[syncStatus];\n}\n","import { Icon } from \"#design-system\";\nimport {\n getSyncStatusSync,\n setSelectedNode,\n showDeleteNodeModal,\n useDownloadDocument,\n useDragNode,\n useNodeActions,\n useSelectedDriveSafe,\n useUserPermissions,\n} from \"@powerhousedao/reactor-browser\";\nimport type {\n DocumentDriveDocument,\n FileNode,\n SharingType,\n} from \"@powerhousedao/shared/document-drive\";\nimport { useState } from \"react\";\nimport { addProp, entries, map, pipe } from \"remeda\";\nimport { twMerge } from \"tailwind-merge\";\nimport { fileNodeDropdownOptions } from \"../../constants/options.js\";\nimport { ConnectDropdownMenu } from \"../dropdown-menu/dropdown-menu.js\";\nimport { NodeInput } from \"../node-input/node-input.js\";\nimport { SyncStatusIcon } from \"../status-icon/sync-status-icon.js\";\n\nfunction getDriveSharingType(drive: DocumentDriveDocument): SharingType {\n if (typeof drive !== \"object\") return \"LOCAL\";\n const isReadDrive = \"readContext\" in drive;\n const { sharingType: _sharingType } = !isReadDrive\n ? drive.state.local\n : { sharingType: \"PUBLIC\" };\n const __sharingType = _sharingType?.toUpperCase();\n const validTypes: string[] = [\"LOCAL\", \"CLOUD\", \"PUBLIC\"];\n return !__sharingType ||\n __sharingType === \"PRIVATE\" ||\n !validTypes.includes(__sharingType)\n ? \"LOCAL\"\n : (__sharingType as SharingType);\n}\n\ntype Props = {\n fileNode: FileNode;\n className?: string;\n customDocumentIconSrc?: string;\n};\n\nexport function FileItem(props: Props) {\n const { fileNode, className, customDocumentIconSrc } = props;\n const [mode, setMode] = useState<\"READ\" | \"WRITE\">(\"READ\");\n const [isDropdownMenuOpen, setIsDropdownMenuOpen] = useState(false);\n const [selectedDrive] = useSelectedDriveSafe();\n const sharingType = selectedDrive\n ? getDriveSharingType(selectedDrive)\n : \"LOCAL\";\n const { isDragging, ...dragProps } = useDragNode({\n srcId: fileNode.id,\n parentId: fileNode.parentFolder ?? undefined,\n });\n const { isAllowedToCreateDocuments } = useUserPermissions();\n const { onRenameNode, onRenameDriveNodes, onDuplicateNode } =\n useNodeActions();\n const downloadDocument = useDownloadDocument(fileNode.id);\n const isReadMode = mode === \"READ\";\n const syncStatus = getSyncStatusSync(fileNode.id, sharingType);\n\n const dropdownMenuHandlers = {\n DOWNLOAD: downloadDocument,\n DUPLICATE: () => onDuplicateNode(fileNode),\n RENAME: () => setMode(\"WRITE\"),\n DELETE: () => showDeleteNodeModal(fileNode),\n } as const;\n\n const dropdownMenuOptions = pipe(\n fileNodeDropdownOptions,\n entries(),\n map(([id, option]) => addProp(option, \"id\", id)),\n );\n\n function onSubmit(name: string) {\n Promise.all([\n onRenameNode(name, fileNode),\n onRenameDriveNodes(name, fileNode.id),\n ])\n .catch((error: unknown) => {\n console.error(error);\n })\n .finally(() => {\n setMode(\"READ\");\n });\n }\n\n function onCancel() {\n setMode(\"READ\");\n }\n\n function onDropdownMenuOptionClick(itemId: string) {\n const handler =\n dropdownMenuHandlers[itemId as keyof typeof dropdownMenuHandlers];\n if (!handler) {\n console.error(`No handler found for dropdown menu item: ${itemId}`);\n return;\n }\n void handler();\n setIsDropdownMenuOpen(false);\n }\n\n const icon = customDocumentIconSrc ? (\n <img\n alt=\"file icon\"\n className=\"max-w-none\"\n height={34}\n src={customDocumentIconSrc}\n width={32}\n /* HTML img elements are draggable by default, so we\n * must disable it here so that only the container\n * can be dragged */\n draggable={false}\n />\n ) : (\n <DefaultFileIcon />\n );\n\n const iconNode = (\n <div className=\"relative\">\n {icon}\n {isReadMode && syncStatus && (\n <div className=\"absolute right-0 bottom-[-2px] size-3 rounded-full bg-gray-50 dark:bg-slate-800\">\n <div className=\"absolute top-[-2px] left-[-2px]\">\n <SyncStatusIcon\n overrideSyncIcons={{ SUCCESS: \"CheckCircleFill\" }}\n syncStatus={syncStatus}\n />\n </div>\n </div>\n )}\n </div>\n );\n\n const containerStyles = twMerge(\n \"group flex h-12 cursor-pointer items-center rounded-lg bg-gray-200 px-2 text-gray-700 select-none hover:text-gray-800 dark:bg-slate-600 dark:text-slate-100 dark:hover:text-slate-100\",\n isDragging ? \"opacity-60\" : \"\",\n className,\n );\n\n const content = isReadMode ? (\n <div className=\"flex w-52 items-center justify-between\">\n <div className=\"mr-2 truncate group-hover:mr-0\">\n <div className=\"max-h-6 truncate text-sm font-medium text-gray-700 group-hover:text-gray-800 dark:text-slate-200 dark:group-hover:text-slate-100\">\n {fileNode.name}\n </div>\n <div className=\"max-h-6 truncate text-xs font-medium text-gray-700 group-hover:text-gray-800 dark:text-slate-200 dark:group-hover:text-slate-100\">\n {fileNode.documentType}\n </div>\n </div>\n {isAllowedToCreateDocuments ? (\n <ConnectDropdownMenu\n items={dropdownMenuOptions}\n onItemClick={onDropdownMenuOptionClick}\n onOpenChange={setIsDropdownMenuOpen}\n open={isDropdownMenuOpen}\n >\n <button\n className={twMerge(\n \"hidden group-hover:block\",\n isDropdownMenuOpen && \"block\",\n )}\n onClick={(e) => {\n e.stopPropagation();\n setIsDropdownMenuOpen(true);\n }}\n >\n <Icon\n className=\"text-gray-700 dark:text-slate-200\"\n name=\"VerticalDots\"\n />\n </button>\n </ConnectDropdownMenu>\n ) : null}\n </div>\n ) : (\n <NodeInput\n className=\"ml-3 flex-1 font-medium\"\n defaultValue={fileNode.name}\n onCancel={onCancel}\n onSubmit={onSubmit}\n />\n );\n\n return (\n <div\n className=\"relative w-64\"\n onClick={isReadMode ? () => setSelectedNode(fileNode) : undefined}\n {...dragProps}\n >\n <div className={containerStyles}>\n <div className=\"flex items-center\">\n <div className=\"mr-1.5\">{iconNode}</div>\n {content}\n </div>\n </div>\n </div>\n );\n}\n\nfunction DefaultFileIcon() {\n return (\n <div className=\"text-white dark:text-slate-800\">\n <svg\n width=\"32\"\n height=\"40\"\n viewBox=\"0 0 32 40\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <g clipPath=\"url(#clip0_3725_503)\">\n <g filter=\"url(#filter0_di_3725_503)\">\n <path\n d=\"M0 6C0 2.68629 2.68629 0 6 0L24 0L32 8V34C32 37.3137 29.3137 40 26 40H6C2.68629 40 0 37.3137 0 34V6Z\"\n fill=\"#F3F5F7\"\n />\n <path\n d=\"M6 0.5H23.793L31.5 8.20703V34C31.5 37.0376 29.0376 39.5 26 39.5H6C2.96243 39.5 0.5 37.0376 0.5 34V6C0.5 2.96243 2.96243 0.5 6 0.5Z\"\n stroke=\"#FF6A55\"\n />\n </g>\n <path\n d=\"M18 12.583C18.1987 12.5831 18.3897 12.6623 18.5303 12.8027L21.8643 16.1357C22.0048 16.2762 22.0838 16.4673 22.084 16.666V25.333C22.084 25.8852 21.8639 26.415 21.4736 26.8057C21.083 27.1963 20.5524 27.4159 20 27.416H12C11.4476 27.4159 10.918 27.1963 10.5273 26.8057C10.1367 26.415 9.91699 25.8855 9.91699 25.333V14.666C9.91716 14.1137 10.1368 13.5839 10.5273 13.1934C10.9179 12.8029 11.4477 12.5831 12 12.583H18ZM12 14.083C11.8456 14.0831 11.6972 14.1448 11.5879 14.2539C11.4786 14.3631 11.4172 14.5115 11.417 14.666V25.333C11.417 25.4876 11.4786 25.6357 11.5879 25.7451C11.6972 25.8544 11.8454 25.9159 12 25.916H20C20.1546 25.9159 20.3038 25.8544 20.4131 25.7451C20.5221 25.6358 20.584 25.4874 20.584 25.333V18.084H18.666C18.1137 18.0838 17.5839 17.8642 17.1934 17.4736C16.8028 17.0831 16.5832 16.5533 16.583 16.001V14.083H12ZM16.8643 19.748C17.1877 19.4893 17.6602 19.5418 17.9189 19.8652L19.252 21.5322C19.471 21.8061 19.4709 22.1949 19.252 22.4688L17.9189 24.1357C17.6601 24.4589 17.1876 24.5116 16.8643 24.2529C16.5412 23.9943 16.489 23.5226 16.7471 23.1992L17.7061 22L16.7471 20.8027C16.4884 20.4794 16.5411 20.0069 16.8643 19.748ZM14.0811 19.8652C14.3398 19.5421 14.8114 19.4896 15.1348 19.748C15.4582 20.0068 15.5107 20.4793 15.252 20.8027L14.293 22L15.252 23.1992C15.5105 23.5227 15.4581 23.9942 15.1348 24.2529C14.8114 24.5113 14.3397 24.4589 14.0811 24.1357L12.7471 22.4688C12.5284 22.195 12.5284 21.806 12.7471 21.5322L14.0811 19.8652ZM18.083 16.001C18.0832 16.1555 18.1447 16.3038 18.2539 16.4131C18.3632 16.5223 18.5115 16.5838 18.666 16.584H20.1914L18.083 14.4756V16.001Z\"\n fill=\"#FF6A55\"\n />\n <path d=\"M23 0L32 9H27C24.7909 9 23 7.20914 23 5V0Z\" fill=\"#FF6A55\" />\n </g>\n <defs>\n <filter\n id=\"filter0_di_3725_503\"\n x=\"-4\"\n y=\"-1\"\n width=\"40\"\n height=\"49\"\n filterUnits=\"userSpaceOnUse\"\n colorInterpolationFilters=\"sRGB\"\n >\n <feFlood floodOpacity=\"0\" result=\"BackgroundImageFix\" />\n <feColorMatrix\n in=\"SourceAlpha\"\n type=\"matrix\"\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\"\n result=\"hardAlpha\"\n />\n <feMorphology\n radius=\"4\"\n operator=\"erode\"\n in=\"SourceAlpha\"\n result=\"effect1_dropShadow_3725_503\"\n />\n <feOffset dy=\"4\" />\n <feGaussianBlur stdDeviation=\"4\" />\n <feColorMatrix\n type=\"matrix\"\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.02 0\"\n />\n <feBlend\n mode=\"multiply\"\n in2=\"BackgroundImageFix\"\n result=\"effect1_dropShadow_3725_503\"\n />\n <feBlend\n mode=\"normal\"\n in=\"SourceGraphic\"\n in2=\"effect1_dropShadow_3725_503\"\n result=\"shape\"\n />\n <feColorMatrix\n in=\"SourceAlpha\"\n type=\"matrix\"\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\"\n result=\"hardAlpha\"\n />\n <feOffset dy=\"-1\" />\n <feGaussianBlur stdDeviation=\"0.5\" />\n <feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\" />\n <feColorMatrix\n type=\"matrix\"\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.04 0\"\n />\n <feBlend\n mode=\"multiply\"\n in2=\"shape\"\n result=\"effect2_innerShadow_3725_503\"\n />\n </filter>\n <clipPath id=\"clip0_3725_503\">\n <rect width=\"32\" height=\"40\" fill=\"currentColor\" />\n </clipPath>\n </defs>\n </svg>\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport {\n setSelectedNode,\n showDeleteNodeModal,\n useDragNode,\n useDropNode,\n useNodeActions,\n useUserPermissions,\n} from \"@powerhousedao/reactor-browser\";\nimport type { FolderNode } from \"@powerhousedao/shared/document-drive\";\nimport { useState } from \"react\";\nimport { addProp, entries, map, pipe } from \"remeda\";\nimport { twMerge } from \"tailwind-merge\";\nimport { folderNodeDropdownOptions } from \"../../constants/options.js\";\nimport { ConnectDropdownMenu } from \"../dropdown-menu/dropdown-menu.js\";\nimport { NodeInput } from \"../node-input/node-input.js\";\n\nexport function FolderItem(props: {\n folderNode: FolderNode;\n className?: string;\n}) {\n const { folderNode, className } = props;\n const { isAllowedToCreateDocuments } = useUserPermissions();\n const [mode, setMode] = useState<\"READ\" | \"WRITE\">(\"READ\");\n const [isDropdownMenuOpen, setIsDropdownMenuOpen] = useState(false);\n const { isDragging, ...dragProps } = useDragNode({\n srcId: folderNode.id,\n parentId: folderNode.parentFolder,\n });\n const { isDropTarget, ...dropProps } = useDropNode(folderNode.id);\n const { onRenameNode, onRenameDriveNodes, onDuplicateNode } =\n useNodeActions();\n const isReadMode = mode === \"READ\";\n function onCancel() {\n setMode(\"READ\");\n }\n\n function onSubmit(name: string) {\n Promise.all([\n onRenameNode(name, folderNode),\n onRenameDriveNodes(name, folderNode.id),\n ])\n .catch((error: unknown) => {\n console.error(error);\n })\n .finally(() => {\n setMode(\"READ\");\n });\n }\n\n const dropdownMenuHandlers = {\n DUPLICATE: () => onDuplicateNode(folderNode),\n RENAME: () => setMode(\"WRITE\"),\n DELETE: () => showDeleteNodeModal(folderNode),\n } as const;\n\n const dropdownMenuOptions = pipe(\n folderNodeDropdownOptions,\n entries(),\n map(([id, option]) => addProp(option, \"id\", id)),\n );\n\n function onDropdownMenuOptionClick(\n itemId: keyof typeof dropdownMenuHandlers,\n ) {\n const handler = dropdownMenuHandlers[itemId];\n if (!handler) {\n console.error(`No handler found for dropdown menu item: ${itemId}`);\n return;\n }\n void handler();\n setIsDropdownMenuOpen(false);\n }\n\n const content =\n isReadMode || !isAllowedToCreateDocuments ? (\n <div className=\"ml-3 max-h-6 truncate font-medium text-gray-700 group-hover:text-gray-800 dark:text-slate-200 dark:group-hover:text-slate-100\">\n {folderNode.name}\n </div>\n ) : (\n <NodeInput\n className=\"ml-3 font-medium\"\n defaultValue={folderNode.name}\n onCancel={onCancel}\n onSubmit={onSubmit}\n />\n );\n\n const containerStyles = twMerge(\n \"group flex h-12 cursor-pointer items-center rounded-lg bg-gray-200 px-2 select-none dark:bg-slate-600 dark:text-slate-100\",\n isDragging\n ? \"opacity-60\"\n : isDropTarget\n ? \"bg-blue-100 dark:bg-blue-800\"\n : \"\",\n className,\n );\n\n return (\n <div\n className=\"relative w-64\"\n onClick={isReadMode ? () => setSelectedNode(folderNode) : undefined}\n >\n <div {...dragProps} {...dropProps} className={containerStyles}>\n <div className=\"flex items-center overflow-hidden\">\n <div className=\"p-1\">\n <div className=\"relative text-gray-700 dark:text-slate-200\">\n <Icon name=\"FolderClose\" size={24} />\n </div>\n </div>\n {content}\n </div>\n {isReadMode && isAllowedToCreateDocuments ? (\n <ConnectDropdownMenu\n items={dropdownMenuOptions}\n onItemClick={onDropdownMenuOptionClick}\n onOpenChange={setIsDropdownMenuOpen}\n open={isDropdownMenuOpen}\n >\n <button\n className={twMerge(\n \"ml-auto hidden group-hover:block\",\n isDropdownMenuOpen && \"block\",\n )}\n onClick={(e) => {\n e.stopPropagation();\n setIsDropdownMenuOpen(true);\n }}\n >\n <Icon\n className=\"text-gray-700 dark:text-slate-200\"\n name=\"VerticalDots\"\n />\n </button>\n </ConnectDropdownMenu>\n ) : null}\n </div>\n </div>\n );\n}\n","import { twMerge } from \"tailwind-merge\";\n\ntype FooterLinkProps<E extends React.ElementType> = {\n readonly as?: E;\n} & React.ComponentPropsWithRef<E>;\n\nexport function FooterLink<E extends React.ElementType = \"a\">(\n props: FooterLinkProps<E>,\n) {\n const { as: Component = \"a\", className, ...restProps } = props;\n\n return (\n <Component\n className={twMerge(\n \"flex cursor-pointer items-center hover:underline\",\n typeof className === \"string\" && className,\n )}\n {...restProps}\n />\n );\n}\n","import { twMerge } from \"tailwind-merge\";\n\nexport const Footer: React.FC<React.HTMLAttributes<HTMLElement>> = ({\n children,\n className,\n ...props\n}) => {\n return (\n <footer\n className={twMerge(\n \"flex items-center gap-x-6 text-xs font-medium text-gray-300 dark:text-slate-600\",\n typeof className === \"string\" && className,\n )}\n {...props}\n >\n {children}\n </footer>\n );\n};\n","import type { ComponentPropsWithRef, ForwardedRef } from \"react\";\nimport { forwardRef } from \"react\";\nimport { twJoin, twMerge } from \"tailwind-merge\";\n\ntype InputProps = ComponentPropsWithRef<\"input\">;\ntype FormInputProps = Omit<InputProps, \"className\"> & {\n readonly icon?: React.JSX.Element;\n readonly errorMessage?: string;\n readonly isTouched?: boolean;\n readonly isDirty?: boolean;\n readonly type?: \"text\" | \"password\" | \"email\" | \"url\";\n readonly inputClassName?: string;\n readonly containerClassName?: string;\n readonly errorMessageClassName?: string;\n readonly hideErrors?: boolean;\n};\nexport const FormInput = forwardRef(function FormInput(\n props: FormInputProps,\n ref: ForwardedRef<HTMLInputElement>,\n) {\n const {\n icon,\n errorMessage,\n isDirty,\n containerClassName,\n inputClassName,\n errorMessageClassName,\n hideErrors = false,\n ...delegatedProps\n } = props;\n const type = props.type ?? \"text\";\n const isError = !!errorMessage;\n return (\n <div>\n <div\n className={twMerge(\n \"mb-1 flex gap-2 rounded-md border border-gray-200 bg-gray-50 p-3 text-gray-900 placeholder:text-gray-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:placeholder:text-slate-900\",\n isError && \"border-red-900 dark:border-red-50\",\n containerClassName,\n )}\n >\n {icon && (\n <span\n className={twJoin(\n (!isDirty || isError) && \"text-gray-200 dark:text-slate-200\",\n )}\n >\n {icon}\n </span>\n )}\n\n <input\n {...delegatedProps}\n className={twMerge(\n \"w-full bg-transparent font-semibold outline-none\",\n inputClassName,\n )}\n ref={ref}\n type={type}\n />\n </div>\n <p\n className={twMerge(\n \"hidden min-h-4 text-xs text-red-900 dark:text-red-400\",\n isError && \"block\",\n hideErrors && \"hidden\",\n errorMessageClassName,\n )}\n >\n {errorMessage}\n </p>\n </div>\n );\n});\n","import { Icon, type AppOptions } from \"#design-system\";\nimport type { ComponentPropsWithRef } from \"react\";\nimport type { Control, Path } from \"react-hook-form\";\nimport { Controller } from \"react-hook-form\";\nimport type { ConnectSelectItem } from \"../../select/select.js\";\nimport { ConnectSelect } from \"../../select/select.js\";\n\nexport function appToInputOption(app: AppOptions): ConnectSelectItem<string> {\n return {\n value: app.id,\n displayValue: app.name,\n icon: <Icon name=\"PowerhouseLogoSmall\" />,\n description: \"Built by Powerhouse\",\n };\n}\ntype AppFormInputProps<T extends AppOptions> = Omit<\n ComponentPropsWithRef<typeof ConnectSelect>,\n \"id\" | \"items\" | \"value\" | \"onChange\"\n> & {\n readonly control: Control<T>;\n readonly appOptions: T[];\n};\n\nexport function AppFormInput<T extends AppOptions>(\n props: AppFormInputProps<T>,\n) {\n const { control, appOptions, ...delegatedProps } = props;\n const items = appOptions.map(appToInputOption);\n\n return (\n <Controller\n control={control}\n name={\"id\" as Path<T>}\n render={({ field }) => (\n <ConnectSelect {...delegatedProps} {...field} id=\"id\" items={items} />\n )}\n />\n );\n}\n","import type { ComponentPropsWithRef, ForwardedRef } from \"react\";\nimport { forwardRef } from \"react\";\n\ntype ToggleProps = Omit<ComponentPropsWithRef<\"input\">, \"type\">;\n\nexport const Toggle = forwardRef(function Toggle(\n props: ToggleProps,\n ref: ForwardedRef<HTMLInputElement>,\n) {\n return (\n <label className=\"relative cursor-pointer items-center\" htmlFor={props.id}>\n <input\n className=\"peer sr-only\"\n ref={ref}\n type=\"checkbox\"\n value=\"\"\n {...props}\n />\n <div className=\"peer h-6 w-11 rounded-full bg-gray-500 peer-checked:bg-blue-900 peer-focus:outline-none after:absolute after:inset-s-0.5 after:top-0.5 after:size-5 after:rounded-full after:border after:border-none after:bg-gray-50 after:transition-all peer-checked:after:translate-x-full dark:bg-slate-400 dark:after:bg-slate-800\" />\n </label>\n );\n});\n","import type { ComponentPropsWithRef, ForwardedRef } from \"react\";\nimport { forwardRef } from \"react\";\nimport { Toggle } from \"../../toggle/toggle.js\";\n\ntype AvailableOfflineToggleProps = Omit<\n ComponentPropsWithRef<typeof Toggle>,\n \"id\"\n>;\n\nexport const AvailableOfflineToggle = forwardRef(\n function AvailableOfflineToggle(\n props: AvailableOfflineToggleProps,\n ref: ForwardedRef<HTMLInputElement>,\n ) {\n return (\n <div className=\"flex items-center rounded-md border border-gray-200 bg-gray-50 p-3 text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <div className=\"flex-1\">\n <label\n className=\"font-medium text-gray-900 dark:text-slate-50\"\n htmlFor=\"availableOffline\"\n >\n Make available offline\n </label>\n <p className=\"text-xs text-gray-700 dark:text-slate-200\">\n Check this options if you keep a local backup\n <br />\n available at all times.\n </p>\n </div>\n <Toggle id=\"availableOffline\" ref={ref} {...props} />\n </div>\n );\n },\n);\n","import type { ComponentPropsWithoutRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\ntype LabelProps = ComponentPropsWithoutRef<\"label\">;\n\nexport function Label(props: LabelProps) {\n const { children, className, ...labelProps } = props;\n return (\n <label\n {...labelProps}\n className={twMerge(\n \"block font-semibold text-gray-500 dark:text-slate-400\",\n className,\n )}\n >\n {children}\n </label>\n );\n}\n","import type { SharingType } from \"@powerhousedao/shared/document-drive\";\nimport type { ComponentPropsWithRef } from \"react\";\nimport type { Control, Path } from \"react-hook-form\";\nimport { Controller } from \"react-hook-form\";\nimport { ConnectSelect } from \"../../select/select.js\";\nimport { sharingTypeOptions } from \"../../../constants/options.js\";\n\ntype SharingTypeFormInputProps<T extends { sharingType: SharingType }> = Omit<\n ComponentPropsWithRef<typeof ConnectSelect>,\n \"id\" | \"items\" | \"value\" | \"onChange\"\n> & {\n readonly control: Control<T>;\n};\nexport function SharingTypeFormInput<T extends { sharingType: SharingType }>(\n props: SharingTypeFormInputProps<T>,\n) {\n const { control, ...delegatedProps } = props;\n\n return (\n <Controller\n control={control}\n name={\"sharingType\" as Path<T>}\n render={({ field }) => (\n <ConnectSelect\n {...delegatedProps}\n {...field}\n id=\"sharingType\"\n items={sharingTypeOptions}\n />\n )}\n />\n );\n}\n","import { PowerhouseButton, type AppOptions } from \"#design-system\";\nimport type { SubmitHandler } from \"react-hook-form\";\nimport { useForm } from \"react-hook-form\";\nimport { FormInput } from \"../form-input/form-input.js\";\nimport { AppFormInput } from \"./inputs/app-form-input.js\";\nimport { AvailableOfflineToggle } from \"./inputs/available-offline-toggle.js\";\nimport { Label } from \"./inputs/label.js\";\nimport { SharingTypeFormInput } from \"./inputs/sharing-type-form-input.js\";\n\ntype AddLocalDriveFormProps = {\n readonly onSubmit: CreateDriveFormSubmitHandler;\n readonly onCancel: () => void;\n readonly appOptions: AppOptions[];\n};\n\ntype CreateDriveFormSubmitHandler = SubmitHandler<AppOptions>;\n\nexport function AddLocalDriveForm(props: AddLocalDriveFormProps) {\n const {\n register,\n handleSubmit,\n control,\n formState: { errors },\n } = useForm<AppOptions>({\n defaultValues: {\n name: \"\",\n sharingType: \"LOCAL\",\n availableOffline: false,\n id: props.appOptions[0].id,\n },\n });\n\n return (\n <form\n name=\"add-local-drive\"\n onSubmit={(e) => void handleSubmit(props.onSubmit)(e)}\n className=\"flex flex-col gap-4\"\n >\n <div className=\"flex flex-col gap-4\">\n <div>\n <Label\n htmlFor=\"name\"\n className=\"text-sm font-medium text-gray-900 dark:text-slate-100\"\n >\n Drive Name\n </Label>\n <FormInput\n {...register(\"name\", {\n required: \"Drive name is required\",\n })}\n errorMessage={errors.name?.message}\n placeholder=\"Drive name\"\n />\n </div>\n <div>\n <Label\n htmlFor=\"driveApp\"\n className=\"text-sm font-medium text-gray-900 dark:text-slate-100\"\n >\n Drive App\n </Label>\n <AppFormInput control={control} appOptions={props.appOptions} />\n </div>\n <div>\n <Label\n htmlFor=\"sharingType\"\n className=\"text-sm font-medium text-gray-900 dark:text-slate-100\"\n >\n Location\n </Label>\n <SharingTypeFormInput control={control} />\n </div>\n <div>\n <AvailableOfflineToggle {...register(\"availableOffline\")} />\n </div>\n <PowerhouseButton className=\"mt-2 w-full\" type=\"submit\">\n Create new drive\n </PowerhouseButton>\n </div>\n </form>\n );\n}\n","import { Icon } from \"#design-system\";\n\ntype DriveNameProps = {\n readonly driveName: string;\n};\nexport function DriveName(props: DriveNameProps) {\n return (\n <div className=\"flex gap-2 rounded-xl bg-gray-100 p-3 font-semibold text-gray-500 dark:bg-slate-700 dark:text-slate-400\">\n <Icon className=\"text-gray-700 dark:text-slate-200\" name=\"Drive\" />\n {props.driveName}\n </div>\n );\n}\n","import type { DivProps, DriveLocation } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\nimport { locationInfoByLocation } from \"../../../constants/options.js\";\ntype LocationInfoProps = DivProps & {\n readonly location: DriveLocation;\n};\n\nexport function LocationInfo(props: LocationInfoProps) {\n const { location, className, ...divProps } = props;\n\n const locationInfo = locationInfoByLocation[location];\n return (\n <div\n {...divProps}\n className={twMerge(\n \"my-3 flex items-center gap-2 rounded-xl border border-gray-100 bg-gray-50 p-3 text-gray-900 shadow-sm dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n className,\n )}\n >\n {locationInfo.icon}\n <div>\n <p>{locationInfo.title}</p>\n <p className=\"text-xs text-gray-200 dark:text-slate-700\">\n {locationInfo.description}\n </p>\n </div>\n </div>\n );\n}\n","import { PowerhouseButton } from \"#design-system\";\nimport type { SharingType } from \"@powerhousedao/shared/document-drive\";\nimport { useEffect, useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { useDebounceValue } from \"usehooks-ts\";\nimport { Disclosure } from \"../disclosure/disclosure.js\";\nimport { Divider } from \"../divider/divider.js\";\nimport { FormInput } from \"../form-input/form-input.js\";\nimport { AvailableOfflineToggle } from \"./inputs/available-offline-toggle.js\";\nimport { DriveName } from \"./inputs/drive-name.js\";\nimport { LocationInfo } from \"./inputs/location-info.js\";\n\ntype RemoteDriveDetails = {\n id: string;\n name: string;\n sharingType: SharingType;\n location: \"SWITCHBOARD\";\n availableOffline: boolean;\n};\n\ntype Inputs = {\n availableOffline: boolean;\n};\n\nexport type AddRemoteDriveInput = RemoteDriveDetails & { url: string };\n\nexport type AddPublicDriveFormProps = {\n readonly sharingType: SharingType;\n readonly onSubmit: (data: AddRemoteDriveInput) => void;\n readonly onCancel: () => void;\n readonly requestPublicDrive: (\n url: string,\n ) => Promise<{ id: string; name: string }>;\n};\n\nexport function AddRemoteDriveForm(props: AddPublicDriveFormProps) {\n const { sharingType = \"PUBLIC\", requestPublicDrive } = props;\n const [remoteDriveDetails, setPublicDriveDetails] =\n useState<RemoteDriveDetails>();\n const [showLocationSettings, setShowLocationSettings] = useState(false);\n const [isUrlValid, setIsUrlValid] = useState(true);\n const [hasConfirmedUrl, setHasConfirmedUrl] = useState(false);\n const [errorMessage, setErrorMessage] = useState(\"\");\n const [url, setUrl] = useState(\"\");\n const [debouncedUrl, setDebouncedUrl] = useDebounceValue(url, 500);\n\n const { register, handleSubmit, setValue } = useForm<Inputs>({\n mode: \"onBlur\",\n defaultValues: {\n availableOffline: remoteDriveDetails?.availableOffline ?? false,\n },\n });\n\n useEffect(() => {\n setDebouncedUrl(url);\n }, [url]);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setHasConfirmedUrl(false);\n if (debouncedUrl === \"\") return;\n fetchPublicDrive().catch(console.error);\n\n async function fetchPublicDrive() {\n try {\n const { id, name } = await requestPublicDrive(debouncedUrl);\n setPublicDriveDetails({\n id,\n name,\n sharingType,\n location: \"SWITCHBOARD\",\n availableOffline: true,\n });\n setValue(\"availableOffline\", true);\n setIsUrlValid(true);\n setErrorMessage(\"\");\n } catch (error) {\n setPublicDriveDetails(undefined);\n setIsUrlValid(false);\n setErrorMessage((error as Error).message);\n }\n }\n }, [debouncedUrl, setValue, sharingType]);\n\n function onSubmit({ availableOffline }: Inputs) {\n if (!remoteDriveDetails) return;\n props.onSubmit({\n ...remoteDriveDetails,\n availableOffline,\n url: debouncedUrl,\n });\n }\n\n return (\n <form onSubmit={(e) => void handleSubmit(onSubmit)(e)}>\n {hasConfirmedUrl ? (\n <>\n <DriveName driveName={remoteDriveDetails?.name ?? \"New drive\"} />\n <Divider className=\"my-3\" />\n <Disclosure\n isOpen={showLocationSettings}\n onOpenChange={() => setShowLocationSettings(!showLocationSettings)}\n title=\"Location\"\n >\n <LocationInfo location=\"SWITCHBOARD\" />\n <AvailableOfflineToggle {...register(\"availableOffline\")} />\n </Disclosure>\n <PowerhouseButton className=\"mt-4 w-full\" color=\"dark\" type=\"submit\">\n Add new drive\n </PowerhouseButton>\n </>\n ) : (\n <>\n <FormInput\n errorMessage={errorMessage}\n onChange={(e) => setUrl(e.target.value)}\n placeholder=\"Drive URL\"\n required\n type=\"url\"\n value={url}\n />\n <PowerhouseButton\n className=\"mt-4 w-full py-2 text-base\"\n color=\"dark\"\n size=\"small\"\n disabled={!isUrlValid || url === \"\"}\n onClick={(e) => {\n e.preventDefault();\n setHasConfirmedUrl(true);\n }}\n type=\"button\"\n >\n Add drive\n </PowerhouseButton>\n </>\n )}\n </form>\n );\n}\n","import { useTheme } from \"@powerhousedao/reactor-browser\";\nimport { JsonView, type JsonViewProps } from \"@uiw/react-json-view\";\nimport { darkTheme } from \"@uiw/react-json-view/dark\";\nimport { lightTheme } from \"@uiw/react-json-view/light\";\nimport { isStrictEqual, isString } from \"remeda\";\nimport { Icon } from \"../../powerhouse/index.js\";\n\n/* Shows arbitrary JSON content in a nicely formatted viewer.\n * Takes all the same props as the JSON view React component.\n * Provides some quality of life improvements:\n *\n * allows expand and collapse of any / all of the rendered fields\n * Allows copy-paste of the whole object as well as individual fields, with a success indicator\n * Formats very long text fields so that they are first truncated, and then if expanded word wrap applies\n */\nexport function FormattedJsonViewer(props: JsonViewProps<object>) {\n const { theme } = useTheme();\n const style = theme === \"light\" ? lightTheme : darkTheme;\n return (\n <JsonView\n displayDataTypes={false}\n displayObjectSize={false}\n style={style}\n {...props}\n >\n <JsonView.Copied\n render={({ onClick, ...props }) => {\n if ((props as { \"data-copied\": boolean })[\"data-copied\"]) {\n return (\n <Icon\n {...props}\n className=\"inline-block text-green-800 dark:text-green-100\"\n name=\"FilesEarmark\"\n size={16}\n />\n );\n }\n return (\n <Icon\n {...props}\n onClick={onClick}\n className=\"inline-block cursor-pointer text-gray-700 dark:text-slate-200\"\n name=\"FilesEarmark\"\n size={16}\n />\n );\n }}\n />\n <JsonView.String\n render={({ children, ...rest }, { value, keyName }) => {\n // strings are truncated with ellipsis at 30 chars in this component by default\n const maxLength = 30;\n if (\n // if the children are a plain string, we know this is a text node\n isString(children) &&\n // the value should therefore also be a string\n isString(value) &&\n // when the content is truncated, the children will be the truncated content\n // and the value will be the original content\n // we know that the content is not truncated if the value and the children are the same\n isStrictEqual(children, value) &&\n // if the string is long then apply word wrap to avoid letting the parent component put everything\n // on one line\n value.length > maxLength\n ) {\n return (\n /* use inline grid so that this text is still aligned with the field name */\n <span {...rest} className=\"inline-grid\">\n <span\n // We must wrap anywhere because data can be of any length\n // do not use hyphens, show the raw content\n // apply one character of left padding and negative indent because of the string quotation mark\n className=\"pl-[1ch] indent-[-1ch] wrap-anywhere hyphens-none\"\n style={{\n // calculate the line width from the width of the key in the json\n maxWidth: `${60 - keyName.toString().length}ch`,\n }}\n >\n \"{children}\"\n </span>\n </span>\n );\n }\n return <span {...rest}>\"{children}\"</span>;\n }}\n />\n </JsonView>\n );\n}\n","type HomeBackgroundImageProps = {\n src?: string;\n};\n\nexport const HomeBackgroundImage = ({ src }: HomeBackgroundImageProps = {}) => {\n if (src) {\n return (\n <picture className=\"pointer-events-none absolute inset-8 z-0 size-[calc(100%-32px)] object-contain\">\n <img src={src} alt=\"background\" className=\"object-contain\" />\n </picture>\n );\n }\n\n return (\n <div className=\"pointer-events-none fixed top-0 z-0 size-full bg-gray-50 dark:bg-slate-800\">\n <svg\n width=\"1858\"\n height=\"1256\"\n viewBox=\"0 0 1858 1256\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <g clipPath=\"url(#clip0_4090_11134)\">\n <ellipse\n opacity=\"0.3\"\n cx=\"478.092\"\n cy=\"523.885\"\n rx=\"983.498\"\n ry=\"480.668\"\n transform=\"rotate(36.3289 478.092 523.885)\"\n fill=\"url(#paint0_radial_4090_11134)\"\n fillOpacity=\"0.3\"\n />\n <g opacity=\"0.3\">\n <ellipse\n cx=\"1385.68\"\n cy=\"503.347\"\n rx=\"759.956\"\n ry=\"331.584\"\n transform=\"rotate(36.3289 1385.68 503.347)\"\n fill=\"url(#paint1_radial_4090_11134)\"\n fillOpacity=\"0.2\"\n style={{ mixBlendMode: \"screen\" }}\n />\n </g>\n </g>\n <defs>\n <radialGradient\n id=\"paint0_radial_4090_11134\"\n cx=\"0\"\n cy=\"0\"\n r=\"1\"\n gradientUnits=\"userSpaceOnUse\"\n gradientTransform=\"translate(500.331 508.304) rotate(89.0086) scale(508.666 1077.08)\"\n >\n <stop stopColor=\"white\" stopOpacity=\"0\" />\n <stop stopColor=\"#FF3FAC\" />\n <stop offset=\"0.363434\" stopColor=\"#9D25FC\" stopOpacity=\"0.41\" />\n <stop offset=\"0.745192\" stopColor=\"#141718\" stopOpacity=\"0\" />\n </radialGradient>\n <radialGradient\n id=\"paint1_radial_4090_11134\"\n cx=\"0\"\n cy=\"0\"\n r=\"1\"\n gradientUnits=\"userSpaceOnUse\"\n gradientTransform=\"translate(1385.68 503.347) rotate(90) scale(331.584 759.956)\"\n >\n <stop stopColor=\"#0084FF\" />\n <stop offset=\"0.802885\" stopColor=\"#141718\" stopOpacity=\"0\" />\n </radialGradient>\n <clipPath id=\"clip0_4090_11134\">\n <rect width=\"1858\" height=\"1256\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n </div>\n );\n};\n","import { Icon } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\n\ntype HomeScreenItemProps = {\n readonly icon?: React.JSX.Element;\n readonly title: string;\n readonly description?: string;\n readonly containerClassName?: string;\n readonly shareable?: boolean;\n readonly onClick?: (event: React.MouseEvent<HTMLDivElement>) => void;\n};\nexport const HomeScreenItem = function HomeScreenItem(\n props: HomeScreenItemProps,\n) {\n const { icon, title, description, containerClassName, shareable, onClick } =\n props;\n return (\n <div\n className={twMerge(\n \"hover-bg-transparent relative flex h-24 w-40 cursor-pointer flex-col items-center justify-center overflow-hidden rounded-md p-2 text-center text-sm text-gray-900 dark:text-slate-50\",\n containerClassName,\n onClick && \"cursor-pointer\",\n )}\n onClick={onClick}\n >\n <div className=\"mx-auto pb-2\">\n {icon || (\n <div className=\"size-8 items-center justify-center rounded-lg bg-gray-900 pt-1 dark:bg-slate-50\">\n <span className=\"w-6 text-white dark:text-slate-900\">\n {title.slice(0, 1).toUpperCase()}\n </span>\n </div>\n )}\n </div>\n <div className=\"w-full max-w-full\">\n <h3 className=\"w-full max-w-full truncate px-2 text-gray-900 dark:text-slate-50\">\n {title}\n </h3>\n {description && (\n <p className=\"text-gray-500 dark:text-slate-400\">{description}</p>\n )}\n </div>\n {shareable && (\n <div className=\"absolute top-0 left-2 mb-2\">\n <Icon name=\"PeopleFill\" width={12} height={12} />\n </div>\n )}\n </div>\n );\n};\n","import { Icon } from \"#design-system\";\nimport { showPHModal } from \"@powerhousedao/reactor-browser\";\nimport { HomeScreenItem } from \"./home-screen-item.js\";\ntype HomeScreenAddDriveItemProps = {\n readonly containerClassName?: string;\n};\nexport const HomeScreenAddDriveItem = function HomeScreenAddDriveItem(\n props: HomeScreenAddDriveItemProps,\n) {\n const { containerClassName } = props;\n return (\n <HomeScreenItem\n title=\"Create New Drive\"\n icon={<Icon name=\"PlusSquare\" size={32} />}\n onClick={() => showPHModal({ type: \"addDrive\" })}\n containerClassName={containerClassName}\n />\n );\n};\n","import { twMerge } from \"tailwind-merge\";\nimport { HomeBackgroundImage } from \"./home-background-image.js\";\n\ntype HomeScreenProps = {\n readonly children: React.ReactNode;\n readonly containerClassName?: string;\n readonly homeBackground?: string | null;\n};\n\nexport const HomeScreen = function HomeScreen(props: HomeScreenProps) {\n const { children, containerClassName, homeBackground } = props;\n return (\n <div\n className={twMerge(\n \"relative container mx-auto flex h-full flex-col\",\n containerClassName,\n )}\n >\n <div className=\"m-8 flex flex-wrap justify-center gap-4 bg-gray-50 pt-12 dark:bg-slate-800\">\n <HomeBackgroundImage src={homeBackground ?? undefined} />\n {children}\n </div>\n </div>\n );\n};\n","import { Icon } from \"#design-system\";\nimport { useCallback, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\nimport type {\n RebuildResult,\n ValidationResult,\n} from \"@powerhousedao/reactor-browser\";\n\nexport type IntegrityInspectorProps = {\n readonly onValidate: (\n documentId: string,\n branch?: string,\n ) => Promise<ValidationResult>;\n readonly onRebuildKeyframes: (\n documentId: string,\n branch?: string,\n ) => Promise<RebuildResult>;\n readonly onRebuildSnapshots: (\n documentId: string,\n branch?: string,\n ) => Promise<RebuildResult>;\n};\n\ntype ActionStatus = \"idle\" | \"running\" | \"done\" | \"error\";\ntype ConfirmAction = \"keyframes\" | \"snapshots\" | null;\n\nexport function IntegrityInspector({\n onValidate,\n onRebuildKeyframes,\n onRebuildSnapshots,\n}: IntegrityInspectorProps) {\n const [documentId, setDocumentId] = useState(\"\");\n const [branch, setBranch] = useState(\"\");\n const [status, setStatus] = useState<ActionStatus>(\"idle\");\n const [validationResult, setValidationResult] =\n useState<ValidationResult | null>(null);\n const [rebuildResult, setRebuildResult] = useState<RebuildResult | null>(\n null,\n );\n const [error, setError] = useState<string | null>(null);\n const [confirmAction, setConfirmAction] = useState<ConfirmAction>(null);\n\n const clearResults = useCallback(() => {\n setValidationResult(null);\n setRebuildResult(null);\n setError(null);\n setConfirmAction(null);\n }, []);\n\n const handleValidate = useCallback(async () => {\n if (!documentId.trim()) return;\n clearResults();\n setStatus(\"running\");\n try {\n const result = await onValidate(\n documentId.trim(),\n branch.trim() || undefined,\n );\n setValidationResult(result);\n setStatus(\"done\");\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n setStatus(\"error\");\n }\n }, [documentId, branch, onValidate, clearResults]);\n\n const handleRebuildKeyframes = useCallback(async () => {\n if (!documentId.trim()) return;\n clearResults();\n setStatus(\"running\");\n try {\n const result = await onRebuildKeyframes(\n documentId.trim(),\n branch.trim() || undefined,\n );\n setRebuildResult(result);\n setStatus(\"done\");\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n setStatus(\"error\");\n }\n }, [documentId, branch, onRebuildKeyframes, clearResults]);\n\n const handleRebuildSnapshots = useCallback(async () => {\n if (!documentId.trim()) return;\n clearResults();\n setStatus(\"running\");\n try {\n const result = await onRebuildSnapshots(\n documentId.trim(),\n branch.trim() || undefined,\n );\n setRebuildResult(result);\n setStatus(\"done\");\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n setStatus(\"error\");\n }\n }, [documentId, branch, onRebuildSnapshots, clearResults]);\n\n return (\n <div className=\"flex h-full flex-col gap-3\">\n <div className=\"flex shrink-0 items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-gray-900 dark:text-slate-50\">\n Integrity Inspector\n </h2>\n </div>\n\n <div className=\"flex shrink-0 items-end gap-3\">\n <div className=\"flex flex-1 flex-col gap-1\">\n <label className=\"text-xs font-medium text-gray-700 dark:text-slate-200\">\n Document ID\n </label>\n <input\n className=\"rounded-sm border border-gray-300 px-3 py-1.5 text-sm outline-none focus:border-blue-400 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:focus:border-blue-500\"\n onChange={(e) => setDocumentId(e.target.value)}\n placeholder=\"Enter document ID\"\n type=\"text\"\n value={documentId}\n />\n </div>\n <div className=\"flex w-40 flex-col gap-1\">\n <label className=\"text-xs font-medium text-gray-700 dark:text-slate-200\">\n Branch (optional)\n </label>\n <input\n className=\"rounded-sm border border-gray-300 px-3 py-1.5 text-sm outline-none focus:border-blue-400 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:focus:border-blue-500\"\n onChange={(e) => setBranch(e.target.value)}\n placeholder=\"main\"\n type=\"text\"\n value={branch}\n />\n </div>\n <div className=\"flex gap-2\">\n <button\n className=\"flex items-center gap-1 rounded-sm border border-blue-300 bg-blue-50 px-3 py-1.5 text-sm text-blue-700 hover:bg-blue-100 disabled:opacity-50 dark:border-blue-600 dark:bg-blue-900 dark:text-blue-100 dark:hover:bg-blue-800\"\n disabled={\n !documentId.trim() ||\n status === \"running\" ||\n confirmAction !== null\n }\n onClick={() => void handleValidate()}\n type=\"button\"\n >\n <Icon name=\"Checkmark\" size={14} />\n Validate\n </button>\n <button\n className=\"flex items-center gap-1 rounded-sm border border-yellow-300 bg-yellow-50 px-3 py-1.5 text-sm text-yellow-700 hover:bg-yellow-100 disabled:opacity-50 dark:border-yellow-600 dark:bg-yellow-900 dark:text-yellow-100 dark:hover:bg-yellow-800\"\n disabled={\n !documentId.trim() ||\n status === \"running\" ||\n confirmAction !== null\n }\n onClick={() => setConfirmAction(\"keyframes\")}\n type=\"button\"\n >\n <Icon name=\"Reload\" size={14} />\n Rebuild Keyframes\n </button>\n <button\n className=\"flex items-center gap-1 rounded-sm border border-yellow-300 bg-yellow-50 px-3 py-1.5 text-sm text-yellow-700 hover:bg-yellow-100 disabled:opacity-50 dark:border-yellow-600 dark:bg-yellow-900 dark:text-yellow-100 dark:hover:bg-yellow-800\"\n disabled={\n !documentId.trim() ||\n status === \"running\" ||\n confirmAction !== null\n }\n onClick={() => setConfirmAction(\"snapshots\")}\n type=\"button\"\n >\n <Icon name=\"Reload\" size={14} />\n Rebuild Snapshots\n </button>\n </div>\n </div>\n\n {confirmAction && (\n <div className=\"flex shrink-0 items-center gap-3 rounded-sm border border-yellow-400 bg-yellow-50 px-3 py-2 dark:border-yellow-500 dark:bg-yellow-900\">\n <span className=\"text-sm text-yellow-800 dark:text-yellow-100\">\n {confirmAction === \"keyframes\"\n ? \"This will delete all keyframes for this document. Continue?\"\n : \"This will invalidate all cached snapshots for this document. Continue?\"}\n </span>\n <button\n className=\"rounded-sm bg-yellow-600 px-3 py-1 text-sm text-white hover:bg-yellow-700 dark:bg-yellow-300 dark:text-slate-900 dark:hover:bg-yellow-200\"\n onClick={() => {\n if (confirmAction === \"keyframes\") {\n void handleRebuildKeyframes();\n } else {\n void handleRebuildSnapshots();\n }\n }}\n type=\"button\"\n >\n Confirm\n </button>\n <button\n className=\"rounded-sm border border-gray-300 bg-gray-50 px-3 py-1 text-sm text-gray-700 hover:bg-gray-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-800\"\n onClick={() => setConfirmAction(null)}\n type=\"button\"\n >\n Cancel\n </button>\n </div>\n )}\n\n <div className=\"min-h-0 flex-1 overflow-auto rounded-lg border border-gray-300 p-4 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {status === \"idle\" && (\n <div className=\"flex h-full items-center justify-center text-sm text-gray-400 dark:text-slate-500\">\n Enter a document ID and run an action\n </div>\n )}\n\n {status === \"running\" && (\n <div className=\"flex h-full items-center justify-center text-sm text-gray-500 dark:text-slate-400\">\n Running...\n </div>\n )}\n\n {status === \"error\" && error && (\n <div className=\"rounded-sm bg-red-50 p-3 text-sm text-red-700 dark:bg-red-900 dark:text-red-100\">\n {error}\n </div>\n )}\n\n {status === \"done\" && validationResult && (\n <ValidationResultView result={validationResult} />\n )}\n\n {status === \"done\" && rebuildResult && (\n <RebuildResultView result={rebuildResult} />\n )}\n </div>\n </div>\n );\n}\n\nfunction ValidationResultView({ result }: { result: ValidationResult }) {\n const totalIssues =\n result.keyframeIssues.length + result.snapshotIssues.length;\n\n return (\n <div className=\"flex flex-col gap-3\">\n <div className=\"flex items-center gap-2\">\n <span\n className={twMerge(\n \"size-3 rounded-full\",\n result.isConsistent\n ? \"bg-green-500 dark:bg-green-400\"\n : \"bg-red-500 dark:bg-red-400\",\n )}\n />\n <span className=\"text-sm font-medium\">\n {result.isConsistent\n ? \"Document is consistent\"\n : `Found ${totalIssues} issue(s)`}\n </span>\n </div>\n\n <div className=\"text-xs text-gray-500 dark:text-slate-400\">\n Document: {result.documentId}\n </div>\n\n {result.keyframeIssues.length > 0 && (\n <div className=\"flex flex-col gap-1\">\n <h3 className=\"text-sm font-medium text-gray-700 dark:text-slate-200\">\n Keyframe Issues\n </h3>\n <table className=\"w-full border-collapse text-xs\">\n <thead>\n <tr className=\"bg-gray-100 dark:bg-slate-700\">\n <th className=\"px-2 py-1 text-left font-medium text-gray-700 dark:text-slate-200\">\n Scope\n </th>\n <th className=\"border-l border-gray-300 px-2 py-1 text-left font-medium text-gray-700 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n Branch\n </th>\n <th className=\"border-l border-gray-300 px-2 py-1 text-left font-medium text-gray-700 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n Revision\n </th>\n <th className=\"border-l border-gray-300 px-2 py-1 text-left font-medium text-gray-700 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n Keyframe Hash\n </th>\n <th className=\"border-l border-gray-300 px-2 py-1 text-left font-medium text-gray-700 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n Replayed Hash\n </th>\n </tr>\n </thead>\n <tbody>\n {result.keyframeIssues.map((issue, i) => (\n <tr\n key={`kf-${i}`}\n className=\"odd:bg-white even:bg-gray-50 dark:odd:bg-slate-800 dark:even:bg-slate-800\"\n >\n <td className=\"px-2 py-1\">{issue.scope}</td>\n <td className=\"border-l border-gray-300 px-2 py-1 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {issue.branch}\n </td>\n <td className=\"border-l border-gray-300 px-2 py-1 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {issue.revision}\n </td>\n <td className=\"border-l border-gray-300 px-2 py-1 font-mono dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {issue.keyframeHash}\n </td>\n <td className=\"border-l border-gray-300 px-2 py-1 font-mono dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {issue.replayedHash}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n\n {result.snapshotIssues.length > 0 && (\n <div className=\"flex flex-col gap-1\">\n <h3 className=\"text-sm font-medium text-gray-700 dark:text-slate-200\">\n Snapshot Issues\n </h3>\n <table className=\"w-full border-collapse text-xs\">\n <thead>\n <tr className=\"bg-gray-100 dark:bg-slate-700\">\n <th className=\"px-2 py-1 text-left font-medium text-gray-700 dark:text-slate-200\">\n Scope\n </th>\n <th className=\"border-l border-gray-300 px-2 py-1 text-left font-medium text-gray-700 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n Branch\n </th>\n <th className=\"border-l border-gray-300 px-2 py-1 text-left font-medium text-gray-700 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n Snapshot Hash\n </th>\n <th className=\"border-l border-gray-300 px-2 py-1 text-left font-medium text-gray-700 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n Replayed Hash\n </th>\n </tr>\n </thead>\n <tbody>\n {result.snapshotIssues.map((issue, i) => (\n <tr\n key={`snap-${i}`}\n className=\"odd:bg-white even:bg-gray-50 dark:odd:bg-slate-800 dark:even:bg-slate-800\"\n >\n <td className=\"px-2 py-1\">{issue.scope}</td>\n <td className=\"border-l border-gray-300 px-2 py-1 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {issue.branch}\n </td>\n <td className=\"border-l border-gray-300 px-2 py-1 font-mono dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {issue.snapshotHash}\n </td>\n <td className=\"border-l border-gray-300 px-2 py-1 font-mono dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {issue.replayedHash}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </div>\n );\n}\n\nfunction RebuildResultView({ result }: { result: RebuildResult }) {\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"size-3 rounded-full bg-green-500 dark:bg-green-400\" />\n <span className=\"text-sm font-medium\">Rebuild complete</span>\n </div>\n <div className=\"text-xs text-gray-500 dark:text-slate-400\">\n Document: {result.documentId}\n </div>\n {result.keyframesDeleted > 0 && (\n <div className=\"text-sm text-gray-700 dark:text-slate-200\">\n Keyframes deleted: {result.keyframesDeleted}\n </div>\n )}\n {result.scopesInvalidated > 0 && (\n <div className=\"text-sm text-gray-700 dark:text-slate-200\">\n Scopes invalidated: {result.scopesInvalidated}\n </div>\n )}\n </div>\n );\n}\n","import { twMerge } from \"tailwind-merge\";\nimport { LogoAnimation } from \"../logo-animation.js\";\n\nexport interface LoadingScreenProps {\n showLoadingScreen: boolean;\n loadingComponent?: React.ReactNode;\n size?: number;\n className?: string;\n}\n\nexport const LoadingScreen: React.FC<LoadingScreenProps> = (props) => {\n const { showLoadingScreen, loadingComponent, size, className } = props;\n\n if (loadingComponent && showLoadingScreen) {\n return loadingComponent;\n }\n\n return (\n <div\n className={twMerge(\n \"absolute inset-0 z-10 flex items-center justify-center bg-gray-50 dark:bg-slate-800\",\n !showLoadingScreen && \"hidden\",\n className,\n )}\n >\n <LogoAnimation size={size} />\n </div>\n );\n};\n","import type { AppOptions, DivProps } from \"#design-system\";\nimport { Modal } from \"#design-system\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { AddLocalDriveForm } from \"../../form/add-local-drive-form.js\";\nimport {\n type AddRemoteDriveInput,\n AddRemoteDriveForm,\n} from \"../../form/add-remote-drive-form.js\";\nimport { TabContent } from \"../../tabs/tab-content.js\";\nimport { Tabs } from \"../../tabs/tabs.js\";\n\ntype ModalProps = ComponentPropsWithoutRef<typeof Modal>;\nexport type AddDriveModalProps = {\n readonly open: boolean;\n readonly onOpenChange: (open: boolean) => void;\n readonly onAddRemoteDrive: (data: AddRemoteDriveInput) => void;\n readonly onAddLocalDrive: (data: AppOptions) => void;\n readonly modalProps?: ModalProps;\n readonly containerProps?: DivProps;\n readonly requestPublicDrive: (\n url: string,\n ) => Promise<{ id: string; name: string }>;\n readonly appOptions: AppOptions[];\n};\nexport function AddDriveModal(props: AddDriveModalProps) {\n function handleCancel() {\n onOpenChange(false);\n }\n const {\n open,\n onOpenChange,\n onAddRemoteDrive,\n onAddLocalDrive,\n requestPublicDrive,\n modalProps,\n containerProps,\n } = props;\n return (\n <Modal\n {...modalProps}\n overlayProps={{\n className: \"items-start pt-[15vh]\",\n }}\n onOpenChange={onOpenChange}\n open={open}\n >\n <div\n {...containerProps}\n className={twMerge(\n \"w-102 rounded-2xl bg-gray-50 p-6 dark:bg-slate-800\",\n containerProps?.className,\n )}\n >\n <Tabs defaultValue=\"Create Drive\">\n <TabContent label=\"Create Drive\" description=\"Create a new drive\">\n <AddLocalDriveForm\n onCancel={handleCancel}\n onSubmit={onAddLocalDrive}\n appOptions={props.appOptions}\n />\n </TabContent>\n <TabContent label=\"Add Drive\" description=\"Add a drive\">\n <AddRemoteDriveForm\n sharingType=\"PUBLIC\"\n onSubmit={onAddRemoteDrive}\n onCancel={handleCancel}\n requestPublicDrive={requestPublicDrive}\n />\n </TabContent>\n </Tabs>\n </div>\n </Modal>\n );\n}\n","import { Icon, Modal } from \"#design-system\";\nimport { isValidName } from \"@powerhousedao/shared/document-drive\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { useCallback, useState } from \"react\";\nimport { FormInput } from \"../form-input/form-input.js\";\nimport { ModalButton } from \"./modal-button.js\";\n\nexport type CreateDocumentModalProps = ComponentPropsWithoutRef<\n typeof Modal\n> & {\n readonly onContinue: (nodeName: string) => void;\n};\n\nconst CLOSE_ANIMATION_DURATION = 300;\n\nexport function CreateDocumentModal(props: CreateDocumentModalProps) {\n const { onOpenChange, onContinue, overlayProps, contentProps, ...restProps } =\n props;\n\n const [nodeName, setNodeName] = useState(\"\");\n const [isValid, setIsValid] = useState(false);\n\n const handleCancel = () => {\n onOpenChange?.(false);\n setTimeout(() => setNodeName(\"\"), CLOSE_ANIMATION_DURATION);\n };\n\n const handleCreate = useCallback(() => {\n if (!isValid) {\n return;\n }\n\n onContinue(nodeName);\n setTimeout(() => setNodeName(\"\"), CLOSE_ANIMATION_DURATION);\n }, [isValid, nodeName, onContinue]);\n\n const handleSubmit = useCallback(\n (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n handleCreate();\n },\n [handleCreate],\n );\n\n return (\n <Modal\n contentProps={contentProps}\n onOpenChange={onOpenChange}\n overlayProps={{\n ...overlayProps,\n className: overlayProps?.className,\n }}\n {...restProps}\n >\n <form\n name=\"create-document\"\n className=\"w-100 rounded-xl bg-gray-50 p-6 text-gray-300 dark:bg-slate-800 dark:text-slate-600\"\n onSubmit={handleSubmit}\n >\n <div className=\"pb-2 text-2xl font-bold text-gray-900 dark:text-slate-100\">\n Create a new document\n </div>\n <div className=\"my-6\">\n {!isValid && nodeName && (\n <div className=\"mb-2 text-red-500 dark:text-red-100\">\n Document name must not be empty or contain control characters.\n </div>\n )}\n <FormInput\n icon={<Icon name=\"BrickGlobe\" />}\n onChange={(e) => {\n const name = e.target.value;\n setNodeName(name);\n setIsValid(isValidName(name));\n }}\n placeholder=\"Document name\"\n required\n value={nodeName}\n />\n </div>\n <div className=\"mt-8 flex justify-between gap-3\">\n <ModalButton variant=\"cancel\" type=\"button\" onClick={handleCancel}>\n Cancel\n </ModalButton>\n <ModalButton variant=\"confirm\" type=\"submit\" disabled={!isValid}>\n Create\n </ModalButton>\n </div>\n </form>\n </Modal>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { useState } from \"react\";\nimport { FormInput } from \"../form-input/form-input.js\";\nimport type { ConfirmationModalProps } from \"./confirmation-modal.js\";\nimport { ConnectConfirmationModal } from \"./confirmation-modal.js\";\n\nexport interface ConnectDeleteDriveModalProps extends ConfirmationModalProps {\n readonly inputPlaceholder: string;\n readonly driveName: string;\n}\n\nexport const ConnectDeleteDriveModal: React.FC<ConnectDeleteDriveModalProps> = (\n props,\n) => {\n const { inputPlaceholder, body, driveName, ...confirmationModalProps } =\n props;\n\n const [inputName, setInputName] = useState(\"\");\n\n return (\n <ConnectConfirmationModal\n {...confirmationModalProps}\n continueDisabled={inputName !== driveName}\n body={\n <div>\n <div className=\"my-6 rounded-md bg-gray-50 p-4 text-center dark:bg-slate-800\">\n {body}\n </div>\n <div>\n <FormInput\n hideErrors\n icon={<Icon name=\"Lock\" />}\n onChange={(e) => setInputName(e.target.value)}\n placeholder={inputPlaceholder}\n value={inputName}\n />\n </div>\n </div>\n }\n ></ConnectConfirmationModal>\n );\n};\n","import {\n type ConfirmationModalProps,\n ConnectConfirmationModal,\n} from \"./confirmation-modal.js\";\n\nexport interface ConnectDeleteItemModalProps extends Omit<\n ConfirmationModalProps,\n \"onContinue\" | \"continueLabel\"\n> {\n readonly onDelete: () => void;\n readonly deleteLabel: string;\n}\n\nexport function ConnectDeleteItemModal(props: ConnectDeleteItemModalProps) {\n const { onDelete, deleteLabel, ...restProps } = props;\n\n return (\n <ConnectConfirmationModal\n {...restProps}\n continueLabel={deleteLabel}\n onContinue={onDelete}\n />\n );\n}\n","import { Icon } from \"#design-system\";\nimport type { ComponentPropsWithRef, ForwardedRef } from \"react\";\nimport { forwardRef } from \"react\";\nimport { FormInput } from \"../../form-input/form-input.js\";\n\ntype DriveNameInputProps = Omit<\n ComponentPropsWithRef<typeof FormInput>,\n \"icon\" | \"id\"\n> & {\n readonly icon?: React.JSX.Element;\n};\n\nexport const DriveNameInput = forwardRef(function DriveNameInput(\n props: DriveNameInputProps,\n ref: ForwardedRef<HTMLInputElement>,\n) {\n return (\n <FormInput\n {...props}\n icon={props.icon ?? <Icon name=\"Drive\" />}\n id=\"driveName\"\n placeholder=\"Drive name\"\n ref={ref}\n />\n );\n});\n","import { Icon, PowerhouseButton } from \"#design-system\";\nimport type { DocumentDriveDocument } from \"@powerhousedao/shared/document-drive\";\nimport { useState } from \"react\";\nimport { DriveNameInput } from \"./drive-name-input.js\";\n\nexport type DeleteDriveProps = {\n drive: DocumentDriveDocument;\n handleDeleteDrive: () => void;\n onCancel: () => void;\n};\n\nexport function DeleteDrive(props: DeleteDriveProps) {\n const { drive, handleDeleteDrive, onCancel } = props;\n const [driveNameInput, setDriveNameInput] = useState(\"\");\n\n const isAllowedToDelete = driveNameInput === drive.header.name;\n\n function deleteDrive() {\n if (isAllowedToDelete) {\n handleDeleteDrive();\n }\n }\n\n return (\n <div>\n <p className=\"mb-2 rounded-md bg-gray-50 p-4 text-center text-gray-200 dark:bg-slate-800 dark:text-slate-200\">\n Are you sure you want to delete this drive? All files and subfolders\n within it will be removed. Do you want to proceed?\n </p>\n <DriveNameInput\n icon={<Icon name=\"Lock\" />}\n onChange={(event) => setDriveNameInput(event.target.value)}\n placeholder=\"Enter drive name...\"\n value={driveNameInput}\n />\n <div className=\"flex gap-3\">\n <PowerhouseButton className=\"w-full\" color=\"light\" onClick={onCancel}>\n Cancel\n </PowerhouseButton>\n <PowerhouseButton\n className=\"w-full\"\n color=\"red\"\n disabled={!isAllowedToDelete}\n onClick={deleteDrive}\n >\n Delete\n </PowerhouseButton>\n </div>\n </div>\n );\n}\n","import { Icon, PowerhouseButton } from \"#design-system\";\nimport type { DriveSystemInfoState } from \"@powerhousedao/reactor-browser\";\nimport type { DocumentDriveDocument } from \"@powerhousedao/shared/document-drive\";\nimport type { SharingType } from \"@powerhousedao/shared/document-drive\";\nimport { useState } from \"react\";\nimport type { SubmitHandler } from \"react-hook-form\";\nimport { useForm } from \"react-hook-form\";\nimport { Disclosure } from \"../disclosure/disclosure.js\";\nimport { Divider } from \"../divider/divider.js\";\nimport { AvailableOfflineToggle } from \"./inputs/available-offline-toggle.js\";\nimport { DeleteDrive } from \"./inputs/delete-drive.js\";\nimport { DriveNameInput } from \"./inputs/drive-name-input.js\";\nimport { Label } from \"./inputs/label.js\";\nimport { LocationInfo } from \"./inputs/location-info.js\";\nimport { SharingTypeFormInput } from \"./inputs/sharing-type-form-input.js\";\n\ntype Inputs = {\n name: string;\n sharingType: SharingType;\n availableOffline: boolean;\n};\n\ntype DriveSettingsFormProps = {\n drive: DocumentDriveDocument;\n sharingType: SharingType;\n availableOffline: boolean;\n systemInfo: DriveSystemInfoState;\n onSubmit: DriveSettingsFormSubmitHandler;\n handleCancel: () => void;\n handleDeleteDrive: () => void;\n};\n\nexport type DriveSettingsFormSubmitHandler = SubmitHandler<Inputs>;\n\nexport function DriveSettingsForm(props: DriveSettingsFormProps) {\n const {\n drive,\n sharingType,\n availableOffline,\n systemInfo,\n onSubmit,\n handleDeleteDrive,\n } = props;\n const name = drive.header.name;\n\n const [showLocationSettings, setShowLocationSettings] = useState(false);\n const [showAbout, setShowAbout] = useState(false);\n const [showDangerZone, setShowDangerZone] = useState(false);\n const [showDeleteDrive, setShowDeleteDrive] = useState(false);\n\n const { register, handleSubmit, control } = useForm<Inputs>({\n mode: \"onBlur\",\n defaultValues: {\n name,\n sharingType,\n availableOffline,\n },\n });\n\n const location = sharingType === \"PUBLIC\" ? \"SWITCHBOARD\" : sharingType;\n\n return (\n <form onSubmit={(e) => void handleSubmit(onSubmit)(e)}>\n <DriveNameInput {...register(\"name\")} />\n <Divider className=\"my-4\" />\n <Label htmlFor=\"sharingType\">Sharing settings</Label>\n <SharingTypeFormInput control={control} />\n <Divider className=\"my-3\" />\n <Disclosure\n isOpen={showLocationSettings}\n onOpenChange={() => setShowLocationSettings(!showLocationSettings)}\n title=\"Location\"\n >\n <LocationInfo location={location} />\n <AvailableOfflineToggle {...register(\"availableOffline\")} />\n </Disclosure>\n <Divider className=\"my-3\" />\n <Disclosure\n isOpen={showAbout}\n onOpenChange={() => setShowAbout(!showAbout)}\n title=\"About this drive\"\n >\n {systemInfo.status === \"local\" && (\n <p className=\"py-2 text-sm text-gray-500 dark:text-slate-400\">\n Local drive — N/A\n </p>\n )}\n {systemInfo.status === \"loading\" && (\n <p className=\"py-2 text-sm text-gray-400 dark:text-slate-500\">\n Loading…\n </p>\n )}\n {systemInfo.status === \"error\" && (\n <p className=\"py-2 text-sm text-red-600 dark:text-red-100\">\n Could not load system info\n </p>\n )}\n {systemInfo.status === \"ready\" && (\n <div className=\"py-2 text-sm text-gray-700 dark:text-slate-200\">\n <div>\n <span className=\"font-medium\">Version:</span> {systemInfo.version}\n </div>\n <div>\n <span className=\"font-medium\">Git hash:</span>{\" \"}\n {systemInfo.gitHash}\n </div>\n </div>\n )}\n </Disclosure>\n <Divider className=\"my-3\" />\n <Disclosure\n isOpen={showDangerZone}\n onOpenChange={() => setShowDangerZone(!showDangerZone)}\n title=\"Danger zone\"\n >\n <button\n className=\"flex gap-2 py-3 font-semibold text-red-900 transition hover:brightness-125 dark:text-red-400\"\n onClick={() => setShowDeleteDrive(true)}\n type=\"button\"\n >\n <Icon name=\"Trash\" />\n Delete drive\n </button>\n </Disclosure>\n {showDeleteDrive && showDangerZone ? (\n <DeleteDrive\n drive={drive}\n handleDeleteDrive={handleDeleteDrive}\n onCancel={() => setShowDeleteDrive(false)}\n />\n ) : (\n <>\n <Divider className=\"my-3\" />\n <PowerhouseButton className=\"mb-4 w-full\" type=\"submit\">\n Confirm\n </PowerhouseButton>\n </>\n )}\n </form>\n );\n}\n","import type { DivProps } from \"#design-system\";\nimport { Icon, Modal } from \"#design-system\";\nimport type { DriveSystemInfoState } from \"@powerhousedao/reactor-browser\";\nimport type { DocumentDriveDocument } from \"@powerhousedao/shared/document-drive\";\nimport type { SharingType } from \"@powerhousedao/shared/document-drive\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Divider } from \"../divider/divider.js\";\nimport {\n type DriveSettingsFormSubmitHandler,\n DriveSettingsForm,\n} from \"../form/drive-settings-form.js\";\n\ntype ModalProps = ComponentPropsWithoutRef<typeof Modal>;\n\nexport type DriveSettingsModalProps = {\n drive: DocumentDriveDocument;\n sharingType: SharingType;\n availableOffline: boolean;\n systemInfo: DriveSystemInfoState;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onRenameDrive: (drive: DocumentDriveDocument, newName: string) => void;\n onDeleteDrive: (drive: DocumentDriveDocument) => void;\n onChangeSharingType: (\n drive: DocumentDriveDocument,\n newSharingType: SharingType,\n ) => void;\n onChangeAvailableOffline: (\n drive: DocumentDriveDocument,\n newAvailableOffline: boolean,\n ) => void;\n modalProps?: ModalProps;\n containerProps?: DivProps;\n};\nexport function DriveSettingsModal(props: DriveSettingsModalProps) {\n const {\n drive,\n open,\n sharingType,\n availableOffline,\n systemInfo,\n onOpenChange,\n onDeleteDrive,\n onRenameDrive,\n onChangeSharingType,\n onChangeAvailableOffline,\n modalProps,\n containerProps,\n } = props;\n\n const onSubmit: DriveSettingsFormSubmitHandler = (data) => {\n if (data.name !== drive.header.name) {\n onRenameDrive(drive, data.name);\n }\n if (data.sharingType !== sharingType) {\n onChangeSharingType(drive, data.sharingType);\n }\n if (data.availableOffline !== availableOffline) {\n onChangeAvailableOffline(drive, data.availableOffline);\n }\n onOpenChange(false);\n };\n\n function handleDeleteDrive() {\n onDeleteDrive(drive);\n onOpenChange(false);\n }\n\n function handleCancel() {\n onOpenChange(false);\n }\n\n return (\n <Modal\n {...modalProps}\n contentProps={{\n className: \"rounded-2xl\",\n }}\n onOpenChange={onOpenChange}\n open={open}\n >\n <div\n {...containerProps}\n className={twMerge(\n \"max-w-[408px] rounded-2xl bg-gray-50 p-6 dark:bg-slate-800\",\n containerProps?.className,\n )}\n >\n <div className=\"flex justify-between\">\n <h1 className=\"text-xl font-bold text-gray-900 dark:text-slate-50\">\n Drive settings\n </h1>\n <button\n className=\"flex size-8 items-center justify-center rounded-md bg-gray-100 text-gray-500 outline-none hover:text-gray-900 dark:bg-slate-700 dark:text-slate-400 dark:hover:text-slate-50\"\n onClick={handleCancel}\n tabIndex={-1}\n >\n <Icon name=\"XmarkLight\" size={24} />\n </button>\n </div>\n <Divider className=\"my-4\" />\n <DriveSettingsForm\n handleCancel={handleCancel}\n handleDeleteDrive={handleDeleteDrive}\n onSubmit={onSubmit}\n drive={drive}\n sharingType={sharingType}\n availableOffline={availableOffline}\n systemInfo={systemInfo}\n />\n </div>\n </Modal>\n );\n}\n","import { Icon, Modal } from \"#design-system\";\nimport { JsonViewer } from \"#design-system/ui\";\n\n/**\n * Converts an object to a JSON-serializable form by handling\n * non-serializable values like functions, symbols, and errors.\n */\nfunction toSerializableObject(obj: unknown): unknown {\n return JSON.parse(\n JSON.stringify(obj, (_key, value: unknown) => {\n if (typeof value === \"function\") return \"[Function]\";\n if (typeof value === \"symbol\") return \"[Symbol]\";\n if (value instanceof Error)\n return { name: value.name, message: value.message };\n return value;\n }),\n );\n}\n\nexport type ObjectInspectorModalProps = {\n readonly open: boolean;\n readonly onOpenChange: (open: boolean) => void;\n readonly title: string;\n readonly object: unknown;\n};\n\nexport function ObjectInspectorModal({\n open,\n onOpenChange,\n title,\n object,\n}: ObjectInspectorModalProps) {\n const serializableObject = object ? toSerializableObject(object) : null;\n\n return (\n <Modal\n contentProps={{\n className: \"rounded-2xl\",\n style: { height: \"80vh\", width: \"80vw\", maxWidth: \"900px\" },\n }}\n onOpenChange={onOpenChange}\n open={open}\n title={title}\n >\n <div className=\"flex size-full flex-col bg-gray-50 dark:bg-slate-800\">\n <div className=\"flex shrink-0 items-center justify-between border-b border-gray-200 px-4 py-3 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <h2 className=\"text-lg font-semibold text-gray-900 dark:text-slate-50\">\n {title}\n </h2>\n <button\n className=\"flex size-6 cursor-pointer items-center justify-center rounded-md text-gray-500 outline-none hover:text-gray-900 dark:text-slate-400 dark:hover:text-slate-50\"\n onClick={() => onOpenChange(false)}\n type=\"button\"\n >\n <Icon name=\"XmarkLight\" size={24} />\n </button>\n </div>\n\n <div className=\"flex-1 overflow-auto p-4\">\n {serializableObject ? (\n <JsonViewer data={serializableObject} />\n ) : (\n <p className=\"text-gray-500 dark:text-slate-400\">\n No data to display\n </p>\n )}\n </div>\n </div>\n </Modal>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ObjectInspectorModal } from \"../object-inspector-modal/index.js\";\n\nexport type ProcessorInfo = {\n processorId: string;\n factoryId: string;\n driveId: string;\n processorIndex: number;\n lastOrdinal: number;\n status: \"active\" | \"errored\";\n lastError: string | undefined;\n lastErrorTimestamp: Date | undefined;\n};\n\nexport type ProcessorsInspectorProps = {\n readonly getProcessors: () => Promise<ProcessorInfo[]>;\n readonly onRetry?: (processorId: string) => Promise<void>;\n};\n\ntype SortDirection = \"asc\" | \"desc\";\n\ntype SortOptions = {\n readonly column: string;\n readonly direction: SortDirection;\n};\n\ntype ColumnDef = {\n readonly key: string;\n readonly label: string;\n readonly width?: string;\n};\n\nconst VIEW_COLUMN: ColumnDef = { key: \"view\", label: \"\", width: \"60px\" };\n\nconst COLUMNS: ColumnDef[] = [\n VIEW_COLUMN,\n { key: \"status\", label: \"Status\", width: \"90px\" },\n { key: \"processorId\", label: \"Processor ID\", width: \"150px\" },\n { key: \"factoryId\", label: \"Factory ID\", width: \"150px\" },\n { key: \"driveId\", label: \"Drive ID\", width: \"150px\" },\n { key: \"processorIndex\", label: \"Index\", width: \"70px\" },\n { key: \"lastOrdinal\", label: \"Last Ordinal\", width: \"100px\" },\n { key: \"lastError\", label: \"Error\", width: \"180px\" },\n { key: \"lastErrorTimestamp\", label: \"Error At\", width: \"160px\" },\n { key: \"actions\", label: \"Actions\", width: \"80px\" },\n];\n\nfunction truncateId(id: string, maxLength: number = 12): string {\n if (id.length <= maxLength) return id;\n return id.slice(0, maxLength) + \"...\";\n}\n\nfunction sortProcessors(\n processors: ProcessorInfo[],\n sort: SortOptions | undefined,\n): ProcessorInfo[] {\n if (!sort) return processors;\n\n return [...processors].sort((a, b) => {\n let comparison: number;\n\n switch (sort.column) {\n case \"status\":\n comparison = a.status.localeCompare(b.status);\n break;\n case \"processorId\":\n comparison = a.processorId.localeCompare(b.processorId);\n break;\n case \"factoryId\":\n comparison = a.factoryId.localeCompare(b.factoryId);\n break;\n case \"driveId\":\n comparison = a.driveId.localeCompare(b.driveId);\n break;\n case \"processorIndex\":\n comparison = a.processorIndex - b.processorIndex;\n break;\n case \"lastOrdinal\":\n comparison = a.lastOrdinal - b.lastOrdinal;\n break;\n case \"lastError\":\n comparison = (a.lastError ?? \"\").localeCompare(b.lastError ?? \"\");\n break;\n case \"lastErrorTimestamp\":\n comparison =\n (a.lastErrorTimestamp?.getTime() ?? 0) -\n (b.lastErrorTimestamp?.getTime() ?? 0);\n break;\n default:\n return 0;\n }\n\n return sort.direction === \"asc\" ? comparison : -comparison;\n });\n}\n\nfunction SortIcon({\n direction,\n active,\n}: {\n direction: SortDirection;\n active: boolean;\n}) {\n if (!active) {\n return (\n <Icon\n className=\"opacity-0 group-hover:opacity-50\"\n name=\"CaretSort\"\n size={12}\n />\n );\n }\n\n return (\n <Icon\n className={direction === \"asc\" ? \"rotate-180\" : undefined}\n name=\"TriangleDown\"\n size={12}\n />\n );\n}\n\nexport function ProcessorsInspector({\n getProcessors,\n onRetry,\n}: ProcessorsInspectorProps) {\n const [processors, setProcessors] = useState<ProcessorInfo[]>([]);\n const [loading, setLoading] = useState(true);\n const [sort, setSort] = useState<SortOptions | undefined>();\n const [retryingId, setRetryingId] = useState<string | null>(null);\n const [selectedProcessor, setSelectedProcessor] =\n useState<ProcessorInfo | null>(null);\n\n const [error, setError] = useState<string | null>(null);\n\n const loadProcessors = useCallback(async () => {\n try {\n const result = await getProcessors();\n setProcessors(result);\n setError(null);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setLoading(false);\n }\n }, [getProcessors]);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n void loadProcessors();\n\n const interval = setInterval(() => {\n void loadProcessors();\n }, 2000);\n\n return () => clearInterval(interval);\n }, [loadProcessors]);\n\n const handleRefresh = useCallback(async () => {\n setLoading(true);\n await loadProcessors();\n }, [loadProcessors]);\n\n const handleRetry = useCallback(\n async (processorId: string) => {\n if (!onRetry) return;\n setRetryingId(processorId);\n try {\n await onRetry(processorId);\n await loadProcessors();\n } finally {\n setRetryingId(null);\n }\n },\n [onRetry, loadProcessors],\n );\n\n const handleSort = (columnKey: string) => {\n const newDirection: SortDirection =\n sort?.column === columnKey && sort.direction === \"asc\" ? \"desc\" : \"asc\";\n\n setSort({ column: columnKey, direction: newDirection });\n };\n\n const sortedProcessors = sortProcessors(processors, sort);\n\n const activeCount = processors.filter((p) => p.status === \"active\").length;\n const erroredCount = processors.filter((p) => p.status === \"errored\").length;\n\n return (\n <div className=\"flex h-full flex-col gap-2\">\n <div className=\"flex shrink-0 items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-gray-900 dark:text-slate-50\">\n Processors Inspector\n </h2>\n <div className=\"flex items-center gap-2\">\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={loading}\n onClick={() => void handleRefresh()}\n type=\"button\"\n >\n <Icon name=\"Reload\" size={14} />\n Refresh\n </button>\n </div>\n </div>\n\n <div className=\"flex shrink-0 items-center gap-4 rounded-lg bg-gray-100 px-4 py-2 text-sm dark:bg-slate-700\">\n <div className=\"text-gray-700 dark:text-slate-200\">\n Total: <span className=\"font-medium\">{processors.length}</span>\n </div>\n <div className=\"flex items-center gap-2 text-gray-700 dark:text-slate-200\">\n <span className=\"size-2 rounded-full bg-green-500 dark:bg-green-400\" />\n Active: <span className=\"font-medium\">{activeCount}</span>\n </div>\n <div className=\"flex items-center gap-2 text-gray-700 dark:text-slate-200\">\n <span className=\"size-2 rounded-full bg-red-500 dark:bg-red-400\" />\n Errored: <span className=\"font-medium\">{erroredCount}</span>\n </div>\n </div>\n\n {error && (\n <div className=\"shrink-0 rounded-lg border border-red-300 bg-red-50 px-4 py-2 text-sm text-red-700 dark:border-red-600 dark:bg-red-900 dark:text-red-100\">\n Failed to load processors: {error}\n </div>\n )}\n\n <div className=\"max-h-full overflow-auto rounded-lg border border-gray-300 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <table className=\"w-full border-collapse\">\n <thead className=\"sticky top-0 bg-gray-100 dark:bg-slate-700\">\n <tr>\n {COLUMNS.map((column, index) => {\n const isActive = sort?.column === column.key;\n const sortDirection = isActive ? sort.direction : \"asc\";\n\n return (\n <th\n key={column.key}\n className={twMerge(\n \"group cursor-pointer px-3 py-2 text-left text-xs font-medium text-gray-700 hover:bg-gray-200 hover:text-gray-900 dark:text-slate-200 dark:hover:bg-slate-600 dark:hover:text-slate-100\",\n index > 0 &&\n \"border-l border-gray-300 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n )}\n onClick={() => handleSort(column.key)}\n style={{ width: column.width }}\n >\n <div className=\"flex items-center gap-1\">\n <span className=\"truncate\">{column.label}</span>\n <SortIcon active={isActive} direction={sortDirection} />\n </div>\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {loading && sortedProcessors.length === 0 ? (\n <tr>\n <td\n className=\"px-3 py-8 text-center text-sm text-gray-500 dark:text-slate-400\"\n colSpan={COLUMNS.length}\n >\n Loading...\n </td>\n </tr>\n ) : sortedProcessors.length === 0 ? (\n <tr>\n <td\n className=\"px-3 py-8 text-center text-sm text-gray-500 dark:text-slate-400\"\n colSpan={COLUMNS.length}\n >\n No processors registered\n </td>\n </tr>\n ) : (\n sortedProcessors.map((processor) => (\n <tr\n key={processor.processorId}\n className={twMerge(\n \"hover:bg-blue-50 dark:hover:bg-blue-900\",\n processor.status === \"errored\"\n ? \"bg-red-50 dark:bg-red-900\"\n : \"odd:bg-white even:bg-gray-50 dark:odd:bg-slate-800 dark:even:bg-slate-800\",\n )}\n >\n <td className=\"px-3 py-2 text-xs\">\n <button\n className=\"flex items-center gap-1 rounded-sm bg-blue-50 px-2 py-1 text-xs text-blue-700 hover:bg-blue-100 dark:bg-blue-900 dark:text-blue-100 dark:hover:bg-blue-800\"\n onClick={() => setSelectedProcessor(processor)}\n type=\"button\"\n >\n View\n </button>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span\n className={twMerge(\n \"inline-flex items-center gap-1 rounded-sm px-1.5 py-0.5\",\n processor.status === \"active\"\n ? \"bg-green-100 text-green-700 dark:bg-green-800 dark:text-green-100\"\n : \"bg-red-100 text-red-700 dark:bg-red-800 dark:text-red-100\",\n )}\n >\n {processor.status === \"active\" && (\n <span className=\"inline-block size-1.5 rounded-full bg-green-500 dark:bg-green-400\" />\n )}\n {processor.status === \"errored\" && (\n <span className=\"inline-block size-1.5 rounded-full bg-red-500 dark:bg-red-400\" />\n )}\n {processor.status}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span\n className=\"block truncate\"\n title={processor.processorId}\n >\n {truncateId(processor.processorId)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span\n className=\"block truncate\"\n title={processor.factoryId}\n >\n {truncateId(processor.factoryId)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"block truncate\" title={processor.driveId}>\n {truncateId(processor.driveId)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {processor.processorIndex}\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {processor.lastOrdinal}\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {processor.lastError ? (\n <span\n className=\"block truncate text-red-600 dark:text-red-100\"\n title={processor.lastError}\n >\n {processor.lastError}\n </span>\n ) : (\n <span className=\"text-gray-400 dark:text-slate-500\">\n -\n </span>\n )}\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {processor.lastErrorTimestamp ? (\n <span\n className=\"block truncate\"\n title={processor.lastErrorTimestamp.toISOString()}\n >\n {processor.lastErrorTimestamp.toLocaleString()}\n </span>\n ) : (\n <span className=\"text-gray-400 dark:text-slate-500\">\n -\n </span>\n )}\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {processor.status === \"errored\" && onRetry && (\n <button\n className=\"flex items-center gap-1 rounded-sm bg-yellow-50 px-2 py-1 text-xs text-yellow-700 hover:bg-yellow-100 disabled:opacity-50 dark:bg-yellow-900 dark:text-yellow-100 dark:hover:bg-yellow-800\"\n disabled={retryingId === processor.processorId}\n onClick={() => void handleRetry(processor.processorId)}\n type=\"button\"\n >\n Retry\n </button>\n )}\n </td>\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n\n <div className=\"shrink-0 text-sm text-gray-700 dark:text-slate-200\">\n Showing {sortedProcessors.length} processor(s)\n </div>\n\n <ObjectInspectorModal\n object={selectedProcessor}\n onOpenChange={(open) => !open && setSelectedProcessor(null)}\n open={selectedProcessor !== null}\n title=\"Processor\"\n />\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport type { Job } from \"@powerhousedao/reactor-browser\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ObjectInspectorModal } from \"../object-inspector-modal/index.js\";\n\nexport type QueueState = {\n readonly isPaused: boolean;\n readonly pendingJobs: Job[];\n readonly executingJobs: Job[];\n readonly totalPending: number;\n readonly totalExecuting: number;\n};\n\nexport type QueueInspectorProps = {\n readonly getQueueState: () => Promise<QueueState>;\n readonly onPause: () => Promise<void>;\n readonly onResume: () => Promise<void>;\n};\n\ntype SortDirection = \"asc\" | \"desc\";\n\ntype SortOptions = {\n readonly column: string;\n readonly direction: SortDirection;\n};\n\ntype ColumnDef = {\n readonly key: string;\n readonly label: string;\n readonly width?: string;\n};\n\nconst VIEW_COLUMN: ColumnDef = { key: \"view\", label: \"\", width: \"60px\" };\n\nconst COLUMNS: ColumnDef[] = [\n VIEW_COLUMN,\n { key: \"id\", label: \"ID\", width: \"120px\" },\n { key: \"kind\", label: \"Kind\", width: \"80px\" },\n { key: \"documentId\", label: \"Document ID\", width: \"150px\" },\n { key: \"scope\", label: \"Scope\", width: \"100px\" },\n { key: \"branch\", label: \"Branch\", width: \"100px\" },\n { key: \"createdAt\", label: \"Created At\", width: \"160px\" },\n { key: \"retryCount\", label: \"Retries\", width: \"70px\" },\n { key: \"status\", label: \"Status\", width: \"100px\" },\n];\n\nfunction truncateId(id: string, maxLength: number = 12): string {\n if (id.length <= maxLength) return id;\n return id.slice(0, maxLength) + \"...\";\n}\n\nfunction formatDate(dateStr: string): string {\n const date = new Date(dateStr);\n return date.toLocaleString();\n}\n\ntype JobWithStatus = Job & { status: \"pending\" | \"executing\" };\n\nfunction sortJobs(\n jobs: JobWithStatus[],\n sort: SortOptions | undefined,\n): JobWithStatus[] {\n if (!sort) return jobs;\n\n return [...jobs].sort((a, b) => {\n let comparison: number;\n\n switch (sort.column) {\n case \"id\":\n comparison = a.id.localeCompare(b.id);\n break;\n case \"kind\":\n comparison = a.kind.localeCompare(b.kind);\n break;\n case \"documentId\":\n comparison = a.documentId.localeCompare(b.documentId);\n break;\n case \"scope\":\n comparison = a.scope.localeCompare(b.scope);\n break;\n case \"branch\":\n comparison = a.branch.localeCompare(b.branch);\n break;\n case \"createdAt\":\n comparison = a.createdAt.localeCompare(b.createdAt);\n break;\n case \"retryCount\":\n comparison = (a.retryCount ?? 0) - (b.retryCount ?? 0);\n break;\n case \"status\":\n comparison = a.status.localeCompare(b.status);\n break;\n default:\n return 0;\n }\n\n return sort.direction === \"asc\" ? comparison : -comparison;\n });\n}\n\nfunction SortIcon({\n direction,\n active,\n}: {\n direction: SortDirection;\n active: boolean;\n}) {\n if (!active) {\n return (\n <Icon\n className=\"opacity-0 group-hover:opacity-50\"\n name=\"CaretSort\"\n size={12}\n />\n );\n }\n\n return (\n <Icon\n className={direction === \"asc\" ? \"rotate-180\" : undefined}\n name=\"TriangleDown\"\n size={12}\n />\n );\n}\n\nexport function QueueInspector({\n getQueueState,\n onPause,\n onResume,\n}: QueueInspectorProps) {\n const [state, setState] = useState<QueueState>({\n isPaused: false,\n pendingJobs: [],\n executingJobs: [],\n totalPending: 0,\n totalExecuting: 0,\n });\n const [loading, setLoading] = useState(true);\n const [sort, setSort] = useState<SortOptions | undefined>();\n const [actionInProgress, setActionInProgress] = useState(false);\n const [selectedJob, setSelectedJob] = useState<JobWithStatus | null>(null);\n\n const loadState = useCallback(async () => {\n const newState = await getQueueState();\n setState(newState);\n setLoading(false);\n }, [getQueueState]);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n void loadState();\n\n const interval = setInterval(() => {\n void loadState();\n }, 2000);\n\n return () => clearInterval(interval);\n }, [loadState]);\n\n const handleRefresh = useCallback(async () => {\n setLoading(true);\n await loadState();\n }, [loadState]);\n\n const handlePauseResume = useCallback(async () => {\n setActionInProgress(true);\n if (state.isPaused) {\n await onResume();\n } else {\n await onPause();\n }\n await loadState();\n setActionInProgress(false);\n }, [state.isPaused, onPause, onResume, loadState]);\n\n const handleSort = (columnKey: string) => {\n const newDirection: SortDirection =\n sort?.column === columnKey && sort.direction === \"asc\" ? \"desc\" : \"asc\";\n\n setSort({ column: columnKey, direction: newDirection });\n };\n\n const allJobs: JobWithStatus[] = [\n ...state.executingJobs.map((job) => ({\n ...job,\n status: \"executing\" as const,\n })),\n ...state.pendingJobs.map((job) => ({ ...job, status: \"pending\" as const })),\n ];\n\n const sortedJobs = sortJobs(allJobs, sort);\n\n return (\n <div className=\"flex h-full flex-col gap-2\">\n <div className=\"flex shrink-0 items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-gray-900 dark:text-slate-50\">\n Queue Inspector\n </h2>\n <div className=\"flex items-center gap-2\">\n <button\n className={twMerge(\n \"flex items-center gap-1 rounded-sm border px-3 py-1.5 text-sm disabled:opacity-50\",\n state.isPaused\n ? \"border-green-300 bg-green-50 text-green-700 hover:bg-green-100 dark:border-green-600 dark:bg-green-900 dark:text-green-100 dark:hover:bg-green-800\"\n : \"border-yellow-300 bg-yellow-50 text-yellow-700 hover:bg-yellow-100 dark:border-yellow-600 dark:bg-yellow-900 dark:text-yellow-100 dark:hover:bg-yellow-800\",\n )}\n disabled={actionInProgress}\n onClick={() => void handlePauseResume()}\n type=\"button\"\n >\n <Icon\n name={state.isPaused ? \"ArrowFilledRight\" : \"Ellipsis\"}\n size={14}\n />\n {state.isPaused ? \"Resume\" : \"Pause\"}\n </button>\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={loading}\n onClick={() => void handleRefresh()}\n type=\"button\"\n >\n <Icon name=\"Reload\" size={14} />\n Refresh\n </button>\n </div>\n </div>\n\n <div className=\"flex shrink-0 items-center gap-4 rounded-lg bg-gray-100 px-4 py-2 text-sm dark:bg-slate-700\">\n <div className=\"flex items-center gap-2\">\n <span\n className={twMerge(\n \"size-2 rounded-full\",\n state.isPaused\n ? \"bg-yellow-500 dark:bg-yellow-400\"\n : \"bg-green-500 dark:bg-green-400\",\n )}\n />\n <span className=\"font-medium text-gray-700 dark:text-slate-200\">\n {state.isPaused ? \"Paused\" : \"Running\"}\n </span>\n </div>\n <div className=\"text-gray-700 dark:text-slate-200\">\n Pending: <span className=\"font-medium\">{state.totalPending}</span>\n </div>\n <div className=\"text-gray-700 dark:text-slate-200\">\n Executing: <span className=\"font-medium\">{state.totalExecuting}</span>\n </div>\n </div>\n\n <div className=\"max-h-full overflow-auto rounded-lg border border-gray-300 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <table className=\"w-full border-collapse\">\n <thead className=\"sticky top-0 bg-gray-100 dark:bg-slate-700\">\n <tr>\n {COLUMNS.map((column, index) => {\n const isActive = sort?.column === column.key;\n const sortDirection = isActive ? sort.direction : \"asc\";\n\n return (\n <th\n key={column.key}\n className={twMerge(\n \"group cursor-pointer px-3 py-2 text-left text-xs font-medium text-gray-700 hover:bg-gray-200 hover:text-gray-900 dark:text-slate-200 dark:hover:bg-slate-600 dark:hover:text-slate-100\",\n index > 0 &&\n \"border-l border-gray-300 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n )}\n onClick={() => handleSort(column.key)}\n style={{ width: column.width }}\n >\n <div className=\"flex items-center gap-1\">\n <span className=\"truncate\">{column.label}</span>\n <SortIcon active={isActive} direction={sortDirection} />\n </div>\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {loading && sortedJobs.length === 0 ? (\n <tr>\n <td\n className=\"px-3 py-8 text-center text-sm text-gray-500 dark:text-slate-400\"\n colSpan={COLUMNS.length}\n >\n Loading...\n </td>\n </tr>\n ) : sortedJobs.length === 0 ? (\n <tr>\n <td\n className=\"px-3 py-8 text-center text-sm text-gray-500 dark:text-slate-400\"\n colSpan={COLUMNS.length}\n >\n No jobs in queue\n </td>\n </tr>\n ) : (\n sortedJobs.map((job) => (\n <tr\n key={job.id}\n className=\"odd:bg-white even:bg-gray-50 hover:bg-blue-50 dark:odd:bg-slate-800 dark:even:bg-slate-800 dark:hover:bg-blue-900\"\n >\n <td className=\"px-3 py-2 text-xs\">\n <button\n className=\"flex items-center gap-1 rounded-sm bg-blue-50 px-2 py-1 text-xs text-blue-700 hover:bg-blue-100 dark:bg-blue-900 dark:text-blue-100 dark:hover:bg-blue-800\"\n onClick={() => setSelectedJob(job)}\n type=\"button\"\n >\n View\n </button>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"block truncate\" title={job.id}>\n {truncateId(job.id)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span\n className={twMerge(\n \"inline-block rounded-sm px-1.5 py-0.5\",\n job.kind === \"mutation\"\n ? \"bg-purple-100 text-purple-700 dark:bg-purple-800 dark:text-purple-100\"\n : \"bg-blue-100 text-blue-700 dark:bg-blue-800 dark:text-blue-100\",\n )}\n >\n {job.kind}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"block truncate\" title={job.documentId}>\n {truncateId(job.documentId)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"block truncate\" title={job.scope}>\n {job.scope}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"block truncate\" title={job.branch}>\n {job.branch}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"block truncate\" title={job.createdAt}>\n {formatDate(job.createdAt)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {job.retryCount ?? 0}\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span\n className={twMerge(\n \"inline-flex items-center gap-1 rounded-sm px-1.5 py-0.5\",\n job.status === \"executing\"\n ? \"bg-green-100 text-green-700 dark:bg-green-800 dark:text-green-100\"\n : \"bg-gray-100 text-gray-700 dark:bg-slate-700 dark:text-slate-200\",\n )}\n >\n {job.status === \"executing\" && (\n <span className=\"inline-block size-1.5 animate-pulse rounded-full bg-green-500 dark:bg-green-400\" />\n )}\n {job.status}\n </span>\n </td>\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n\n <div className=\"shrink-0 text-sm text-gray-700 dark:text-slate-200\">\n Showing {sortedJobs.length} job(s)\n </div>\n\n <ObjectInspectorModal\n object={selectedJob}\n onOpenChange={(open) => !open && setSelectedJob(null)}\n open={selectedJob !== null}\n title=\"Job\"\n />\n </div>\n );\n}\n","import { twMerge } from \"tailwind-merge\";\n\nexport type ConnectionStateBadgeProps = {\n readonly state: string;\n readonly failureCount: number;\n};\n\nconst stateStyles: Record<string, string> = {\n connected:\n \"bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100\",\n connecting: \"bg-blue-100 text-blue-800 dark:bg-blue-800 dark:text-blue-100\",\n reconnecting:\n \"bg-yellow-100 text-yellow-800 dark:bg-yellow-800 dark:text-yellow-100\",\n error: \"bg-red-100 text-red-800 dark:bg-red-800 dark:text-red-100\",\n disconnected:\n \"bg-gray-100 text-gray-700 dark:bg-slate-700 dark:text-slate-200\",\n};\n\nexport function ConnectionStateBadge({\n state,\n failureCount,\n}: ConnectionStateBadgeProps) {\n const style =\n stateStyles[state] ??\n \"bg-gray-100 text-gray-700 dark:bg-slate-700 dark:text-slate-200\";\n\n return (\n <span\n className={twMerge(\n \"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium\",\n style,\n )}\n >\n {state}\n {failureCount > 0 && (\n <span className=\"text-xs opacity-75\">({failureCount})</span>\n )}\n </span>\n );\n}\n","export type SortDirection = \"asc\" | \"desc\";\n\nexport type SortOptions = {\n readonly column: string;\n readonly direction: SortDirection;\n};\n\nexport type ColumnDef = {\n readonly key: string;\n readonly label: string;\n readonly width?: string;\n};\n\nexport function truncateId(id: string, maxLength: number = 12): string {\n if (id.length <= maxLength) return id;\n return id.slice(0, maxLength) + \"...\";\n}\n","import { Icon } from \"#design-system\";\nimport { type SortDirection } from \"../utils.js\";\n\nexport type SortIconProps = {\n readonly direction: SortDirection;\n readonly active: boolean;\n};\n\nexport function SortIcon({ direction, active }: SortIconProps) {\n if (!active) {\n return (\n <Icon\n className=\"opacity-0 group-hover:opacity-50\"\n name=\"CaretSort\"\n size={12}\n />\n );\n }\n\n return (\n <Icon\n className={direction === \"asc\" ? \"rotate-180\" : undefined}\n name=\"TriangleDown\"\n size={12}\n />\n );\n}\n","import { Icon } from \"#design-system\";\nimport {\n type SyncOperation,\n SyncOperationStatus,\n} from \"@powerhousedao/reactor-browser\";\nimport { useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ObjectInspectorModal } from \"../../object-inspector-modal/index.js\";\nimport { type ColumnDef, type SortOptions, truncateId } from \"../utils.js\";\nimport { SortIcon } from \"./sort-icon.js\";\n\nexport type MailboxType = \"inbox\" | \"outbox\" | \"deadLetter\";\n\nconst VIEW_COLUMN: ColumnDef = { key: \"view\", label: \"\", width: \"60px\" };\n\nconst COLUMNS: ColumnDef[] = [\n VIEW_COLUMN,\n { key: \"documentId\", label: \"Document ID\", width: \"150px\" },\n { key: \"branch\", label: \"Branch\", width: \"100px\" },\n { key: \"scopes\", label: \"Scopes\", width: \"100px\" },\n { key: \"status\", label: \"Status\", width: \"150px\" },\n { key: \"opsCount\", label: \"Ops Count\", width: \"80px\" },\n];\n\nconst DEAD_LETTER_COLUMNS: ColumnDef[] = [\n VIEW_COLUMN,\n { key: \"documentId\", label: \"Document ID\", width: \"150px\" },\n { key: \"branch\", label: \"Branch\", width: \"100px\" },\n { key: \"scopes\", label: \"Scopes\", width: \"100px\" },\n { key: \"error\", label: \"Error\", width: \"200px\" },\n];\n\nfunction toSerializableObject(obj: unknown): unknown {\n return JSON.parse(\n JSON.stringify(obj, (_key, value: unknown) => {\n if (typeof value === \"function\") return \"[Function]\";\n if (typeof value === \"symbol\") return \"[Symbol]\";\n if (value instanceof Error)\n return { name: value.name, message: value.message };\n return value;\n }),\n );\n}\n\nfunction getStatusLabel(status: SyncOperationStatus): string {\n switch (status) {\n case SyncOperationStatus.Unknown:\n return \"Unknown\";\n case SyncOperationStatus.TransportPending:\n return \"Transport Pending\";\n case SyncOperationStatus.ExecutionPending:\n return \"Execution Pending\";\n case SyncOperationStatus.Applied:\n return \"Applied\";\n case SyncOperationStatus.Error:\n return \"Error\";\n default:\n return \"Unknown\";\n }\n}\n\nfunction getStatusIcon(status: SyncOperationStatus): React.ReactNode {\n switch (status) {\n case SyncOperationStatus.TransportPending:\n case SyncOperationStatus.ExecutionPending:\n return <span>⏳</span>;\n case SyncOperationStatus.Applied:\n return <span>✅</span>;\n case SyncOperationStatus.Error:\n return <span>❌</span>;\n default:\n return <span>❓</span>;\n }\n}\n\nfunction getErrorMessage(error: SyncOperation[\"error\"]): string {\n if (!error) return \"\";\n return error.error.message;\n}\n\nfunction sortOperations(\n operations: readonly SyncOperation[],\n sort: SortOptions | undefined,\n): SyncOperation[] {\n const ops = [...operations];\n if (!sort) return ops;\n\n return ops.sort((a, b) => {\n let comparison: number;\n\n switch (sort.column) {\n case \"documentId\":\n comparison = a.documentId.localeCompare(b.documentId);\n break;\n case \"branch\":\n comparison = a.branch.localeCompare(b.branch);\n break;\n case \"scopes\":\n comparison = a.scopes.join(\",\").localeCompare(b.scopes.join(\",\"));\n break;\n case \"status\":\n comparison = a.status - b.status;\n break;\n case \"opsCount\":\n comparison = a.operations.length - b.operations.length;\n break;\n case \"error\":\n comparison = getErrorMessage(a.error).localeCompare(\n getErrorMessage(b.error),\n );\n break;\n default:\n return 0;\n }\n\n return sort.direction === \"asc\" ? comparison : -comparison;\n });\n}\n\nexport type MailboxTableProps = {\n readonly title: string;\n readonly mailboxType: MailboxType;\n readonly operations: readonly SyncOperation[];\n readonly sort: SortOptions | undefined;\n readonly onSort: (mailbox: MailboxType, column: string) => void;\n readonly collapsed: boolean;\n readonly onToggleCollapse: () => void;\n};\n\nexport function MailboxTable({\n title,\n mailboxType,\n operations,\n sort,\n onSort,\n collapsed,\n onToggleCollapse,\n}: MailboxTableProps) {\n const [selectedOperation, setSelectedOperation] =\n useState<SyncOperation | null>(null);\n const columns = mailboxType === \"deadLetter\" ? DEAD_LETTER_COLUMNS : COLUMNS;\n const sortedOps = sortOperations(operations, sort);\n\n const handleSort = (columnKey: string) => {\n onSort(mailboxType, columnKey);\n };\n\n const handleCopyAll = async () => {\n const serializable = toSerializableObject(operations);\n const json = JSON.stringify(serializable, null, 2);\n await navigator.clipboard.writeText(json);\n };\n\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex items-center justify-between\">\n <button\n className=\"flex items-center gap-2 text-left text-sm font-medium text-gray-700 hover:text-gray-900 dark:text-slate-200 dark:hover:text-slate-50\"\n onClick={onToggleCollapse}\n type=\"button\"\n >\n <Icon\n className={twMerge(\n \"transition-transform\",\n collapsed && \"-rotate-90\",\n )}\n name=\"ChevronDown\"\n size={14}\n />\n {title} ({operations.length} item{operations.length !== 1 ? \"s\" : \"\"})\n </button>\n {operations.length > 0 && (\n <button\n className=\"flex items-center gap-1 rounded-sm bg-gray-100 px-2 py-1 text-xs text-gray-700 hover:bg-gray-200 dark:bg-slate-700 dark:text-slate-200 dark:hover:bg-slate-600 dark:hover:text-slate-100\"\n onClick={() => void handleCopyAll()}\n type=\"button\"\n >\n <Icon name=\"Copy\" size={12} />\n Copy All\n </button>\n )}\n </div>\n\n {!collapsed && (\n <div className=\"scrollbar-thin overflow-auto rounded-lg border border-gray-300 scrollbar-thumb-gray-300 scrollbar-thumb-rounded-md scrollbar-track-transparent dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:scrollbar-thumb-slate-600\">\n <table className=\"w-full border-collapse\">\n <thead className=\"sticky top-0 bg-gray-100 dark:bg-slate-700\">\n <tr>\n {columns.map((column, index) => {\n const isActive = sort?.column === column.key;\n const sortDirection = isActive ? sort.direction : \"asc\";\n\n return (\n <th\n key={column.key}\n className={twMerge(\n \"group cursor-pointer px-3 py-2 text-left text-xs font-medium text-gray-700 hover:bg-gray-200 hover:text-gray-900 dark:text-slate-200 dark:hover:bg-slate-600 dark:hover:text-slate-100\",\n index > 0 &&\n \"border-l border-gray-300 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n )}\n onClick={() => handleSort(column.key)}\n style={{ width: column.width }}\n >\n <div className=\"flex items-center gap-1\">\n <span className=\"truncate\">{column.label}</span>\n <SortIcon active={isActive} direction={sortDirection} />\n </div>\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {sortedOps.length === 0 ? (\n <tr>\n <td\n className=\"px-3 py-4 text-center text-sm text-gray-500 dark:text-slate-400\"\n colSpan={columns.length}\n >\n No operations\n </td>\n </tr>\n ) : (\n sortedOps.map((op) => (\n <tr\n key={op.id}\n className=\"odd:bg-white even:bg-gray-50 hover:bg-blue-50 dark:odd:bg-slate-800 dark:even:bg-slate-800 dark:hover:bg-blue-900\"\n >\n <td className=\"px-3 py-2 text-xs\">\n <button\n className=\"flex items-center gap-1 rounded-sm bg-blue-50 px-2 py-1 text-xs text-blue-700 hover:bg-blue-100 dark:bg-blue-900 dark:text-blue-100 dark:hover:bg-blue-800\"\n onClick={() => setSelectedOperation(op)}\n type=\"button\"\n >\n View\n </button>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"block truncate\" title={op.documentId}>\n {truncateId(op.documentId)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"block truncate\" title={op.branch}>\n {op.branch}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span\n className=\"block truncate\"\n title={op.scopes.join(\", \")}\n >\n {op.scopes.join(\", \")}\n </span>\n </td>\n {mailboxType === \"deadLetter\" ? (\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span\n className=\"block truncate text-red-600 dark:text-red-100\"\n title={getErrorMessage(op.error)}\n >\n {getErrorMessage(op.error) || \"Unknown error\"}\n </span>\n </td>\n ) : (\n <>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"flex items-center gap-1\">\n {getStatusIcon(op.status)}\n {getStatusLabel(op.status)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {op.operations.length}\n </td>\n </>\n )}\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n )}\n\n <ObjectInspectorModal\n object={selectedOperation}\n onOpenChange={(open) => !open && setSelectedOperation(null)}\n open={selectedOperation !== null}\n title=\"Sync Operation\"\n />\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport type {\n IChannel,\n IntervalPollTimer,\n} from \"@powerhousedao/reactor-browser\";\nimport { useCallback, useState } from \"react\";\nimport type { ConnectionStateSummary } from \"../remotes-inspector.js\";\nimport { type SortDirection, type SortOptions } from \"../utils.js\";\nimport { ConnectionStateBadge } from \"./connection-state-badge.js\";\nimport { MailboxTable, type MailboxType } from \"./mailbox-table.js\";\n\nexport type ChannelInspectorProps = {\n readonly remoteName: string;\n readonly channel: IChannel;\n readonly onBack: () => void;\n readonly onRefresh?: () => void;\n readonly connectionState?: ConnectionStateSummary;\n};\n\nfunction formatTimestamp(ms: number): string {\n if (ms === 0) return \"-\";\n return new Date(ms).toLocaleTimeString();\n}\n\nexport function ChannelInspector({\n remoteName,\n channel,\n onBack,\n onRefresh,\n connectionState,\n}: ChannelInspectorProps) {\n const [sorts, setSorts] = useState<\n Record<MailboxType, SortOptions | undefined>\n >({\n inbox: undefined,\n outbox: undefined,\n deadLetter: undefined,\n });\n\n const [collapsed, setCollapsed] = useState<Record<MailboxType, boolean>>({\n inbox: false,\n outbox: false,\n deadLetter: false,\n });\n\n const handleToggleCollapse = (mailbox: MailboxType) => {\n setCollapsed((prev) => ({\n ...prev,\n [mailbox]: !prev[mailbox],\n }));\n };\n\n const handleSort = (mailbox: MailboxType, columnKey: string) => {\n setSorts((prev) => {\n const currentSort = prev[mailbox];\n const newDirection: SortDirection =\n currentSort?.column === columnKey && currentSort.direction === \"asc\"\n ? \"desc\"\n : \"asc\";\n\n return {\n ...prev,\n [mailbox]: { column: columnKey, direction: newDirection },\n };\n });\n };\n\n const getPollerControls = useCallback(() => {\n return \"poller\" in channel ? (channel.poller as IntervalPollTimer) : null;\n }, [channel]);\n\n const pollerControls = getPollerControls();\n const [pollerState, setPollerState] = useState(() => ({\n isPaused: pollerControls?.isPaused() ?? false,\n isRunning: pollerControls?.isRunning() ?? false,\n }));\n\n const [intervalMs, setIntervalMs] = useState(\n () => pollerControls?.getIntervalMs() ?? 2000,\n );\n\n const [mailboxStates, setMailboxStates] = useState(() => ({\n inbox: { isPaused: channel.inbox.isPaused() },\n outbox: { isPaused: channel.outbox.isPaused() },\n }));\n\n const handlePause = useCallback(() => {\n if (pollerControls) {\n pollerControls.pause();\n setPollerState({\n isPaused: pollerControls.isPaused(),\n isRunning: pollerControls.isRunning(),\n });\n }\n }, [pollerControls]);\n\n const handleResume = useCallback(() => {\n if (pollerControls) {\n pollerControls.resume();\n setPollerState({\n isPaused: pollerControls.isPaused(),\n isRunning: pollerControls.isRunning(),\n });\n }\n }, [pollerControls]);\n\n const handlePollNow = useCallback(() => {\n if (pollerControls) {\n pollerControls.triggerNow();\n }\n }, [pollerControls]);\n\n const handleApplyInterval = useCallback(() => {\n if (pollerControls) {\n pollerControls.setIntervalMs(intervalMs);\n }\n }, [pollerControls, intervalMs]);\n\n const handleMailboxPause = useCallback(\n (mailbox: \"inbox\" | \"outbox\") => {\n const mailboxInstance =\n mailbox === \"inbox\" ? channel.inbox : channel.outbox;\n mailboxInstance.pause();\n setMailboxStates((prev) => ({\n ...prev,\n [mailbox]: { isPaused: mailboxInstance.isPaused() },\n }));\n },\n [channel],\n );\n\n const handleMailboxResume = useCallback(\n (mailbox: \"inbox\" | \"outbox\") => {\n const mailboxInstance =\n mailbox === \"inbox\" ? channel.inbox : channel.outbox;\n mailboxInstance.resume();\n setMailboxStates((prev) => ({\n ...prev,\n [mailbox]: { isPaused: mailboxInstance.isPaused() },\n }));\n },\n [channel],\n );\n\n const handleMailboxFlush = useCallback(\n (mailbox: \"inbox\" | \"outbox\") => {\n const mailboxInstance =\n mailbox === \"inbox\" ? channel.inbox : channel.outbox;\n mailboxInstance.flush();\n onRefresh?.();\n },\n [channel, onRefresh],\n );\n\n return (\n <div className=\"flex h-full flex-col gap-3 overflow-auto\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-2 py-1 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={onBack}\n type=\"button\"\n >\n <Icon className=\"rotate-90\" name=\"ChevronDown\" size={14} />\n Back\n </button>\n <h2 className=\"text-lg font-semibold text-gray-900 dark:text-slate-50\">\n Channel: {remoteName}\n </h2>\n </div>\n {onRefresh && (\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={onRefresh}\n type=\"button\"\n >\n <Icon name=\"Reload\" size={14} />\n Refresh\n </button>\n )}\n </div>\n\n {connectionState && (\n <div className=\"rounded-sm border border-gray-200 bg-gray-50 p-4 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <h3 className=\"mb-3 text-sm font-semibold text-gray-900 dark:text-slate-50\">\n Connection State\n </h3>\n <div className=\"flex flex-wrap items-center gap-4 text-sm text-gray-700 dark:text-slate-200\">\n <div className=\"flex items-center gap-2\">\n <span>State:</span>\n <ConnectionStateBadge\n failureCount={connectionState.failureCount}\n state={connectionState.state}\n />\n </div>\n <div>\n Last success: {formatTimestamp(connectionState.lastSuccessUtcMs)}\n </div>\n <div>\n Last failure: {formatTimestamp(connectionState.lastFailureUtcMs)}\n </div>\n <div>Failures: {connectionState.failureCount}</div>\n <div>\n Push:{\" \"}\n <span\n className={\n connectionState.pushBlocked\n ? \"text-red-600 dark:text-red-100\"\n : \"text-green-600 dark:text-green-100\"\n }\n >\n {connectionState.pushBlocked ? \"Blocked\" : \"OK\"}\n </span>\n {connectionState.pushFailureCount > 0 && (\n <span className=\"ml-1 text-red-600 dark:text-red-100\">\n ({connectionState.pushFailureCount} failures)\n </span>\n )}\n </div>\n </div>\n </div>\n )}\n\n {pollerControls && (\n <div className=\"rounded-sm border border-gray-200 bg-gray-50 p-4 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <h3 className=\"mb-3 text-sm font-semibold text-gray-900 dark:text-slate-50\">\n Poller\n </h3>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-4\">\n <div className=\"text-sm text-gray-700 dark:text-slate-200\">\n Status:{\" \"}\n <span\n className={\n pollerState.isPaused\n ? \"text-yellow-600 dark:text-yellow-100\"\n : \"text-green-600 dark:text-green-100\"\n }\n >\n {pollerState.isPaused ? \"Paused\" : \"Running\"}\n </span>\n </div>\n <div className=\"flex items-center gap-1\">\n <label\n className=\"text-sm text-gray-700 dark:text-slate-200\"\n htmlFor=\"poll-interval\"\n >\n Interval:\n </label>\n <input\n className=\"w-20 rounded-sm border border-gray-300 px-2 py-1 text-sm dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\"\n id=\"poll-interval\"\n min={100}\n onChange={(e) => setIntervalMs(Number(e.target.value))}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n handleApplyInterval();\n }\n }}\n type=\"number\"\n value={intervalMs}\n />\n <span className=\"text-sm text-gray-500 dark:text-slate-400\">\n ms\n </span>\n <button\n className=\"ml-1 rounded-sm border border-gray-300 bg-gray-50 px-2 py-1 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={handleApplyInterval}\n type=\"button\"\n >\n Apply\n </button>\n </div>\n </div>\n <div className=\"flex gap-2\">\n {pollerState.isPaused ? (\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={handleResume}\n type=\"button\"\n >\n Resume\n </button>\n ) : (\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={handlePause}\n type=\"button\"\n >\n Pause\n </button>\n )}\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={!pollerState.isPaused}\n onClick={handlePollNow}\n type=\"button\"\n >\n Poll Now\n </button>\n </div>\n </div>\n </div>\n )}\n\n <div className=\"rounded-sm border border-gray-200 bg-gray-50 p-4 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <h3 className=\"mb-3 text-sm font-semibold text-gray-900 dark:text-slate-50\">\n Mailbox Processing\n </h3>\n <div className=\"flex flex-col gap-3\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3 text-sm text-gray-700 dark:text-slate-200\">\n <span>\n Inbox:{\" \"}\n <span\n className={\n mailboxStates.inbox.isPaused\n ? \"text-yellow-600 dark:text-yellow-100\"\n : \"text-green-600 dark:text-green-100\"\n }\n >\n {mailboxStates.inbox.isPaused ? \"Paused\" : \"Active\"}\n </span>\n </span>\n <span className=\"font-mono text-sm text-gray-500 dark:text-slate-400\">\n We ack'd (theirs): {channel.inbox.ackOrdinal} | Received:{\" \"}\n {channel.inbox.latestOrdinal}\n </span>\n </div>\n <div className=\"flex gap-2\">\n {mailboxStates.inbox.isPaused ? (\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={() => handleMailboxResume(\"inbox\")}\n type=\"button\"\n >\n Resume\n </button>\n ) : (\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={() => handleMailboxPause(\"inbox\")}\n type=\"button\"\n >\n Pause\n </button>\n )}\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={!mailboxStates.inbox.isPaused}\n onClick={() => handleMailboxFlush(\"inbox\")}\n type=\"button\"\n >\n Flush\n </button>\n </div>\n </div>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3 text-sm text-gray-700 dark:text-slate-200\">\n <span>\n Outbox:{\" \"}\n <span\n className={\n mailboxStates.outbox.isPaused\n ? \"text-yellow-600 dark:text-yellow-100\"\n : \"text-green-600 dark:text-green-100\"\n }\n >\n {mailboxStates.outbox.isPaused ? \"Paused\" : \"Active\"}\n </span>\n </span>\n <span className=\"font-mono text-sm text-gray-500 dark:text-slate-400\">\n They ack'd (ours): {channel.outbox.ackOrdinal} | Sent:{\" \"}\n {channel.outbox.latestOrdinal}\n </span>\n </div>\n <div className=\"flex gap-2\">\n {mailboxStates.outbox.isPaused ? (\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={() => handleMailboxResume(\"outbox\")}\n type=\"button\"\n >\n Resume\n </button>\n ) : (\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={() => handleMailboxPause(\"outbox\")}\n type=\"button\"\n >\n Pause\n </button>\n )}\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={!mailboxStates.outbox.isPaused}\n onClick={() => handleMailboxFlush(\"outbox\")}\n type=\"button\"\n >\n Flush\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <div className=\"flex flex-col gap-6\">\n <MailboxTable\n collapsed={collapsed.inbox}\n mailboxType=\"inbox\"\n onSort={handleSort}\n onToggleCollapse={() => handleToggleCollapse(\"inbox\")}\n operations={channel.inbox.items}\n sort={sorts.inbox}\n title=\"Inbox\"\n />\n\n <MailboxTable\n collapsed={collapsed.outbox}\n mailboxType=\"outbox\"\n onSort={handleSort}\n onToggleCollapse={() => handleToggleCollapse(\"outbox\")}\n operations={channel.outbox.items}\n sort={sorts.outbox}\n title=\"Outbox\"\n />\n\n <MailboxTable\n collapsed={collapsed.deadLetter}\n mailboxType=\"deadLetter\"\n onSort={handleSort}\n onToggleCollapse={() => handleToggleCollapse(\"deadLetter\")}\n operations={channel.deadLetter.items}\n sort={sorts.deadLetter}\n title=\"Dead Letter\"\n />\n </div>\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport type { Remote } from \"@powerhousedao/reactor-browser\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ChannelInspector } from \"./components/channel-inspector.js\";\nimport { ConnectionStateBadge } from \"./components/connection-state-badge.js\";\nimport { SortIcon } from \"./components/sort-icon.js\";\nimport {\n type ColumnDef,\n type SortDirection,\n type SortOptions,\n truncateId,\n} from \"./utils.js\";\n\nexport type ConnectionStateSummary = {\n state: string;\n failureCount: number;\n lastSuccessUtcMs: number;\n lastFailureUtcMs: number;\n pushBlocked: boolean;\n pushFailureCount: number;\n};\n\nexport type RemotesInspectorProps = {\n readonly getRemotes: () => Promise<Remote[]>;\n readonly removeRemote?: (name: string) => Promise<void>;\n readonly addRemoteManual?: (url: string) => Promise<void>;\n readonly triggerPull?: (name: string) => void;\n readonly connectionStates?: ReadonlyMap<string, ConnectionStateSummary>;\n};\n\nconst BASE_COLUMNS: ColumnDef[] = [\n { key: \"id\", label: \"ID\", width: \"120px\" },\n { key: \"name\", label: \"Name\", width: \"150px\" },\n { key: \"status\", label: \"Status\", width: \"120px\" },\n { key: \"collectionId\", label: \"Collection ID\", width: \"200px\" },\n { key: \"filter\", label: \"Filter\", width: \"200px\" },\n { key: \"channel\", label: \"Channel\", width: \"100px\" },\n];\n\nconst ACTIONS_COLUMN: ColumnDef = {\n key: \"actions\",\n label: \"Actions\",\n width: \"100px\",\n};\n\nfunction formatFilter(filter: Remote[\"filter\"]): string {\n const parts: string[] = [];\n\n if (filter.branch) {\n parts.push(`branch:${filter.branch}`);\n }\n\n if (filter.documentId.length > 0) {\n parts.push(`${filter.documentId.length} doc(s)`);\n }\n\n if (filter.scope.length > 0) {\n parts.push(`${filter.scope.length} scope(s)`);\n }\n\n return parts.length > 0 ? parts.join(\", \") : \"-\";\n}\n\nfunction sortRemotes(\n remotes: Remote[],\n sort: SortOptions | undefined,\n): Remote[] {\n if (!sort) return remotes;\n\n return [...remotes].sort((a, b) => {\n let aValue: string;\n let bValue: string;\n\n switch (sort.column) {\n case \"id\":\n aValue = a.id;\n bValue = b.id;\n break;\n case \"name\":\n aValue = a.name;\n bValue = b.name;\n break;\n case \"collectionId\":\n aValue = a.collectionId;\n bValue = b.collectionId;\n break;\n case \"filter\":\n aValue = formatFilter(a.filter);\n bValue = formatFilter(b.filter);\n break;\n default:\n return 0;\n }\n\n const comparison = aValue.localeCompare(bValue);\n return sort.direction === \"asc\" ? comparison : -comparison;\n });\n}\n\nexport function RemotesInspector({\n getRemotes,\n removeRemote,\n addRemoteManual,\n triggerPull,\n connectionStates,\n}: RemotesInspectorProps) {\n const [remotes, setRemotes] = useState<Remote[]>([]);\n const [loading, setLoading] = useState(true);\n const [sort, setSort] = useState<SortOptions | undefined>();\n const [selectedRemote, setSelectedRemote] = useState<Remote | undefined>();\n const [manualUrl, setManualUrl] = useState(\"\");\n const [adding, setAdding] = useState(false);\n const [addError, setAddError] = useState<string | undefined>();\n\n const hasRowActions = !!removeRemote || !!triggerPull;\n const columns = useMemo(\n () => (hasRowActions ? [...BASE_COLUMNS, ACTIONS_COLUMN] : BASE_COLUMNS),\n [hasRowActions],\n );\n\n const loadRemotes = useCallback(async () => {\n setLoading(true);\n const data = await getRemotes();\n setRemotes(data);\n setLoading(false);\n }, [getRemotes]);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n void loadRemotes();\n }, [loadRemotes]);\n\n const handleRefresh = useCallback(async () => {\n await loadRemotes();\n if (selectedRemote) {\n const updated = remotes.find((r) => r.id === selectedRemote.id);\n setSelectedRemote(updated);\n }\n }, [loadRemotes, selectedRemote, remotes]);\n\n const handleSort = (columnKey: string) => {\n if (\n columnKey === \"channel\" ||\n columnKey === \"actions\" ||\n columnKey === \"status\"\n )\n return;\n\n const newDirection: SortDirection =\n sort?.column === columnKey && sort.direction === \"asc\" ? \"desc\" : \"asc\";\n\n setSort({ column: columnKey, direction: newDirection });\n };\n\n const handleViewChannel = (remote: Remote) => {\n setSelectedRemote(remote);\n };\n\n const handleRemove = useCallback(\n async (remote: Remote) => {\n if (!removeRemote) return;\n await removeRemote(remote.name);\n await loadRemotes();\n if (selectedRemote?.id === remote.id) {\n setSelectedRemote(undefined);\n }\n },\n [removeRemote, loadRemotes, selectedRemote],\n );\n\n const handleBack = () => {\n setSelectedRemote(undefined);\n };\n\n const handleAddManual = useCallback(async () => {\n if (!addRemoteManual) return;\n const url = manualUrl.trim();\n if (!url) return;\n setAdding(true);\n setAddError(undefined);\n try {\n await addRemoteManual(url);\n setManualUrl(\"\");\n await loadRemotes();\n } catch (error) {\n setAddError(error instanceof Error ? error.message : String(error));\n } finally {\n setAdding(false);\n }\n }, [addRemoteManual, manualUrl, loadRemotes]);\n\n const handlePull = useCallback(\n (remote: Remote) => {\n triggerPull?.(remote.name);\n },\n [triggerPull],\n );\n\n if (selectedRemote) {\n return (\n <ChannelInspector\n channel={selectedRemote.channel}\n connectionState={connectionStates?.get(selectedRemote.name)}\n onBack={handleBack}\n onRefresh={() => void handleRefresh()}\n remoteName={selectedRemote.name}\n />\n );\n }\n\n const sortedRemotes = sortRemotes(remotes, sort);\n\n return (\n <div className=\"flex h-full flex-col gap-2\">\n <div className=\"flex shrink-0 items-center justify-between gap-2\">\n <h2 className=\"text-lg font-semibold text-gray-900 dark:text-slate-50\">\n Remotes Inspector\n </h2>\n <div className=\"flex items-center gap-2\">\n {addRemoteManual && (\n <div className=\"flex items-center gap-1\">\n <input\n className=\"w-[260px] rounded-sm border border-gray-300 px-2 py-1.5 text-sm text-gray-900 placeholder:text-gray-400 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:placeholder:text-slate-500\"\n disabled={adding}\n onChange={(e) => setManualUrl(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") void handleAddManual();\n }}\n placeholder=\"https://reactor/d/drive-id\"\n type=\"text\"\n value={manualUrl}\n />\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={adding || !manualUrl.trim()}\n onClick={() => void handleAddManual()}\n title=\"Register a remote drive in manual poll mode (no background polling)\"\n type=\"button\"\n >\n Add (manual)\n </button>\n </div>\n )}\n <button\n className=\"flex items-center gap-1 rounded-sm border border-gray-300 bg-gray-50 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 disabled:opacity-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n disabled={loading}\n onClick={() => void handleRefresh()}\n type=\"button\"\n >\n <Icon name=\"Reload\" size={14} />\n Refresh\n </button>\n </div>\n </div>\n {addError && (\n <div className=\"shrink-0 rounded-sm border border-red-300 bg-red-50 px-3 py-1.5 text-xs text-red-700 dark:border-red-600 dark:bg-red-900 dark:text-red-100\">\n {addError}\n </div>\n )}\n\n <div className=\"scrollbar-thin max-h-full overflow-auto rounded-lg border border-gray-300 scrollbar-thumb-gray-300 scrollbar-thumb-rounded-md scrollbar-track-transparent dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:scrollbar-thumb-slate-600\">\n <table className=\"w-full border-collapse\">\n <thead className=\"sticky top-0 bg-gray-100 dark:bg-slate-700\">\n <tr>\n {columns.map((column, index) => {\n const isActive = sort?.column === column.key;\n const sortDirection = isActive ? sort.direction : \"asc\";\n const isSortable =\n column.key !== \"channel\" &&\n column.key !== \"actions\" &&\n column.key !== \"status\";\n\n return (\n <th\n key={column.key}\n className={twMerge(\n \"group px-3 py-2 text-left text-xs font-medium text-gray-700 dark:text-slate-200\",\n index > 0 &&\n \"border-l border-gray-300 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n isSortable &&\n \"cursor-pointer hover:bg-gray-200 hover:text-gray-900 dark:hover:bg-slate-600 dark:hover:text-slate-100\",\n )}\n onClick={() => isSortable && handleSort(column.key)}\n style={{ width: column.width }}\n >\n <div className=\"flex items-center gap-1\">\n <span className=\"truncate\">{column.label}</span>\n {isSortable && (\n <SortIcon active={isActive} direction={sortDirection} />\n )}\n </div>\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {loading && sortedRemotes.length === 0 ? (\n <tr>\n <td\n className=\"px-3 py-8 text-center text-sm text-gray-500 dark:text-slate-400\"\n colSpan={columns.length}\n >\n Loading...\n </td>\n </tr>\n ) : sortedRemotes.length === 0 ? (\n <tr>\n <td\n className=\"px-3 py-8 text-center text-sm text-gray-500 dark:text-slate-400\"\n colSpan={columns.length}\n >\n No remotes configured\n </td>\n </tr>\n ) : (\n sortedRemotes.map((remote) => (\n <tr\n key={remote.id}\n className=\"odd:bg-white even:bg-gray-50 hover:bg-blue-50 dark:odd:bg-slate-800 dark:even:bg-slate-800 dark:hover:bg-blue-900\"\n >\n <td className=\"px-3 py-2 text-xs text-gray-900 dark:text-slate-50\">\n <span className=\"block truncate\" title={remote.id}>\n {truncateId(remote.id)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span className=\"block truncate\" title={remote.name}>\n {remote.name}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {connectionStates?.get(remote.name) ? (\n <ConnectionStateBadge\n failureCount={\n connectionStates.get(remote.name)!.failureCount\n }\n state={connectionStates.get(remote.name)!.state}\n />\n ) : (\n <span className=\"text-xs text-gray-400 dark:text-slate-500\">\n -\n </span>\n )}\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span\n className=\"block truncate\"\n title={remote.collectionId}\n >\n {remote.collectionId}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 text-xs text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <span\n className=\"block truncate\"\n title={formatFilter(remote.filter)}\n >\n {formatFilter(remote.filter)}\n </span>\n </td>\n <td className=\"border-l border-gray-300 px-3 py-2 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <button\n className=\"flex items-center gap-1 rounded-sm bg-blue-50 px-2 py-1 text-xs text-blue-700 hover:bg-blue-100 dark:bg-blue-900 dark:text-blue-100 dark:hover:bg-blue-800\"\n onClick={() => handleViewChannel(remote)}\n type=\"button\"\n >\n View\n <Icon name=\"CaretRight\" size={12} />\n </button>\n </td>\n {hasRowActions && (\n <td className=\"border-l border-gray-300 px-3 py-2 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <div className=\"flex items-center gap-1\">\n {triggerPull && (\n <button\n className=\"rounded-sm bg-gray-100 px-2 py-1 text-xs text-gray-700 hover:bg-gray-200 dark:bg-slate-700 dark:text-slate-200 dark:hover:bg-slate-600 dark:hover:text-slate-100\"\n onClick={() => handlePull(remote)}\n title=\"Trigger a single pull cycle for this remote\"\n type=\"button\"\n >\n Pull\n </button>\n )}\n {removeRemote && (\n <button\n className=\"rounded-sm bg-red-50 px-2 py-1 text-xs text-red-700 hover:bg-red-100 dark:bg-red-900 dark:text-red-100 dark:hover:bg-red-800\"\n onClick={() => void handleRemove(remote)}\n type=\"button\"\n >\n Remove\n </button>\n )}\n </div>\n </td>\n )}\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n\n <div className=\"shrink-0 text-sm text-gray-700 dark:text-slate-200\">\n Showing {sortedRemotes.length} remote(s)\n </div>\n </div>\n );\n}\n","import type { DivProps } from \"#design-system\";\nimport { Icon, Modal } from \"#design-system\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { DBExplorer, type DBExplorerProps } from \"../../db-explorer/index.js\";\nimport {\n IntegrityInspector,\n type IntegrityInspectorProps,\n} from \"../../integrity-inspector/index.js\";\nimport {\n ProcessorsInspector,\n type ProcessorsInspectorProps,\n} from \"../../processors-inspector/index.js\";\nimport {\n QueueInspector,\n type QueueInspectorProps,\n} from \"../../queue-inspector/index.js\";\nimport {\n RemotesInspector,\n type RemotesInspectorProps,\n} from \"../../remotes-inspector/index.js\";\nimport { TabContent } from \"../../tabs/tab-content.js\";\nimport { Tabs } from \"../../tabs/tabs.js\";\n\ntype ModalProps = ComponentPropsWithoutRef<typeof Modal>;\n\nexport type InspectorModalProps = {\n readonly open: boolean;\n readonly onOpenChange: (open: boolean) => void;\n readonly modalProps?: ModalProps;\n readonly containerProps?: DivProps;\n readonly dbExplorerProps: DBExplorerProps;\n readonly remotesInspectorProps: RemotesInspectorProps;\n readonly queueInspectorProps?: QueueInspectorProps;\n readonly processorsInspectorProps?: ProcessorsInspectorProps;\n readonly integrityInspectorProps?: IntegrityInspectorProps;\n readonly defaultTab?:\n | \"Database\"\n | \"Remotes\"\n | \"Queue\"\n | \"Processors\"\n | \"Integrity\";\n};\n\nexport function InspectorModal({\n open,\n onOpenChange,\n modalProps,\n containerProps,\n dbExplorerProps,\n remotesInspectorProps,\n queueInspectorProps,\n processorsInspectorProps,\n integrityInspectorProps,\n defaultTab = \"Database\",\n}: InspectorModalProps) {\n return (\n <Modal\n {...modalProps}\n contentProps={{\n className: \"rounded-2xl\",\n style: { height: \"90vh\", width: \"90vw\", maxWidth: \"1400px\" },\n }}\n onOpenChange={onOpenChange}\n open={open}\n >\n <div\n {...containerProps}\n className={twMerge(\n \"flex size-full flex-col\",\n containerProps?.className,\n )}\n >\n <div className=\"flex shrink-0 items-center justify-end px-3 pt-3\">\n <button\n className=\"flex size-6 cursor-pointer items-center justify-center rounded-md text-gray-500 outline-none hover:text-gray-900 dark:text-slate-400 dark:hover:text-slate-50\"\n onClick={() => onOpenChange(false)}\n type=\"button\"\n >\n <Icon name=\"XmarkLight\" size={24} />\n </button>\n </div>\n\n <div className=\"flex min-h-0 flex-1 flex-col overflow-hidden px-3 pb-3\">\n <Tabs defaultValue={defaultTab}>\n <TabContent description=\"Database explorer\" label=\"Database\">\n <div className=\"h-full\">\n <DBExplorer {...dbExplorerProps} />\n </div>\n </TabContent>\n <TabContent description=\"Remotes inspector\" label=\"Remotes\">\n <div className=\"h-full\">\n <RemotesInspector {...remotesInspectorProps} />\n </div>\n </TabContent>\n {queueInspectorProps && (\n <TabContent description=\"Queue inspector\" label=\"Queue\">\n <div className=\"h-full\">\n <QueueInspector {...queueInspectorProps} />\n </div>\n </TabContent>\n )}\n {processorsInspectorProps && (\n <TabContent description=\"Processors inspector\" label=\"Processors\">\n <div className=\"h-full\">\n <ProcessorsInspector {...processorsInspectorProps} />\n </div>\n </TabContent>\n )}\n {integrityInspectorProps && (\n <TabContent description=\"Integrity inspector\" label=\"Integrity\">\n <div className=\"h-full\">\n <IntegrityInspector {...integrityInspectorProps} />\n </div>\n </TabContent>\n )}\n </Tabs>\n </div>\n </div>\n </Modal>\n );\n}\n","import type { ComponentPropsWithoutRef } from \"react\";\nimport { useState } from \"react\";\n\nimport { Modal } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\n\nconst buttonStyles =\n \"min-h-[36px] text-sm font-semibold py-2 px-4 rounded-xl outline-none active:opacity-75 hover:scale-105 transform transition-all\";\n\nexport interface PendingPackageInstallation {\n documentType: string;\n packageName: string;\n}\n\nexport type PackageInstallModalProps = ComponentPropsWithoutRef<\n typeof Modal\n> & {\n readonly pendingInstallations: PendingPackageInstallation[];\n readonly onInstall: (packageName: string) => Promise<void>;\n readonly onDismiss: (packageName: string) => void;\n};\n\ninterface GroupedInstallation {\n packageName: string;\n documentTypes: string[];\n}\n\nfunction groupByPackage(\n installations: PendingPackageInstallation[],\n): GroupedInstallation[] {\n const groups = new Map<string, string[]>();\n for (const item of installations) {\n const existing = groups.get(item.packageName) ?? [];\n existing.push(item.documentType);\n groups.set(item.packageName, existing);\n }\n return Array.from(groups.entries()).map(([packageName, documentTypes]) => ({\n packageName,\n documentTypes,\n }));\n}\n\nexport function PackageInstallModal(props: PackageInstallModalProps) {\n const {\n pendingInstallations,\n onInstall,\n onDismiss,\n open,\n onOpenChange,\n overlayProps,\n contentProps,\n ...restProps\n } = props;\n\n const [installingPackages, setInstallingPackages] = useState<Set<string>>(\n () => new Set(),\n );\n\n const grouped = groupByPackage(pendingInstallations);\n\n async function handleInstall(packageName: string) {\n setInstallingPackages((prev) => new Set(prev).add(packageName));\n try {\n await onInstall(packageName);\n } finally {\n setInstallingPackages((prev) => {\n const next = new Set(prev);\n next.delete(packageName);\n return next;\n });\n }\n }\n\n if (grouped.length === 0) return null;\n\n return (\n <Modal\n open={open ?? grouped.length > 0}\n onOpenChange={(isOpen) => {\n if (!isOpen) {\n for (const { packageName } of grouped) {\n onDismiss(packageName);\n }\n }\n onOpenChange?.(isOpen);\n }}\n contentProps={contentProps}\n overlayProps={{\n ...overlayProps,\n className: overlayProps?.className,\n }}\n {...restProps}\n >\n <div className=\"w-[460px] rounded-xl bg-gray-50 p-6 text-gray-300 dark:bg-slate-800 dark:text-slate-600\">\n <div className=\"border-b border-gray-50 pb-2 text-2xl font-bold text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {grouped.length === 1 ? \"Package Required\" : \"Packages Required\"}\n </div>\n <div className=\"my-4 text-sm text-gray-700 dark:text-slate-200\">\n {grouped.length === 1\n ? \"A document requires a package that is not installed.\"\n : \"Documents require packages that are not installed.\"}\n </div>\n <div className=\"flex flex-col gap-3\">\n {grouped.map(({ packageName, documentTypes }) => {\n const installing = installingPackages.has(packageName);\n return (\n <div\n key={packageName}\n className=\"rounded-xl bg-gray-50 p-4 dark:bg-slate-800\"\n >\n <div className=\"mb-1 text-sm font-semibold text-gray-900 dark:text-slate-100\">\n {packageName}\n </div>\n <div className=\"mb-3 text-xs text-gray-500 dark:text-slate-400\">\n Required for document type\n {documentTypes.length > 1 ? \"s\" : \"\"}:{\" \"}\n {documentTypes.join(\", \")}\n </div>\n <div className=\"flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={() => onDismiss(packageName)}\n disabled={installing}\n className={twMerge(\n buttonStyles,\n \"border border-gray-200 bg-gray-50 text-gray-800 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n installing && \"cursor-not-allowed opacity-50\",\n )}\n >\n Dismiss\n </button>\n <button\n type=\"button\"\n onClick={() => void handleInstall(packageName)}\n disabled={installing}\n className={twMerge(\n buttonStyles,\n \"bg-gray-800 text-gray-50 dark:bg-slate-100 dark:text-slate-900\",\n installing && \"cursor-not-allowed opacity-50\",\n )}\n >\n {installing ? \"Installing...\" : \"Install\"}\n </button>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n </Modal>\n );\n}\n","import type { ComponentPropsWithoutRef, ReactNode } from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { Modal } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\n\ntype ModalProps = ComponentPropsWithoutRef<typeof Modal>;\n\nexport type ReadRequiredModalProps = {\n readonly open?: boolean;\n readonly onOpenChange?: (open: boolean) => void;\n readonly header: ReactNode;\n readonly body?: ReactNode;\n readonly closeLabel: string;\n readonly onContinue: () => void;\n readonly bodyClassName?: string;\n readonly overlayProps?: ModalProps[\"overlayProps\"];\n readonly contentProps?: ModalProps[\"contentProps\"];\n};\n\nexport function ReadRequiredModal(props: ReadRequiredModalProps) {\n const {\n open,\n onOpenChange,\n header,\n body,\n closeLabel,\n onContinue,\n bodyClassName,\n overlayProps,\n contentProps,\n } = props;\n\n const [disableClose, setDisableClose] = useState(true);\n const contentRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const checkScroll = () => {\n const element = contentRef.current;\n if (element) {\n if (element.scrollHeight > element.clientHeight) {\n setDisableClose(true);\n element.addEventListener(\"scroll\", handleScroll);\n } else {\n setDisableClose(false);\n }\n }\n };\n\n const handleScroll = () => {\n const element = contentRef.current;\n if (\n element &&\n element.scrollHeight - Math.ceil(element.scrollTop) ===\n element.clientHeight\n ) {\n setDisableClose(false);\n }\n };\n\n requestAnimationFrame(checkScroll);\n\n return () => {\n const element = contentRef.current;\n if (element) {\n element.removeEventListener(\"scroll\", handleScroll);\n }\n };\n }, []);\n\n return (\n <Modal\n open={open}\n onOpenChange={onOpenChange}\n overlayProps={overlayProps}\n contentProps={contentProps}\n >\n <div className=\"w-[500px] p-6\">\n <div className=\"border-b border-gray-100 pb-2 text-2xl font-bold text-gray-900 dark:border-slate-500 dark:text-slate-100\">\n {header}\n </div>\n <div\n ref={contentRef}\n className={twMerge(\n \"my-6 max-h-[245px] overflow-scroll rounded-md bg-gray-50 p-4 text-center dark:bg-slate-700\",\n bodyClassName,\n )}\n >\n {body}\n </div>\n <div className=\"mt-8 flex justify-between gap-3\">\n <button\n disabled={disableClose}\n onClick={onContinue}\n className={twMerge(\n \"min-h-12 flex-1 transform rounded-xl px-6 py-3 text-base font-semibold transition-all outline-none hover:scale-105 active:opacity-75\",\n \"bg-gray-800 text-gray-50 dark:bg-slate-100 dark:text-slate-900\",\n disableClose &&\n \"cursor-not-allowed bg-gray-300 hover:scale-100 dark:bg-slate-600 dark:text-slate-100\",\n )}\n >\n {closeLabel}\n </button>\n </div>\n </div>\n </Modal>\n );\n}\n","import { useState } from \"react\";\nimport { Disclosure } from \"../../../disclosure/disclosure.js\";\n\nconst PH_DEPENDENCIES = [\n /^@powerhousedao\\/.+$/,\n \"document-drive\",\n \"document-model\",\n];\n\ntype ValidatedPackageJson = {\n version: string;\n dependencies: Record<string, string>;\n};\n\nexport function verifyPackageJsonFields(\n packageJson: unknown,\n): ValidatedPackageJson | false {\n try {\n const parsed = packageJson as {\n version?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n };\n const version = parsed.version || \"Missing version field in package.json\";\n const dependencies = Object.fromEntries(\n Object.entries({\n ...parsed.dependencies,\n ...parsed.devDependencies,\n ...parsed.peerDependencies,\n }).filter(([key]) =>\n PH_DEPENDENCIES.some((regexOrName) =>\n typeof regexOrName === \"string\"\n ? regexOrName === key\n : regexOrName.test(key),\n ),\n ),\n );\n return { version, dependencies };\n } catch (error) {\n console.error(error);\n return false;\n }\n}\n\ntype Props = {\n readonly packageJson: unknown;\n readonly phCliVersion?: string;\n};\n\nexport function DependencyVersions(props: Props) {\n const [isOpen, setIsOpen] = useState(false);\n const { packageJson, phCliVersion } = props;\n\n const validatedData = verifyPackageJsonFields(packageJson);\n if (!validatedData) {\n console.error(\"Failed to validate package.json data\");\n return null;\n }\n\n return (\n <Disclosure\n isOpen={isOpen}\n onOpenChange={() => setIsOpen(!isOpen)}\n title={`App version: ${validatedData.version}`}\n toggleClassName=\"text-gray-900 text-sm dark:text-slate-50\"\n >\n <ul className=\"text-sm text-gray-700 dark:text-slate-200\">\n {Object.entries(validatedData.dependencies).map(([dep, version]) => (\n <li key={dep} className=\"my-1 flex justify-between pr-1\">\n <span>{dep.replace(\"@powerhousedao/\", \"\")}:</span>\n <span className=\"font-normal\">{version}</span>\n </li>\n ))}\n {phCliVersion && (\n <li className=\"my-1 flex justify-between pr-1\" key=\"ph-cli\">\n <span>@powerhousedao/ph-cli:</span>\n <span className=\"font-normal\">{phCliVersion}</span>\n </li>\n )}\n </ul>\n </Disclosure>\n );\n}\n","import { DependencyVersions } from \"../settings-modal/dependency-versions/dependency-versions.js\";\n\ntype Props = {\n packageJson: unknown;\n phCliVersion?: string;\n};\nexport function About(props: Props) {\n const { packageJson, phCliVersion } = props;\n return (\n <div className=\"bg-gray-50 p-3 dark:bg-slate-800\">\n <h2 className=\"font-semibold text-gray-900 dark:text-slate-100\">About</h2>\n <p className=\"text-sm font-normal text-gray-700 dark:text-slate-200\">\n Connect is the hub for your most important documents and processes\n translated into software. Easily capture data in a structured way with\n Connect.\n </p>\n <div className=\"my-4\">\n <DependencyVersions\n packageJson={packageJson}\n phCliVersion={phCliVersion}\n />\n </div>\n </div>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\nimport type {\n DocumentDriveDocument,\n SharingType,\n} from \"@powerhousedao/shared/document-drive\";\nimport { capitalCase } from \"change-case\";\nimport { useState } from \"react\";\nimport { ConnectDropdownMenu } from \"../../dropdown-menu/dropdown-menu.js\";\n\nfunction getDriveSharingType(drive: DocumentDriveDocument): SharingType {\n if (typeof drive !== \"object\") return \"LOCAL\";\n const isReadDrive = \"readContext\" in drive;\n const { sharingType: _sharingType } = !isReadDrive\n ? drive.state.local\n : { sharingType: \"PUBLIC\" };\n const __sharingType = _sharingType?.toUpperCase();\n const validTypes: string[] = [\"LOCAL\", \"CLOUD\", \"PUBLIC\"];\n return !__sharingType ||\n __sharingType === \"PRIVATE\" ||\n !validTypes.includes(__sharingType)\n ? \"LOCAL\"\n : (__sharingType as SharingType);\n}\n\ntype ModifyDrivesProps = {\n drives: DocumentDriveDocument[];\n onDeleteDrive: (drive: DocumentDriveDocument) => void;\n className?: string;\n};\n\ntype LocalStorageProps = {\n onClearStorage: () => void | Promise<void>;\n className?: string;\n};\n\ntype Props = ModifyDrivesProps & LocalStorageProps;\n\nexport function DangerZone(props: Props) {\n const { className, ...rest } = props;\n return (\n <div\n className={twMerge(\n \"h-full rounded-lg bg-gray-50 p-3 dark:bg-slate-800\",\n className,\n )}\n >\n <h2 className=\"mb-4 font-semibold text-gray-900 dark:text-slate-100\">\n Modify Drives\n </h2>\n <ModifyDrives {...rest} />\n <h2 className=\"my-4 font-semibold text-gray-900 dark:text-slate-100\">\n Local Storage\n </h2>\n <LocalStorage {...rest} />\n </div>\n );\n}\n\nfunction ModifyDrives(props: ModifyDrivesProps) {\n const { className, ...rest } = props;\n return (\n <div className={className}>\n <DriveList {...rest} />\n </div>\n );\n}\n\nfunction DriveList(props: ModifyDrivesProps) {\n const { className, ...rest } = props;\n return (\n <div className={className}>\n {props.drives.map((drive) => (\n <Drive key={drive.header.id} drive={drive} {...rest} />\n ))}\n </div>\n );\n}\n\nfunction Drive(props: ModifyDrivesProps & { drive: DocumentDriveDocument }) {\n const { drive, className, onDeleteDrive } = props;\n const [isDropdownMenuOpen, setIsDropdownMenuOpen] = useState(false);\n const localDriveIcon = <Icon name=\"Hdd\" size={16} className=\"flex-none\" />;\n\n const cloudDriveIcon = <Icon name=\"Server\" size={16} className=\"flex-none\" />;\n\n const publicDriveIcon = drive.state.global.icon ? (\n <img\n alt=\"drive icon\"\n className=\"size-4 flex-none object-contain\"\n src={drive.state.global.icon}\n />\n ) : (\n <Icon name=\"Server\" size={16} className=\"flex-none\" />\n );\n\n function getNodeIcon() {\n const sharingType = getDriveSharingType(drive);\n if (sharingType === \"PUBLIC\") {\n return publicDriveIcon;\n }\n if (sharingType === \"CLOUD\") {\n return cloudDriveIcon;\n }\n return localDriveIcon;\n }\n\n const icon = getNodeIcon();\n\n return (\n <div\n className={twMerge(\n \"mb-4 flex w-96 items-center gap-2 rounded-md border border-gray-200 bg-gray-50 px-3 py-2 text-gray-900 shadow-sm last-of-type:mb-0 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n className,\n )}\n >\n {icon}\n <div>\n <span className=\"block text-sm/4.5 font-medium\">\n {capitalCase(drive.header.name)}\n </span>\n <div className=\"flex items-baseline gap-x-2 leading-4.5\">\n <span className=\"text-sm text-gray-700 dark:text-slate-200\">\n {capitalCase(getDriveSharingType(drive))} App\n </span>\n <a\n href=\"https://www.powerhouse.inc/\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"group flex items-center gap-x-2 text-sm text-gray-500 transition-colors hover:text-purple-700 dark:text-slate-500 dark:hover:text-purple-100\"\n >\n By Powerhouse\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 12 12\"\n className=\"size-4 text-gray-400 transition-colors group-hover:text-inherit dark:text-slate-500\"\n >\n <path\n d=\"M7.99365 11.9939C9.46632 11.9939 10.6603 10.7999 10.6603 9.32722V7.32722C10.6603 6.95922 10.3617 6.66056 9.99365 6.66056C9.62565 6.66056 9.32699 6.95922 9.32699 7.32722V9.32722C9.32699 10.0639 8.73032 10.6606 7.99365 10.6606H2.66032C1.92365 10.6606 1.32699 10.0639 1.32699 9.32722V3.99389C1.32699 3.25723 1.92365 2.66056 2.66032 2.66056H4.66032C5.02832 2.66056 5.32699 2.36189 5.32699 1.99389C5.32699 1.6259 5.02832 1.32723 4.66032 1.32723H2.66032C1.18765 1.32723 -0.00634766 2.52123 -0.00634766 3.99389V9.32722C-0.00634766 10.7999 1.18765 11.9939 2.66032 11.9939H7.99365ZM5.32699 7.32722C5.49765 7.32722 5.67565 7.26989 5.80632 7.13989L10.1396 2.80656L11.9937 4.66056V-0.00610352H7.32699L9.18099 1.8479L4.84766 6.18123C4.58766 6.4419 4.58766 6.87922 4.84766 7.13989C4.97832 7.26989 5.15632 7.32722 5.32699 7.32722Z\"\n fill=\"currentColor\"\n />\n </svg>\n </a>\n </div>\n </div>\n <ConnectDropdownMenu\n items={[\n {\n id: \"delete-drive\",\n label: \"Delete\",\n icon: <Icon name=\"Trash\" />,\n className: \"text-red-900 dark:text-red-400\",\n },\n ]}\n onItemClick={(id) => {\n if (id === \"delete-drive\") {\n onDeleteDrive(drive);\n }\n }}\n onOpenChange={setIsDropdownMenuOpen}\n open={isDropdownMenuOpen}\n >\n <button\n className=\"group ml-auto flex-none\"\n onClick={(e) => {\n e.stopPropagation();\n setIsDropdownMenuOpen(true);\n }}\n >\n <Icon\n className=\"text-gray-700 group-hover:text-gray-900 dark:text-slate-200 dark:group-hover:text-slate-50\"\n name=\"VerticalDots\"\n size={16}\n />\n </button>\n </ConnectDropdownMenu>\n </div>\n );\n}\n\nfunction LocalStorage(props: LocalStorageProps) {\n const { onClearStorage } = props;\n return (\n <div>\n <button\n className=\"flex items-center gap-x-2 rounded-md border border-gray-300 bg-transparent px-3 py-1 text-sm font-medium text-red-900 transition-colors hover:bg-gray-100 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-700\"\n onClick={() => void onClearStorage()}\n >\n Clear Storage <Icon name=\"Trash\" size={16} />\n </button>\n </div>\n );\n}\n","import type { SelectOption } from \"#design-system/ui\";\nimport { SelectFieldRaw } from \"#design-system/ui\";\nimport { twMerge } from \"tailwind-merge\";\n\ntype Props = {\n documentModelEditor: string;\n setDocumentModelEditor: (value: string) => void;\n documentModelEditorOptions: SelectOption[];\n className?: string;\n};\n\nexport function DefaultEditor(props: Props) {\n const { className, ...rest } = props;\n return (\n <div\n className={twMerge(\n \"rounded-lg bg-gray-50 p-3 dark:bg-slate-800\",\n className,\n )}\n >\n <DefaultEditorSelect {...rest} />\n </div>\n );\n}\n\nexport function DefaultEditorSelect(props: Props) {\n const {\n documentModelEditor,\n setDocumentModelEditor,\n documentModelEditorOptions,\n className,\n } = props;\n\n return (\n <div>\n <h3 className=\"mb-4 font-semibold text-gray-900 dark:text-slate-50\">\n Default Editor Selection\n </h3>\n <SelectFieldRaw\n className={twMerge(\"max-w-fit min-w-36\", className)}\n name=\"default-editor\"\n required\n value={documentModelEditor}\n options={documentModelEditorOptions}\n multiple={false}\n onChange={(value) => setDocumentModelEditor(value as string)}\n />\n </div>\n );\n}\n","/**\n * Parse a package specifier into a bare name and an optional tag/version.\n *\n * - Scoped names split on the LAST `@` (since the name itself starts with\n * `@scope/`): `@scope/pkg@dev` → `{ name: \"@scope/pkg\", tag: \"dev\" }`.\n * - Unscoped names split on the first `@`: `pkg@1.2.3` →\n * `{ name: \"pkg\", tag: \"1.2.3\" }`.\n * - A bare name (no separator) returns `{ name, tag: undefined }`.\n * - Trailing/leading whitespace is trimmed; an empty tag (e.g. \"pkg@\")\n * is treated as missing.\n */\nexport function parsePackageSpec(spec: string): {\n name: string;\n tag: string | undefined;\n} {\n const trimmed = spec.trim();\n if (trimmed.length === 0) return { name: \"\", tag: undefined };\n\n const splitAt = trimmed.startsWith(\"@\")\n ? trimmed.lastIndexOf(\"@\")\n : trimmed.indexOf(\"@\");\n\n if (splitAt > 0) {\n const name = trimmed.slice(0, splitAt);\n const tag = trimmed.slice(splitAt + 1);\n return { name, tag: tag.length > 0 ? tag : undefined };\n }\n\n return { name: trimmed, tag: undefined };\n}\n\n/**\n * Compose a spec string from a name and optional tag/version. Used by\n * callers that want to re-serialize what `parsePackageSpec` parsed.\n */\nexport function buildPackageSpec(name: string, tag?: string): string {\n return tag ? `${name}@${tag}` : name;\n}\n","import { Icon } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\nimport {\n Input,\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"#design-system/ui\";\nimport { useMemo, useState } from \"react\";\n\nexport type VersionSelection =\n | { kind: \"tag\"; value: string }\n | { kind: \"version\"; value: string };\n\nexport interface VersionPickerProps {\n distTags?: Record<string, string>;\n versions?: string[];\n selected: VersionSelection;\n onChange: (next: VersionSelection) => void;\n disabled?: boolean;\n className?: string;\n}\n\nexport function resolveDefaultVersionSelection(options: {\n distTags?: Record<string, string>;\n versions?: string[];\n version?: string;\n preferredTag?: string;\n}): VersionSelection {\n const { distTags, versions, version, preferredTag } = options;\n\n if (preferredTag && distTags && preferredTag in distTags) {\n return { kind: \"tag\", value: preferredTag };\n }\n if (distTags?.latest) {\n return { kind: \"tag\", value: \"latest\" };\n }\n const firstTag = distTags ? Object.keys(distTags)[0] : undefined;\n if (firstTag) {\n return { kind: \"tag\", value: firstTag };\n }\n if (versions && versions.length > 0) {\n return { kind: \"version\", value: versions[versions.length - 1] };\n }\n return { kind: \"tag\", value: version ?? \"latest\" };\n}\n\nexport const VersionPicker: React.FC<VersionPickerProps> = (props) => {\n const { distTags, versions, selected, onChange, disabled, className } = props;\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState(\"\");\n\n const tagEntries = useMemo(\n () => (distTags ? Object.entries(distTags) : []),\n [distTags],\n );\n\n const filteredTags = useMemo(() => {\n const needle = query.trim().toLowerCase();\n if (!needle) return tagEntries;\n return tagEntries.filter(\n ([tag, ver]) =>\n tag.toLowerCase().includes(needle) ||\n ver.toLowerCase().includes(needle),\n );\n }, [tagEntries, query]);\n\n const filteredVersions = useMemo(() => {\n const all = versions ?? [];\n const needle = query.trim().toLowerCase();\n if (!needle) return all.slice().reverse();\n return all.filter((v) => v.toLowerCase().includes(needle)).reverse();\n }, [versions, query]);\n\n const hasAnyPickable = tagEntries.length > 0 || (versions?.length ?? 0) > 0;\n\n const triggerLabel = selected.value;\n\n return (\n <Popover\n open={open && !disabled}\n onOpenChange={(next) => {\n setOpen(next);\n if (!next) setQuery(\"\");\n }}\n >\n <PopoverTrigger\n disabled={disabled || !hasAnyPickable}\n className={twMerge(\n \"flex items-center justify-between gap-2 rounded-md border border-gray-300 bg-gray-50 px-2.5 py-1 text-xs font-medium text-gray-900 transition-colors dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n \"hover:bg-gray-50 focus:ring-2 focus:ring-gray-900/20 focus:outline-none dark:hover:bg-slate-800\",\n \"disabled:cursor-not-allowed disabled:opacity-60\",\n className,\n )}\n data-version-picker-trigger\n >\n <span className=\"truncate\">{triggerLabel}</span>\n <Icon\n name=\"ChevronDown\"\n size={12}\n className=\"shrink-0 text-gray-500 dark:text-slate-400\"\n />\n </PopoverTrigger>\n <PopoverContent\n data-version-picker\n align=\"start\"\n sideOffset={4}\n className=\"w-56 p-0\"\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <div className=\"border-b border-gray-200 p-2 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <div className=\"relative\">\n <Icon\n name=\"Search\"\n size={14}\n className=\"absolute top-1/2 left-2 -translate-y-1/2 text-gray-400 dark:text-slate-500\"\n />\n <Input\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder=\"Search versions...\"\n className=\"h-8 pl-7 text-xs\"\n />\n </div>\n </div>\n <div className=\"max-h-60 overflow-y-auto py-1\">\n {filteredTags.length === 0 && filteredVersions.length === 0 && (\n <p className=\"px-3 py-4 text-center text-xs text-gray-500 dark:text-slate-400\">\n No matches.\n </p>\n )}\n {filteredTags.length > 0 && (\n <div className=\"pb-1\">\n <p className=\"px-3 py-1 text-xs font-semibold tracking-wide text-gray-500 uppercase dark:text-slate-400\">\n Tags\n </p>\n {filteredTags.map(([tag, ver]) => {\n const isSelected =\n selected.kind === \"tag\" && selected.value === tag;\n return (\n <button\n key={`tag:${tag}`}\n type=\"button\"\n onClick={() => {\n onChange({ kind: \"tag\", value: tag });\n setOpen(false);\n setQuery(\"\");\n }}\n className={twMerge(\n \"flex w-full items-center justify-between gap-2 px-3 py-1.5 text-left text-xs transition-colors\",\n \"hover:bg-gray-100 dark:hover:bg-slate-700\",\n isSelected &&\n \"bg-gray-100 font-semibold dark:bg-slate-700\",\n )}\n >\n <span className=\"truncate text-gray-900 dark:text-slate-50\">\n {tag}\n </span>\n <span className=\"truncate text-gray-500 dark:text-slate-400\">\n {ver}\n </span>\n </button>\n );\n })}\n </div>\n )}\n {filteredVersions.length > 0 && (\n <div>\n <p className=\"px-3 py-1 text-xs font-semibold tracking-wide text-gray-500 uppercase dark:text-slate-400\">\n Versions\n </p>\n {filteredVersions.map((ver) => {\n const isSelected =\n selected.kind === \"version\" && selected.value === ver;\n return (\n <button\n key={`ver:${ver}`}\n type=\"button\"\n onClick={() => {\n onChange({ kind: \"version\", value: ver });\n setOpen(false);\n setQuery(\"\");\n }}\n className={twMerge(\n \"flex w-full items-center px-3 py-1.5 text-left text-xs transition-colors\",\n \"hover:bg-gray-100 dark:hover:bg-slate-700\",\n isSelected &&\n \"bg-gray-100 font-semibold dark:bg-slate-700\",\n )}\n >\n <span className=\"truncate text-gray-900 dark:text-slate-50\">\n {ver}\n </span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n );\n};\n","import { PackageAnimation } from \"#design-system\";\nimport type {\n SearchAutocompleteOption,\n SearchAutocompleteRowContext,\n} from \"#design-system/ui\";\nimport { SearchAutocomplete } from \"#design-system/ui\";\nimport type { RegistryPackageList } from \"@powerhousedao/shared/registry\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { buildPackageSpec, parsePackageSpec } from \"./parse-package-spec.js\";\nimport type { VersionSelection } from \"./version-picker.js\";\nimport {\n VersionPicker,\n resolveDefaultVersionSelection,\n} from \"./version-picker.js\";\n\nexport type PackageManagerInputProps = {\n registryPackageList: RegistryPackageList;\n onInstall: (packageSpec: string) => Promise<void>;\n disabled?: boolean;\n className?: string;\n};\n\nconst NPM_NAME_RE =\n /^@[a-z0-9][a-z0-9._-]*\\/[a-z0-9][a-z0-9._-]*$|^[a-z0-9][a-z0-9._-]*$/i;\n\nfunction isPlausiblePackageName(name: string): boolean {\n return name.length >= 2 && NPM_NAME_RE.test(name);\n}\n\ntype PackageResultCardProps = {\n option: SearchAutocompleteOption;\n ctx: SearchAutocompleteRowContext;\n typedTag: string | undefined;\n};\n\nfunction PackageResultCard(props: PackageResultCardProps) {\n const { option, ctx, typedTag } = props;\n const { selectingValue, selectLabel, selectingContent, handleSelect } = ctx;\n\n const baseName = option.label.split(\" @ \")[0] ?? option.value;\n const hasVersionMetadata =\n (option.distTags && Object.keys(option.distTags).length > 0) ||\n (option.versions?.length ?? 0) > 0;\n\n const [selected, setSelected] = useState<VersionSelection>(() =>\n resolveDefaultVersionSelection({\n distTags: option.distTags,\n versions: option.versions,\n version: option.version,\n preferredTag: typedTag,\n }),\n );\n\n // Re-sync when the typed tag changes (e.g. user edits the search query).\n // We track `typedTag` so typing `pkg@dev` pre-selects the `dev` chip.\n useEffect(() => {\n if (!typedTag) return;\n if (option.distTags && typedTag in option.distTags) {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setSelected({ kind: \"tag\", value: typedTag });\n } else if (option.versions?.includes(typedTag)) {\n setSelected({ kind: \"version\", value: typedTag });\n }\n }, [typedTag, option.distTags, option.versions]);\n\n // npm-fallback and other metadata-less rows: trust the option's prebuilt\n // spec (which already encodes any typed tag) and skip the picker entirely.\n const installSpec = hasVersionMetadata\n ? buildPackageSpec(baseName, selected.value)\n : option.value;\n const isSelecting = selectingValue === installSpec;\n const isDisabled = option.disabled === true;\n\n return (\n <div className=\"flex items-start justify-between gap-3 rounded-md p-2 hover:bg-gray-50 dark:hover:bg-slate-800\">\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium text-gray-900 dark:text-slate-50\">\n {baseName}\n </p>\n {option.description && (\n <p className=\"truncate text-xs text-gray-700 dark:text-slate-200\">\n {option.description}\n </p>\n )}\n {option.meta && (\n <p className=\"truncate text-xs text-gray-700 dark:text-slate-200\">\n {option.meta}\n </p>\n )}\n {hasVersionMetadata && (\n <div className=\"mt-2\">\n <VersionPicker\n distTags={option.distTags}\n versions={option.versions}\n selected={selected}\n onChange={setSelected}\n disabled={isDisabled}\n />\n </div>\n )}\n </div>\n <div className=\"shrink-0 self-center\">\n {isSelecting && selectingContent ? (\n <div className=\"flex items-center justify-center\">\n {selectingContent}\n </div>\n ) : isDisabled ? (\n <span className=\"rounded-md bg-gray-100 px-3 py-1 text-xs font-medium text-gray-500 dark:bg-slate-700 dark:text-slate-400\">\n {option.disabledLabel ?? \"Unavailable\"}\n </span>\n ) : (\n <button\n onClick={() => handleSelect(installSpec)}\n disabled={isSelecting}\n className=\"rounded-md bg-gray-900 px-3 py-1 text-xs font-medium text-white transition-colors hover:bg-gray-800 disabled:opacity-50 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-100\"\n >\n {isSelecting ? \"...\" : selectLabel}\n </button>\n )}\n </div>\n </div>\n );\n}\n\nexport const PackageManagerInput: React.FC<PackageManagerInputProps> = (\n props,\n) => {\n const { registryPackageList, onInstall, disabled, className } = props;\n const [typedTag, setTypedTag] = useState<string | undefined>(undefined);\n\n const fetchOptions = async (\n query: string,\n ): Promise<SearchAutocompleteOption[]> => {\n const { name: namePart, tag } = parsePackageSpec(query);\n setTypedTag(tag);\n const needle = namePart.toLowerCase();\n\n const localOptions: SearchAutocompleteOption[] = registryPackageList\n .filter(\n (pkg) =>\n pkg.name.toLowerCase().includes(needle) ||\n pkg.manifest?.description?.toLowerCase().includes(needle),\n )\n .map((pkg) => {\n const isInstalled =\n pkg.status === \"local-install\" || pkg.status === \"registry-install\";\n return {\n // `value` carries the default install spec; the row overrides it\n // with the version picker's current selection at click time.\n value: pkg.name,\n label: pkg.name,\n version: pkg.version,\n description: pkg.manifest?.description,\n meta: pkg.manifest?.publisher?.name,\n disabled: isInstalled,\n disabledLabel: isInstalled ? \"Installed\" : undefined,\n distTags: pkg.distTags,\n versions: pkg.versions,\n };\n });\n\n if (!isPlausiblePackageName(namePart) || localOptions.length > 0) {\n return Promise.resolve(localOptions);\n }\n\n const fallbackSpec = buildPackageSpec(namePart, tag);\n const fallbackLabel = tag ? `${namePart} @ ${tag}` : namePart;\n const fallbackOption: SearchAutocompleteOption = {\n value: fallbackSpec,\n label: fallbackLabel,\n version: tag,\n description:\n \"Not published to this registry. Install via the npmjs.org uplink.\",\n meta: \"npm fallback\",\n };\n return Promise.resolve([fallbackOption]);\n };\n\n const handleSelect = useCallback(\n (value: string) => {\n return onInstall(value);\n },\n [onInstall],\n );\n\n const renderRow = useCallback(\n (option: SearchAutocompleteOption, ctx: SearchAutocompleteRowContext) => (\n <PackageResultCard option={option} ctx={ctx} typedTag={typedTag} />\n ),\n [typedTag],\n );\n\n return (\n <div className={className}>\n <h3 className=\"mb-4 font-semibold text-gray-900 dark:text-slate-50\">\n Install Package\n </h3>\n <SearchAutocomplete\n fetchOptions={fetchOptions}\n onSelect={handleSelect}\n selectLabel=\"Install\"\n selectingContent={\n <PackageAnimation animate loop color=\"#6b7280\" size={48} />\n }\n placeholder=\"Search packages (e.g. my-pkg, my-pkg@dev, my-pkg@1.2.3)...\"\n disabled={disabled}\n renderRow={renderRow}\n keepOpenSelector=\"[data-version-picker],[data-version-picker-trigger]\"\n />\n </div>\n );\n};\n","import { Icon } from \"#design-system\";\nimport type {\n RegistryPackage,\n RegistryPackageList,\n} from \"@powerhousedao/shared/registry\";\nimport type { ReactNode } from \"react\";\nimport { useCallback, useEffect, useLayoutEffect, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ConnectDropdownMenu } from \"../../../dropdown-menu/dropdown-menu.js\";\nimport { buildPackageSpec } from \"./parse-package-spec.js\";\nimport type { VersionSelection } from \"./version-picker.js\";\nimport {\n resolveDefaultVersionSelection,\n VersionPicker,\n} from \"./version-picker.js\";\n\nconst PackageDetail: React.FC<{ label: string; value: ReactNode }> = ({\n label,\n value,\n}) => {\n return (\n <div className=\"flex items-start gap-2 text-sm\">\n <p className=\"text-gray-700 dark:text-slate-200\">{label}:</p>\n <p className=\"text-gray-700 dark:text-slate-200\">{value}</p>\n </div>\n );\n};\n\nexport const PackageManagerListItem = (props: {\n registryPackage: RegistryPackage;\n onInstall: (packageSpec: string) => Promise<void>;\n onUninstall: (packageName: string) => void;\n className?: string;\n}) => {\n const { registryPackage, onInstall, onUninstall, className } = props;\n const [isDropdownMenuOpen, setIsDropdownMenuOpen] = useState(false);\n\n const canPickVersion =\n registryPackage.status === \"available\" ||\n registryPackage.status === \"dismissed\";\n const hasVersionMetadata =\n (registryPackage.distTags &&\n Object.keys(registryPackage.distTags).length > 0) ||\n (registryPackage.versions?.length ?? 0) > 0;\n\n const [selected, setSelected] = useState<VersionSelection>(() =>\n resolveDefaultVersionSelection({\n distTags: registryPackage.distTags,\n versions: registryPackage.versions,\n version: registryPackage.version,\n }),\n );\n\n const installDropdownItem = {\n id: \"install\",\n label: \"Install\",\n icon: <Icon name=\"DownloadFile\" />,\n className: \"text-gray-900 dark:text-slate-100\",\n } as const;\n\n const uninstallDropdownItem = {\n id: \"uninstall\",\n label: \"Uninstall\",\n icon: <Icon name=\"Trash\" />,\n className: \"text-red-900 dark:text-red-400\",\n } as const;\n\n function getDropdownItems() {\n return [\n canPickVersion ? installDropdownItem : undefined,\n registryPackage.status === \"registry-install\"\n ? uninstallDropdownItem\n : undefined,\n ].filter((item) => item !== undefined);\n }\n\n const dropdownItems = getDropdownItems();\n return (\n <li\n className={twMerge(\n \"relative flex flex-col items-start rounded-md border border-gray-200 bg-gray-50 p-3 text-sm/5 shadow-sm dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n className,\n )}\n >\n <div className=\"flex flex-wrap items-center gap-2 pr-8\">\n <h3 className=\"font-semibold text-gray-900 dark:text-slate-50\">\n {registryPackage.name}\n </h3>\n {canPickVersion && hasVersionMetadata ? (\n <VersionPicker\n distTags={registryPackage.distTags}\n versions={registryPackage.versions}\n selected={selected}\n onChange={setSelected}\n />\n ) : registryPackage.version ? (\n <span className=\"text-xs font-normal text-gray-500 dark:text-slate-400\">\n v{registryPackage.version}\n </span>\n ) : null}\n </div>\n {registryPackage.manifest !== null &&\n (() => {\n const { description, category, publisher } = registryPackage.manifest;\n const hasAnyField =\n description != null ||\n category != null ||\n publisher?.name != null ||\n publisher?.url != null;\n if (!hasAnyField) return null;\n return (\n <>\n {description != null && (\n <PackageDetail label=\"Description\" value={description} />\n )}\n {category != null && (\n <PackageDetail label=\"Category\" value={category} />\n )}\n {publisher?.name != null && (\n <PackageDetail label=\"Publisher\" value={publisher.name} />\n )}\n {publisher?.url != null && (\n <PackageDetail\n label=\"Publisher URL\"\n value={\n <a className=\"underline\" href={publisher.url}>\n {publisher.url}\n </a>\n }\n />\n )}\n </>\n );\n })()}\n <ConnectDropdownMenu\n items={dropdownItems}\n onItemClick={(id) => {\n if (id === \"install\") {\n const spec =\n canPickVersion && hasVersionMetadata\n ? buildPackageSpec(registryPackage.name, selected.value)\n : registryPackage.name;\n onInstall(spec).catch(console.error);\n return;\n }\n onUninstall(registryPackage.name);\n }}\n onOpenChange={setIsDropdownMenuOpen}\n open={isDropdownMenuOpen}\n >\n <button\n className=\"group absolute top-3 right-3\"\n onClick={(e) => {\n e.stopPropagation();\n setIsDropdownMenuOpen(true);\n }}\n >\n <Icon\n className=\"text-gray-700 group-hover:text-gray-900 dark:text-slate-200 dark:group-hover:text-slate-50\"\n name=\"VerticalDots\"\n />\n </button>\n </ConnectDropdownMenu>\n </li>\n );\n};\n\nexport const PackageManagerList = (props: {\n registryPackageList: RegistryPackageList;\n onInstall: (packageSpec: string) => Promise<void>;\n onUninstall: (packageName: string) => void;\n className?: string;\n}) => {\n const { className, registryPackageList, onInstall, onUninstall } = props;\n const [maxHeight, setMaxHeight] = useState<number | undefined>();\n\n const locallyInstalledPackages = registryPackageList.filter(\n (p) => p.status === \"local-install\",\n );\n const registryInstalledPackages = registryPackageList.filter(\n (p) => p.status === \"registry-install\",\n );\n const availablePackages = registryPackageList.filter(\n (p) => p.status === \"available\",\n );\n const dismissedPackages = registryPackageList.filter(\n (p) => p.status === \"dismissed\",\n );\n\n useLayoutEffect(() => {\n const calculateMaxHeight = () => {\n const viewportHeight = window.innerHeight;\n const availableHeight = viewportHeight - 516;\n setMaxHeight(Math.max(200, availableHeight));\n };\n\n calculateMaxHeight();\n\n window.addEventListener(\"resize\", calculateMaxHeight);\n return () => window.removeEventListener(\"resize\", calculateMaxHeight);\n }, []);\n\n const hasLocallyInstalled = locallyInstalledPackages.length > 0;\n const hasRegistryInstalled = registryInstalledPackages.length > 0;\n const hasAnyInstalled = hasLocallyInstalled || hasRegistryInstalled;\n const hasAvailable = availablePackages.length > 0;\n const hasDismissed = dismissedPackages.length > 0;\n const installedCount =\n locallyInstalledPackages.length + registryInstalledPackages.length;\n\n return (\n <div\n className={twMerge(\n \"flex flex-col items-stretch overflow-hidden\",\n className,\n )}\n style={{ maxHeight }}\n >\n <div className=\"flex-1 overflow-y-auto pr-2\">\n <PackageSection\n sectionId=\"installed\"\n title=\"Installed Packages\"\n count={installedCount}\n isEmpty={!hasAnyInstalled}\n emptyText=\"No packages installed.\"\n >\n {hasLocallyInstalled && (\n <PackageSubSection\n title=\"Locally installed\"\n count={locallyInstalledPackages.length}\n >\n <PackageList\n packages={locallyInstalledPackages}\n onInstall={onInstall}\n onUninstall={onUninstall}\n />\n </PackageSubSection>\n )}\n {hasRegistryInstalled && (\n <PackageSubSection\n title=\"Installed from registry\"\n count={registryInstalledPackages.length}\n >\n <PackageList\n packages={registryInstalledPackages}\n onInstall={onInstall}\n onUninstall={onUninstall}\n />\n </PackageSubSection>\n )}\n </PackageSection>\n\n <PackageSection\n sectionId=\"available\"\n title=\"Available Packages\"\n count={availablePackages.length}\n isEmpty={!hasAvailable}\n emptyText=\"No packages available to install.\"\n >\n <PackageList\n packages={availablePackages}\n onInstall={onInstall}\n onUninstall={onUninstall}\n />\n </PackageSection>\n\n {hasDismissed && (\n <PackageSection\n sectionId=\"dismissed\"\n title=\"Dismissed Packages\"\n count={dismissedPackages.length}\n >\n <PackageList\n packages={dismissedPackages}\n onInstall={onInstall}\n onUninstall={onUninstall}\n />\n </PackageSection>\n )}\n </div>\n </div>\n );\n};\n\nconst STORAGE_KEY = \"ph:package-manager:collapsed-sections\";\n\nfunction loadCollapsedSections(): Record<string, boolean> {\n if (typeof window === \"undefined\") return {};\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n return raw ? (JSON.parse(raw) as Record<string, boolean>) : {};\n } catch {\n return {};\n }\n}\n\nfunction useCollapsedSection(sectionId: string): [boolean, () => void] {\n const [collapsed, setCollapsed] = useState<boolean>(\n () => loadCollapsedSections()[sectionId] ?? true,\n );\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n try {\n const current = loadCollapsedSections();\n current[sectionId] = collapsed;\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(current));\n } catch {\n // ignore persistence errors\n }\n }, [sectionId, collapsed]);\n\n const toggle = useCallback(() => setCollapsed((prev) => !prev), []);\n return [collapsed, toggle];\n}\n\nconst PackageSection: React.FC<{\n sectionId: string;\n title: string;\n count: number;\n isEmpty?: boolean;\n emptyText?: string;\n children?: ReactNode;\n}> = ({ sectionId, title, count, isEmpty, emptyText, children }) => {\n const [collapsed, toggle] = useCollapsedSection(sectionId);\n const contentId = `package-section-${sectionId}`;\n\n return (\n <section className=\"mb-6\">\n <h3 className=\"sticky top-0 z-10 mb-3 border-b border-gray-200 bg-gray-50 text-gray-900 dark:border-slate-600 dark:bg-slate-800 dark:text-slate-100\">\n <button\n type=\"button\"\n onClick={toggle}\n aria-expanded={!collapsed}\n aria-controls={contentId}\n className=\"flex w-full items-center gap-2 pb-2 text-left text-base font-semibold text-gray-900 hover:text-gray-700 dark:text-slate-100 dark:hover:text-slate-200\"\n >\n <Icon\n name=\"ChevronDown\"\n size={16}\n className={twMerge(\n \"shrink-0 text-gray-700 transition-transform dark:text-slate-200\",\n collapsed && \"-rotate-90\",\n )}\n />\n <span>{title}</span>\n <span className=\"text-xs font-medium text-gray-700 dark:text-slate-200\">\n {count}\n </span>\n </button>\n </h3>\n {!collapsed && (\n <div id={contentId}>\n {isEmpty ? (\n <p className=\"text-sm text-gray-700 dark:text-slate-200\">\n {emptyText}\n </p>\n ) : (\n <div className=\"flex flex-col gap-4\">{children}</div>\n )}\n </div>\n )}\n </section>\n );\n};\n\nconst PackageSubSection: React.FC<{\n title: string;\n count: number;\n children: ReactNode;\n}> = ({ title, count, children }) => {\n return (\n <div>\n <h4 className=\"mb-2 flex items-baseline gap-2 text-xs font-semibold tracking-wide text-gray-700 uppercase dark:text-slate-200\">\n <span>{title}</span>\n <span className=\"font-medium tracking-normal text-gray-500 normal-case dark:text-slate-400\">\n ({count})\n </span>\n </h4>\n {children}\n </div>\n );\n};\n\nconst PackageList: React.FC<{\n packages: RegistryPackageList;\n onInstall: (packageSpec: string) => Promise<void>;\n onUninstall: (packageName: string) => void;\n}> = ({ packages, onInstall, onUninstall }) => {\n return (\n <ul className=\"flex flex-col items-stretch gap-4 pr-2\">\n {packages.map((pkg) => (\n <PackageManagerListItem\n key={pkg.name}\n registryPackage={pkg}\n onInstall={onInstall}\n onUninstall={onUninstall}\n />\n ))}\n </ul>\n );\n};\n","import type { RegistryPackageList } from \"@powerhousedao/shared/registry\";\nimport { twMerge } from \"tailwind-merge\";\nimport { PackageManagerInput } from \"./package-manager-input.js\";\nimport { PackageManagerList } from \"./package-manager-list.js\";\n\ntype Props = {\n registryPackageList: RegistryPackageList;\n mutable: boolean;\n /**\n * Install handler. The argument is the full spec the user chose — either\n * the bare package name, or `name@tag` / `name@version` when they typed\n * a suffix in the search input or picked one via the filter UI.\n */\n onInstall: (packageSpec: string) => Promise<void>;\n onUninstall: (packageName: string) => void;\n disabled?: boolean;\n className?: string;\n};\n\nexport const PackageManager: React.FC<Props> = (props) => {\n const {\n registryPackageList,\n onInstall,\n onUninstall,\n mutable,\n disabled,\n className,\n } = props;\n\n return (\n <div\n className={twMerge(\n \"flex h-full flex-1 flex-col rounded-lg bg-gray-50 p-3 text-gray-900 dark:bg-slate-800 dark:text-slate-100\",\n className,\n )}\n >\n {mutable && (\n <PackageManagerInput\n className=\"mb-4\"\n registryPackageList={registryPackageList}\n onInstall={onInstall}\n disabled={disabled}\n />\n )}\n <PackageManagerList\n registryPackageList={registryPackageList}\n onUninstall={onUninstall}\n onInstall={onInstall}\n />\n </div>\n );\n};\n","import type { ComponentProps } from \"react\";\n\nimport { Icon, Modal } from \"#design-system\";\nimport { useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport type SettingsTab = {\n id: string;\n icon?: React.ReactNode;\n label: React.ReactNode;\n content: React.ReactNode | React.ComponentType<any>;\n};\n\ntype Props = {\n readonly title: React.ReactNode;\n readonly tabs: SettingsTab[];\n defaultTab?: string;\n navFooter?: React.ReactNode;\n} & ComponentProps<typeof Modal>;\n\nexport function SettingsModal(props: Props) {\n const {\n title,\n overlayProps,\n contentProps,\n onOpenChange,\n tabs,\n defaultTab,\n navFooter,\n ...restProps\n } = props;\n\n const [selectedTab, setSelectedTab] = useState(defaultTab ?? tabs.at(0)?.id);\n\n const tabsContent = tabs.map((tab) => (\n <button type=\"button\" onClick={() => setSelectedTab(tab.id)} key={tab.id}>\n <div\n className={twMerge(\n \"flex h-9 w-48 cursor-pointer items-center gap-x-2 rounded-md pl-3 text-gray-700 hover:bg-gray-50 dark:text-slate-200 dark:hover:bg-slate-800\",\n selectedTab === tab.id\n ? \"bg-gray-50 dark:bg-slate-800\"\n : \"bg-transparent\",\n )}\n >\n {tab.icon}\n <span>{tab.label}</span>\n </div>\n </button>\n ));\n\n const selectedTabContent = tabs.find(\n (tab) => tab.id === selectedTab,\n )?.content;\n\n const SelectedTabComponent = selectedTabContent;\n\n return (\n <Modal\n contentProps={{\n ...contentProps,\n className: twMerge(\n \"min-h-full w-full max-w-4xl rounded-xl\",\n contentProps?.className,\n ),\n style: {\n ...contentProps?.style,\n boxShadow:\n \"0px 0px 16px 4px rgba(0, 0, 0, 0.04), 0px 33px 32px -16px rgba(0, 0, 0, 0.10)\",\n },\n }}\n onOpenChange={onOpenChange}\n overlayProps={{\n ...overlayProps,\n className: twMerge(\"py-28\", overlayProps?.className),\n }}\n {...restProps}\n >\n <div className=\"flex justify-between rounded-t-xl border-b border-gray-50 p-4 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <h1 className=\"text-center text-xl font-semibold text-gray-900 dark:text-slate-50\">\n {title}\n </h1>\n <button\n type=\"button\"\n className=\"flex size-6 items-center justify-center rounded-md text-gray-900 outline-none dark:text-slate-100\"\n onClick={() => onOpenChange?.(false)}\n >\n <Icon name=\"XmarkLight\" size={24} />\n </button>\n </div>\n <div className=\"flex flex-1\">\n <div className=\"flex flex-col p-3 pt-6\">\n <div className=\"flex flex-col gap-y-1\">{tabsContent}</div>\n {navFooter && (\n <div className=\"mt-auto border-t border-gray-100 pt-2 dark:border-slate-700\">\n {navFooter}\n </div>\n )}\n </div>\n <div className=\"m-6 flex h-full flex-1 flex-col overflow-hidden rounded-lg border border-gray-50 bg-gray-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {typeof SelectedTabComponent === \"function\" ? (\n <SelectedTabComponent />\n ) : (\n SelectedTabComponent\n )}\n </div>\n </div>\n </Modal>\n );\n}\n","import type { ComponentPropsWithoutRef } from \"react\";\n\nimport { Modal } from \"#design-system\";\nimport { ModalButton } from \"./modal-button.js\";\n\nexport type ConnectUpgradeDriveModalProps = ComponentPropsWithoutRef<\n typeof Modal\n> & {\n readonly header: React.ReactNode;\n readonly body: React.ReactNode;\n readonly onContinue: () => void;\n readonly cancelLabel: string;\n readonly continueLabel: string;\n};\n\nexport function ConnectUpgradeDriveModal(props: ConnectUpgradeDriveModalProps) {\n const {\n body,\n header,\n onOpenChange,\n onContinue,\n cancelLabel,\n continueLabel,\n overlayProps,\n contentProps,\n ...restProps\n } = props;\n\n return (\n <Modal\n contentProps={contentProps}\n onOpenChange={onOpenChange}\n overlayProps={{\n ...overlayProps,\n className: overlayProps?.className,\n }}\n {...restProps}\n >\n <div className=\"w-100 bg-gray-50 p-6 text-gray-300 dark:bg-slate-800 dark:text-slate-200\">\n <div className=\"pb-2 text-2xl font-bold text-gray-900 dark:text-slate-100\">\n {header}\n </div>\n <div className=\"my-6 rounded-md bg-gray-50 p-4 text-center text-gray-900 dark:bg-slate-800 dark:text-slate-100\">\n {body}\n </div>\n <div className=\"mt-8 flex justify-between gap-3\">\n <ModalButton variant=\"cancel\" onClick={() => onOpenChange?.(false)}>\n {cancelLabel}\n </ModalButton>\n <ModalButton variant=\"confirm\" onClick={onContinue}>\n {continueLabel}\n </ModalButton>\n </div>\n </div>\n </Modal>\n );\n}\n","import { Icon } from \"#design-system\";\n\ntype Props = {\n readonly branch?: string;\n};\nexport function Branch(props: Props) {\n const { branch = \"main\" } = props;\n\n return (\n <button className=\"flex h-8 w-fit items-center gap-1 rounded-lg bg-gray-50 pr-2 pl-1 text-xs text-stone-300 dark:bg-slate-800\">\n <Icon name=\"Branch\" />\n <span>BRANCH</span>\n <span className=\"text-gray-900 dark:text-slate-50\">{branch}</span>\n </button>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { useCopyToClipboard } from \"usehooks-ts\";\n\ntype Props = {\n readonly docId: string;\n readonly onCopy?: () => void;\n};\nexport function DocId(props: Props) {\n const { docId, onCopy } = props;\n const [, copy] = useCopyToClipboard();\n\n function handleCopy(text: string) {\n return () => {\n copy(text)\n .then(() => {\n onCopy?.();\n })\n .catch((error) => {\n console.error(\"Failed to copy!\", error);\n });\n };\n }\n\n return (\n <button\n className=\"flex h-8 w-fit items-center gap-1 rounded-lg bg-gray-50 pr-2 pl-1 text-xs text-stone-300 dark:bg-slate-800\"\n onClick={handleCopy(docId)}\n >\n <Icon name=\"Link\" />\n DOC ID\n <span className=\"text-gray-900 dark:text-slate-50\">{docId}</span>\n </button>\n );\n}\n","import { Icon } from \"#design-system\";\nimport { useCopyToClipboard } from \"usehooks-ts\";\n\nexport type DocumentStateProps = {\n readonly documentState: object;\n readonly onCopyState?: () => void;\n};\n\nexport const DocumentState = (props: DocumentStateProps) => {\n const { documentState, onCopyState } = props;\n const [, copy] = useCopyToClipboard();\n\n function handleCopy() {\n const jsonState = JSON.stringify(documentState, null, 2);\n copy(jsonState)\n .then(() => {\n onCopyState?.();\n })\n .catch((error) => {\n console.error(\"Failed to copy document state!\", error);\n });\n }\n\n return (\n <button\n className=\"rounded-lg bg-gray-50 p-1 text-stone-300 dark:bg-slate-800\"\n onClick={handleCopy}\n >\n <Icon name=\"CurlyBrackets\" />\n </button>\n );\n};\n","import { ConnectSelect } from \"../../select/select.js\";\n\ntype Props = {\n readonly value: string;\n readonly onChange: (value: string) => void;\n};\nexport function Scope(props: Props) {\n const { value, onChange } = props;\n const items = [\n { displayValue: \"Global scope\", value: \"global\" },\n { displayValue: \"Local scope\", value: \"local\" },\n ] as const;\n\n return (\n <ConnectSelect\n absolutePositionMenu\n containerClassName=\"bg-gray-50 text-gray-500 rounded-lg w-fit text-xs z-10 dark:bg-slate-800 dark:text-slate-400\"\n id=\"scope select\"\n itemClassName=\"py-2 text-gray-500 grid grid-cols-[auto,auto] gap-1 dark:text-slate-400\"\n items={items}\n menuClassName=\"min-w-0 text-gray-500 dark:text-slate-400\"\n onChange={onChange}\n value={value}\n />\n );\n}\n","import { Icon } from \"#design-system\";\nimport type { ReactNode } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Branch } from \"./branch.js\";\nimport { DocId } from \"./doc-id.js\";\nimport { DocumentState } from \"./document-state.js\";\nimport { Scope } from \"./scope.js\";\n\ninterface Props extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n readonly title: ReactNode;\n readonly docId: string;\n readonly scope: string;\n readonly onChangeScope: (scope: string) => void;\n readonly onClose: () => void;\n readonly documentState?: object;\n readonly onCopyState?: () => void;\n readonly onCopyDocId?: () => void;\n}\n\nexport function Header(props: Props) {\n const {\n title,\n docId,\n scope,\n onChangeScope,\n onClose,\n className,\n documentState,\n onCopyState,\n onCopyDocId,\n ...divProps\n } = props;\n return (\n <header\n className={twMerge(\n \"flex items-center justify-between bg-transparent\",\n className,\n )}\n {...divProps}\n >\n <div className=\"flex items-center gap-3\">\n <button\n name=\"close-revision-history\"\n className=\"rounded-lg bg-gray-50 p-1 text-stone-300 shadow-button dark:bg-slate-800\"\n onClick={onClose}\n >\n <Icon name=\"VariantArrowLeft\" />\n </button>\n <h1 className=\"text-xs text-gray-900 dark:text-slate-50\">{title}</h1>\n </div>\n <div className=\"flex items-center gap-2\">\n <DocId docId={docId} onCopy={onCopyDocId} />\n {documentState && (\n <DocumentState\n documentState={documentState}\n onCopyState={onCopyState}\n />\n )}\n <Branch />\n <Scope onChange={onChangeScope} value={scope} />\n </div>\n </header>\n );\n}\n","import { useEffect, useState } from \"react\";\n\ntype EnsData = {\n ens: string;\n address: string;\n avatar: string | null;\n avatar_small: string | null;\n avatar_url: string | null;\n contentHash: string | null;\n header: string | null;\n header_url: string | null;\n ens_primary: string;\n resolverAddress: string;\n url: string | null;\n github: string | null;\n twitter: string | null;\n telegram: string | null;\n email: string | null;\n description: string | null;\n notice: string | null;\n keywords: string | null;\n discord: string | null;\n};\n\ntype UseEnsResult = {\n data: EnsData | undefined;\n isLoading: boolean;\n error: Error | undefined;\n};\n\nconst ensCache = new Map<`0x${string}`, Promise<EnsData | undefined>>();\n\nfunction fetchEns(address: `0x${string}`): Promise<EnsData | undefined> {\n const cached = ensCache.get(address);\n if (cached) return cached;\n\n const promise = fetch(`https://api.ensdata.net/${address}`)\n .then((res) => {\n if (!res.ok) throw new Error(`ENS lookup failed: ${res.status}`);\n return res.json() as Promise<EnsData>;\n })\n .catch((err: unknown) => {\n ensCache.delete(address);\n throw err instanceof Error ? err : new Error(\"ENS lookup failed\");\n });\n\n ensCache.set(address, promise);\n return promise;\n}\n\nexport function useEns(address: `0x${string}` | undefined): UseEnsResult {\n const [data, setData] = useState<EnsData>();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error>();\n\n useEffect(() => {\n if (!address) {\n setData(undefined);\n setError(undefined);\n return;\n }\n\n let cancelled = false;\n setIsLoading(true);\n setError(undefined);\n\n fetchEns(address)\n .then((json) => {\n if (cancelled) return;\n setData(json);\n })\n .catch((err: unknown) => {\n if (cancelled) return;\n setError(err instanceof Error ? err : new Error(\"ENS lookup failed\"));\n })\n .finally(() => {\n if (cancelled) return;\n setIsLoading(false);\n });\n\n return () => {\n cancelled = true;\n };\n }, [address]);\n\n return { data, isLoading, error };\n}\n","export function formatEthAddress(address: string) {\n return `${address.slice(0, 7)}...${address.slice(-5)}`;\n}\n","import {\n Anchor,\n Content,\n Portal,\n Root,\n Trigger,\n} from \"@radix-ui/react-popover\";\nimport { useState, type ReactNode } from \"react\";\nimport { funnel } from \"remeda\";\n\n/* A hybrid popover / tooltip component intended for showing data that needs\n to show / hide on hover, while also being able to stay open so that the user can\n interact with its contents.\n\n Uses these rules:\n\n When the user hover's the trigger, show the tooltip / popover.\n Immediately place the content under the user's cursor.\n Then let the responsibility of closing the tooltip / popover be transferred _to the content_.\n When the user leaves _the contents_ or interacts elsewhere, only then close.\n*/\nexport function CodePopover(props: {\n content: ReactNode;\n trigger: ReactNode;\n anchor?: ReactNode;\n}) {\n const { content, trigger, anchor } = props;\n const [isOpen, setIsOpen] = useState(false);\n\n /* debounce calls to open by 300ms */\n const opener = funnel(() => setIsOpen(true), {\n triggerAt: \"start\",\n minQuietPeriodMs: 300,\n });\n\n /* debounce calls to close by 100ms */\n const closer = funnel(() => setIsOpen(false), {\n triggerAt: \"start\",\n minQuietPeriodMs: 100,\n });\n\n /* If we are in the process of closing, cancel that operation.\n Then call the opener.\n */\n function open() {\n closer.cancel();\n opener.call();\n }\n\n /* If we are in the process of opening, cancel that operation.\n Then call the closer.\n */\n function close() {\n opener.cancel();\n closer.call();\n }\n\n return (\n <Root\n /* This component combines internal state with the existing accessibility behaviors from the radix popover */\n open={isOpen}\n onOpenChange={(changedIsOpen) => (changedIsOpen ? open() : close())}\n >\n {/* Trigger only manages opening */}\n <Trigger onMouseEnter={open}>{trigger}</Trigger>\n {!!anchor && <Anchor asChild>{anchor}</Anchor>}\n <Portal>\n <Content\n /* We need to force mount so that the events are fired as expected */\n forceMount\n /* content only manages closing */\n onMouseLeave={close}\n /* Offset the position to ensure that we open under the user's cursor */\n sideOffset={-28}\n /* Do not focus the trigger after closing since that item is not interactive */\n onCloseAutoFocus={(e) => e.preventDefault()}\n /* Set an arbitrarily large bottom collision detection padding so that very long content flows below the fold */\n collisionPadding={{\n top: 24,\n right: 24,\n bottom: -10_000,\n left: 24,\n }}\n className=\"z-50 rounded-lg border border-gray-200 bg-gray-50 p-2 text-xs shadow-tooltip outline-none dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\"\n >\n {content}\n </Content>\n </Portal>\n </Root>\n );\n}\n","import { useEns } from \"../../../hooks/use-ens.js\";\nimport { formatEthAddress } from \"../../../utils/address.js\";\nimport { CodePopover } from \"../../code-popover.js\";\nimport { ENSAvatar } from \"../../ens-avatar/ens-avatar.js\";\nimport { FormattedJsonViewer } from \"../../formatted-json-viewer.js\";\n\nexport type AddressProps = {\n readonly address: `0x${string}` | undefined;\n readonly chainId: number | undefined;\n};\n\nexport function Address(props: AddressProps) {\n const { address, chainId } = props;\n const { data: ensData } = useEns(address);\n\n if (!address) return null;\n\n const shortenedAddress = formatEthAddress(address);\n\n return (\n <CodePopover\n content={<FormattedJsonViewer value={{ address }} />}\n trigger={\n <span className=\"flex w-fit cursor-pointer items-center gap-1 rounded-lg bg-gray-100 p-1 text-xs text-gray-100 dark:bg-slate-700 dark:text-slate-800\">\n <ENSAvatar\n address={address}\n chainId={chainId}\n avatarUrl={ensData?.avatar_url ?? undefined}\n />\n {shortenedAddress}\n </span>\n }\n />\n );\n}\n","import { Icon } from \"#design-system\";\nimport { twMerge } from \"tailwind-merge\";\nimport { CodePopover } from \"../../code-popover.js\";\nimport { FormattedJsonViewer } from \"../../formatted-json-viewer.js\";\n\nexport type ErrorsProps = {\n readonly errors: string[] | undefined;\n};\n\nexport function Errors(props: ErrorsProps) {\n const { errors } = props;\n\n const hasErrors = !!errors?.length;\n\n const color = hasErrors\n ? \"text-red-800 dark:text-red-100\"\n : \"text-green-700 dark:text-green-100\";\n\n const icon = hasErrors ? (\n <Icon name=\"Exclamation\" size={16} />\n ) : (\n <Icon name=\"Check\" size={16} />\n );\n\n const text = hasErrors ? `Error: ${errors[0]}` : \"No errors\";\n\n const content = (\n <span\n className={twMerge(\n \"flex w-fit items-center rounded-lg border border-gray-200 bg-gray-50 px-2 py-1 text-xs dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n color,\n hasErrors && \"cursor-pointer\",\n )}\n >\n {icon}\n <span className={twMerge(\"inline-block max-w-36 truncate\")}>{text}</span>\n </span>\n );\n\n if (hasErrors)\n return (\n <CodePopover\n content={<FormattedJsonViewer value={errors} />}\n trigger={content}\n />\n );\n\n return content;\n}\n","import { Icon } from \"#design-system\";\nimport { CodePopover } from \"../../code-popover.js\";\nimport { FormattedJsonViewer } from \"../../formatted-json-viewer.js\";\nexport type OperationProps = {\n readonly operationType: string;\n readonly operationInput: Record<string, any>;\n};\n\nexport function Operation(props: OperationProps) {\n const { operationType, operationInput } = props;\n return (\n <CodePopover\n content={<FormattedJsonViewer value={operationInput} />}\n trigger={\n <span className=\"flex cursor-pointer items-center gap-2 text-xs text-gray-900 dark:text-slate-50\">\n {operationType}\n <Icon\n className=\"text-gray-300 dark:text-slate-600\"\n name=\"Braces\"\n size={16}\n />\n </span>\n }\n />\n );\n}\n","import { Icon } from \"#design-system\";\nimport { CodePopover } from \"../../code-popover.js\";\nimport { FormattedJsonViewer } from \"../../formatted-json-viewer.js\";\n\nexport type RevisionNumberProps = {\n readonly operationIndex: number;\n readonly eventId: string;\n readonly stateHash: string;\n};\nexport function RevisionNumber(props: RevisionNumberProps) {\n const { operationIndex, eventId, stateHash } = props;\n const revisionNumber = operationIndex + 1;\n\n return (\n <CodePopover\n content={\n <FormattedJsonViewer\n value={{\n revisionNumber,\n eventId,\n stateHash,\n }}\n />\n }\n trigger={\n <span className=\"flex cursor-pointer items-center gap-2 text-xs text-gray-700 dark:text-slate-200\">\n Revision {revisionNumber}.\n <a>\n <Icon\n className=\"cursor-pointer text-gray-100 dark:text-slate-800\"\n name=\"Ellipsis\"\n size={14}\n />\n </a>\n </span>\n }\n />\n );\n}\n","import { Icon } from \"#design-system\";\nimport { CodePopover } from \"../../code-popover.js\";\nimport { FormattedJsonViewer } from \"../../formatted-json-viewer.js\";\nimport type { Signature } from \"../types.js\";\n\nexport type SignatureProps = {\n readonly signatures: Signature[] | undefined;\n};\nexport function Signature(props: SignatureProps) {\n const { signatures } = props;\n\n if (!signatures?.length) return null;\n\n return (\n <CodePopover\n trigger={\n <span className=\"flex w-fit cursor-pointer items-center gap-1 rounded-lg border border-gray-200 bg-gray-50 px-2 py-1 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <VerificationStatus signatures={signatures} />{\" \"}\n <Icon\n className=\"text-gray-300 dark:text-slate-600\"\n name=\"InfoSquare\"\n size={16}\n />\n </span>\n }\n content={<FormattedJsonViewer value={signatures} collapsed={1} />}\n />\n );\n}\n\nfunction VerificationStatus(props: SignatureProps) {\n const { signatures } = props;\n\n if (!signatures?.length) return null;\n\n const signatureCount = signatures.length;\n\n const verifiedSignaturesCount = signatures.filter(\n (signature) => signature.isVerified,\n ).length;\n const signatureText = signatureCount === 1 ? \"signature\" : \"signatures\";\n const verificationStatusText = `${verifiedSignaturesCount}/${signatureCount} ${signatureText} verified`;\n const color =\n verifiedSignaturesCount === 0\n ? \"text-red-800 dark:text-red-100\"\n : verifiedSignaturesCount === signatureCount\n ? \"text-green-700 dark:text-green-100\"\n : \"text-orange-700 dark:text-orange-100\";\n\n return <span className={`text-xs ${color}`}>{verificationStatusText}</span>;\n}\n","import { format } from \"date-fns\";\nimport { CodePopover } from \"../../code-popover.js\";\nimport { FormattedJsonViewer } from \"../../formatted-json-viewer.js\";\n\nexport type TimestampProps = {\n readonly timestampUtcMs: number | string;\n};\n\nexport function Timestamp(props: TimestampProps) {\n const { timestampUtcMs: timestamp } = props;\n\n const timestampNumber =\n typeof timestamp === \"string\" && !timestamp.includes(\"-\")\n ? parseInt(timestamp)\n : timestamp;\n\n const date = new Date(timestampNumber);\n const shortDate = format(date, \"HH:mm 'UTC'\");\n const longDate = format(date, \"eee, dd MMM yyyy HH:mm:ss 'UTC'\");\n\n return (\n <CodePopover\n content={\n <FormattedJsonViewer\n value={{ timestampFormatted: longDate, timestampUtcMs: timestamp }}\n />\n }\n trigger={\n <span className=\"cursor-pointer text-xs text-gray-900 dark:text-slate-50\">\n committed at {shortDate}\n </span>\n }\n />\n );\n}\n","import { memo } from \"react\";\nimport type { Revision as RevisionProps } from \"../types.js\";\nimport { Address } from \"./address.js\";\nimport { Errors } from \"./errors.js\";\nimport { Operation } from \"./operation.js\";\nimport { RevisionNumber } from \"./revision-number.js\";\nimport { Signature } from \"./signature.js\";\nimport { Timestamp } from \"./timestamp.js\";\n\nexport function _Revision(props: RevisionProps) {\n return (\n <article className=\"flex items-center justify-between rounded-xl border border-gray-200 bg-gray-50 px-4 py-2 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n <div className=\"flex items-center gap-2\">\n <RevisionNumber {...props} />\n <Operation {...props} />\n <Address {...props} />\n <Timestamp {...props} />\n </div>\n <div className=\"flex items-center gap-1\">\n <Signature {...props} />\n <Errors {...props} />\n </div>\n </article>\n );\n}\n\nexport const Revision = memo(_Revision);\n","export type SkipProps = {\n readonly operationIndex: number;\n readonly skipCount: number;\n};\n\nexport function Skip(props: SkipProps) {\n const { operationIndex, skipCount } = props;\n const revisionNumber = operationIndex;\n\n const skippedRevisions =\n skipCount === 1\n ? `${revisionNumber}`\n : `${revisionNumber} - ${revisionNumber + 1 - skipCount}`;\n\n return (\n <article className=\"grid grid-cols-[1fr,auto,1fr] items-center py-2\">\n <div className=\"h-px rounded-full bg-gray-100 dark:bg-slate-700\" />\n <div className=\"mx-3 text-xs text-gray-100 dark:text-slate-800\">\n [Skipped Revision {skippedRevisions}]\n </div>\n <div className=\"h-px rounded-full bg-gray-100 dark:bg-slate-700\" />\n </article>\n );\n}\n","import type { Operation } from \"@powerhousedao/shared/document-model\";\nimport type { Day, Revision, Signature, Skip } from \"./types.js\";\n\nexport function makeRows(operations: Operation[]) {\n const revisionsAndSkips: (Revision | Skip | Day)[] = [];\n const seenDays = new Set<string>();\n\n for (const operation of operations) {\n if (!operation.timestampUtcMs) continue;\n const day = operation.timestampUtcMs.split(\"T\")[0];\n\n if (!seenDays.has(day)) {\n seenDays.add(day);\n revisionsAndSkips.push({\n type: \"day\",\n height: 32,\n timestampUtcMs: day,\n });\n }\n\n revisionsAndSkips.push({\n type: \"revision\",\n height: 46,\n operationIndex: operation.index,\n eventId: operation.id ?? \"EVENT_ID_NOT_FOUND\",\n stateHash: operation.hash,\n operationType: operation.action.type,\n operationInput: operation.action.input ?? {},\n address: operation.action?.context?.signer?.user.address as\n | `0x${string}`\n | undefined,\n chainId: operation.action?.context?.signer?.user.chainId,\n timestampUtcMs: operation.timestampUtcMs,\n signatures: makeSignatures(\n (operation.action?.context?.signer?.signatures as\n | string[][]\n | undefined) ?? [],\n ),\n errors: operation.error ? [operation.error] : undefined,\n });\n\n if (operation.skip > 0) {\n revisionsAndSkips.push({\n type: \"skip\",\n height: 34,\n operationIndex: operation.index,\n skipCount: operation.skip,\n timestampUtcMs: operation.timestampUtcMs,\n });\n }\n }\n\n return revisionsAndSkips;\n}\n\nexport function getUniqueDatesInOrder(operations: Operation[]) {\n const dates = new Set<string>();\n\n for (const operation of operations) {\n if (!operation.timestampUtcMs) continue;\n const date = operation.timestampUtcMs.split(\"T\")[0];\n dates.add(date);\n }\n\n return Array.from(dates).sort(\n (a, b) => new Date(b).getTime() - new Date(a).getTime(),\n );\n}\n\nfunction makeSignatureFromSignatureArray(signatureArray: string[]): Signature {\n const [signerAddress, hash, prevStateHash, signatureBytes] = signatureArray;\n\n return {\n signerAddress,\n hash,\n prevStateHash,\n signatureBytes,\n isVerified: true,\n };\n}\n\nfunction makeSignatures(signaturesArray: string[][] | undefined) {\n return signaturesArray?.map(makeSignatureFromSignatureArray);\n}\n","import { Icon } from \"#design-system\";\nimport { format } from \"date-fns\";\n\nexport function Day(props: { readonly timestampUtcMs: string }) {\n const { timestampUtcMs: timestamp } = props;\n const formattedDate = format(timestamp, \"MMM dd, yyyy\");\n return (\n <h2 className=\"-ml-6 flex items-center gap-1 bg-gray-50 py-2 text-xs text-gray-100 dark:bg-slate-800 dark:text-slate-800\">\n <Icon name=\"Ring\" size={16} /> Changes on {formattedDate}\n </h2>\n );\n}\n","import type { Operation } from \"@powerhousedao/shared/document-model\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Revision } from \"../revision/revision.js\";\nimport { Skip } from \"../skip/skip.js\";\nimport { makeRows } from \"../utils.js\";\nimport { Day } from \"./day.js\";\n\nexport type TimelineProps = {\n readonly localOperations: Operation[];\n readonly globalOperations: Operation[];\n readonly scope: string;\n};\n\nexport function Timeline(props: TimelineProps) {\n const { localOperations, globalOperations, scope } = props;\n const operations = scope === \"local\" ? localOperations : globalOperations;\n const initialNumRowsToShow = 100;\n const allRows = useMemo(() => makeRows(operations), [operations]);\n const [scrollAmount, setScrollAmount] = useState(0);\n const [numRowsToShow, setNumRowsToShow] = useState(initialNumRowsToShow);\n const [rows, setRows] = useState(() => allRows.slice(0, numRowsToShow));\n\n const parentRef = useRef<HTMLDivElement>(null);\n\n const hasNextPage = rows.length < allRows.length;\n\n const rowVirtualizer = useVirtualizer({\n count: rows.length,\n getScrollElement: () => parentRef.current,\n estimateSize: (i) => allRows[i].height,\n gap: 8,\n });\n\n useEffect(() => {\n if (!hasNextPage) return;\n const ratio = Math.floor(scrollAmount / 46);\n const newNumRevisions = initialNumRowsToShow + ratio;\n setNumRowsToShow((prev) =>\n newNumRevisions > prev ? newNumRevisions : prev,\n );\n }, [scrollAmount, hasNextPage]);\n\n useEffect(() => {\n setRows(allRows.slice(0, numRowsToShow));\n }, [allRows, numRowsToShow]);\n\n const handleScroll = (e: WheelEvent) => {\n setScrollAmount((prev) => {\n const n = prev + e.deltaY;\n if (n < 0) {\n return 0;\n }\n return n;\n });\n };\n\n useEffect(() => {\n window.addEventListener(\"wheel\", handleScroll);\n return () => {\n window.removeEventListener(\"wheel\", handleScroll);\n };\n }, []);\n\n return (\n <div\n className=\"border-l border-gray-100 dark:border-none dark:bg-slate-800 dark:text-slate-100\"\n ref={parentRef}\n style={{\n height: `${rowVirtualizer.getTotalSize()}px`,\n width: \"100%\",\n position: \"relative\",\n }}\n >\n {rowVirtualizer.getVirtualItems().map((virtualRow) => {\n const row = rows[virtualRow.index];\n\n return (\n <div\n key={virtualRow.index}\n style={{\n position: \"absolute\",\n top: 0,\n left: 16,\n width: \"100%\",\n height: `${virtualRow.size}px`,\n transform: `translateY(${virtualRow.start}px)`,\n }}\n >\n {row.type === \"revision\" && (\n <Revision {...row} key={virtualRow.key} />\n )}\n {row.type === \"skip\" && <Skip key={virtualRow.key} {...row} />}\n {row.type === \"day\" && <Day key={virtualRow.key} {...row} />}\n </div>\n );\n })}\n </div>\n );\n}\n","import { Pagination, usePagination } from \"#design-system\";\nimport type { Operation } from \"@powerhousedao/shared/document-model\";\nimport {\n garbageCollect,\n sortOperations,\n} from \"@powerhousedao/shared/document-model\";\nimport { useMemo, useState } from \"react\";\nimport { ConnectTooltipProvider } from \"../tooltip/tooltip.js\";\nimport { Header } from \"./header/header.js\";\nimport { Timeline } from \"./timeline/timeline.js\";\n\ntype Props = {\n readonly documentTitle: string;\n readonly documentId: string;\n readonly globalOperations: Operation[];\n readonly localOperations: Operation[];\n readonly onClose: () => void;\n readonly itemsPerPage?: number;\n readonly documentState?: object;\n readonly onCopyState?: () => void;\n readonly onCopyDocId?: () => void;\n};\n\nexport function RevisionHistory(props: Props) {\n const {\n documentTitle,\n documentId,\n globalOperations,\n localOperations,\n onClose,\n itemsPerPage = 100,\n documentState,\n onCopyState,\n onCopyDocId,\n } = props;\n\n const [scope, setScope] = useState<string>(\"global\");\n\n const visibleOperations = useMemo(() => {\n const operations = scope === \"global\" ? globalOperations : localOperations;\n return garbageCollect(sortOperations(operations)).sort(\n (a, b) => b.index - a.index,\n );\n }, [globalOperations, localOperations, scope]);\n\n const {\n pageItems,\n pages,\n goToPage,\n goToNextPage,\n goToPreviousPage,\n goToFirstPage,\n goToLastPage,\n hiddenNextPages,\n isNextPageAvailable,\n isPreviousPageAvailable,\n } = usePagination(visibleOperations, {\n itemsPerPage,\n });\n\n function onChangeScope(scope: string) {\n goToFirstPage();\n setScope(scope);\n }\n\n const showPagination = visibleOperations.length > itemsPerPage;\n\n const PaginationComponent = showPagination ? (\n <div className=\"mt-4 flex w-full justify-end\">\n <Pagination\n firstPageLabel=\"First Page\"\n goToFirstPage={goToFirstPage}\n goToLastPage={goToLastPage}\n goToNextPage={goToNextPage}\n goToPage={goToPage}\n goToPreviousPage={goToPreviousPage}\n hiddenNextPages={hiddenNextPages}\n isNextPageAvailable={isNextPageAvailable}\n isPreviousPageAvailable={isPreviousPageAvailable}\n lastPageLabel=\"Last Page\"\n nextPageLabel=\"Next\"\n pages={pages}\n previousPageLabel=\"Previous\"\n />\n </div>\n ) : (\n <hr className=\"h-12 border-none\" />\n );\n\n return (\n <ConnectTooltipProvider>\n <div className=\"p-6 dark:bg-slate-800\">\n <Header\n docId={documentId}\n onChangeScope={onChangeScope}\n onClose={onClose}\n scope={scope}\n title={documentTitle}\n documentState={documentState}\n onCopyState={onCopyState}\n onCopyDocId={onCopyDocId}\n />\n {PaginationComponent}\n <div className=\"mt-4 flex justify-center rounded-md bg-gray-50 p-4 dark:bg-slate-800\">\n {visibleOperations.length > 0 ? (\n <div className=\"grid grid-cols-[minmax(min-content,1018px)]\">\n <Timeline\n globalOperations={scope === \"global\" ? pageItems : []}\n localOperations={scope === \"local\" ? pageItems : []}\n scope={scope}\n />\n </div>\n ) : (\n <h3 className=\"my-40 text-gray-700 dark:text-slate-200\">\n This document has no recorded operations yet.\n </h3>\n )}\n </div>\n {PaginationComponent}\n </div>\n </ConnectTooltipProvider>\n );\n}\n","import { twMerge } from \"tailwind-merge\";\n\nexport type FilterItemType = {\n id: string;\n label: string;\n icon?: React.JSX.Element;\n};\n\nexport interface FilterItemProps extends React.HTMLAttributes<HTMLDivElement> {\n item: FilterItemType;\n}\n\nexport const FilterItem: React.FC<FilterItemProps> = (props) => {\n const { item, className, ...containerProps } = props;\n\n return (\n <div\n className={twMerge(\n \"flex h-full flex-row items-center justify-between gap-x-4 px-2\",\n typeof className === \"string\" && className,\n )}\n {...containerProps}\n >\n {item.icon}\n <div className=\"text-sm font-semibold text-gray-200 dark:text-slate-700\">\n {item.label}\n </div>\n </div>\n );\n};\n","import {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n Icon,\n} from \"#design-system\";\nimport type { ChangeEvent } from \"react\";\nimport { useMemo } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport type { FilterItemType } from \"./filter-item.js\";\nimport { FilterItem } from \"./filter-item.js\";\n\nexport interface ConnectSearchBarProps {\n value?: string;\n onChange?: (value: string) => void;\n placeholder?: string;\n filterLabel?: string;\n filterItems?: Array<FilterItemType>;\n selectedFilter?: string;\n onFilterSelect?: (filterId: string) => void;\n className?: string;\n}\n\nexport const ConnectSearchBar: React.FC<ConnectSearchBarProps> = (props) => {\n const {\n value,\n onChange,\n placeholder,\n filterLabel,\n filterItems,\n selectedFilter,\n onFilterSelect = () => {},\n className,\n } = props;\n\n const items = useMemo(\n () =>\n filterItems?.map((item) => ({\n id: item.id,\n content: <FilterItem item={item} />,\n })) ?? [],\n [filterItems],\n );\n\n const selectedItemFilter = filterItems?.find(\n (item) => item.id === selectedFilter,\n );\n\n const filterLabelContent = selectedItemFilter ? (\n <FilterItem className=\"gap-x-1\" item={selectedItemFilter} />\n ) : (\n filterLabel && (\n <div className=\"mr-2 text-sm font-semibold text-gray-200 dark:text-slate-700\">\n {filterLabel}\n </div>\n )\n );\n\n function handleChange(event: ChangeEvent<HTMLInputElement>) {\n onChange?.(event.target.value);\n }\n\n return (\n <div className={twMerge(\"flex items-center\", className)}>\n <Icon className=\"mr-3 text-gray-700 dark:text-slate-200\" name=\"Search\" />\n <input\n className={twMerge(\n \"flex h-[52px] min-w-0 flex-1 items-center rounded-xl border border-gray-200 bg-gray-50 px-4 text-sm text-gray-200 outline-none dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n )}\n onChange={handleChange}\n placeholder={placeholder}\n value={value}\n />\n <DropdownMenu>\n <DropdownMenuTrigger className=\"ml-3 flex h-full flex-row items-center outline-none\">\n {filterLabelContent} <Icon name=\"ChevronDown\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"rounded-xl border border-gray-100 bg-gray-50 p-2 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\">\n {items.map((item) => (\n <DropdownMenuItem\n className=\"h-10 cursor-pointer overflow-hidden rounded-lg hover:bg-gray-100 dark:hover:bg-slate-700\"\n id={item.id}\n key={item.id}\n onSelect={() => onFilterSelect(item.id)}\n >\n {item.content}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n );\n};\n","import { twMerge } from \"tailwind-merge\";\nimport { ConnectTooltip } from \"../tooltip/tooltip.js\";\n\ntype SidebarItemProps = {\n readonly icon?: React.JSX.Element;\n readonly title: string;\n readonly description?: string;\n readonly containerClassName?: string;\n readonly active?: boolean;\n readonly onClick?: (event: React.MouseEvent<HTMLDivElement>) => void;\n};\nexport const SidebarItem = function SidebarItem(props: SidebarItemProps) {\n const {\n icon,\n title,\n description: _description,\n containerClassName,\n active,\n onClick,\n } = props;\n return (\n <ConnectTooltip\n content={title}\n side=\"right\"\n sideOffset={12}\n className=\"border-none bg-gray-800 px-3 py-2 text-sm text-white dark:bg-slate-100 dark:text-slate-900\"\n >\n <div\n className={twMerge(\n \"group/sidebar-item relative flex cursor-pointer flex-col items-center justify-center text-center text-sm text-gray-900 dark:text-slate-50\",\n containerClassName,\n active && \"bg-gray-50 dark:bg-slate-800\",\n onClick && \"cursor-pointer\",\n )}\n onClick={onClick}\n >\n {active ? (\n <div className=\"absolute top-1/2 left-0 h-10 w-1 -translate-y-1/2 rounded-r-sm bg-violet-400 dark:bg-violet-500\" />\n ) : (\n <div className=\"absolute top-1/2 left-0 h-6 w-1 -translate-y-1/2 rounded-r-sm bg-gray-300 opacity-0 transition-opacity group-hover/sidebar-item:opacity-100 dark:bg-slate-600 dark:text-slate-100\" />\n )}\n <div className=\"mx-auto py-4\">\n {icon || (\n <div className=\"flex size-8 items-center justify-center rounded-lg bg-gray-900 dark:bg-slate-50\">\n <span className=\"text-sm font-medium text-white dark:text-slate-900\">\n {title.slice(0, 1).toUpperCase()}\n </span>\n </div>\n )}\n </div>\n </div>\n </ConnectTooltip>\n );\n};\n","import { Icon } from \"#design-system\";\nimport { SidebarItem } from \"./sidebar-item.js\";\n\ntype SidebarAddDriveItemProps = {\n readonly containerClassName?: string;\n readonly onClick?: (event: React.MouseEvent<HTMLDivElement>) => void;\n};\nexport const SidebarAddDriveItem = function SidebarAddDriveItem(\n props: SidebarAddDriveItemProps,\n) {\n const { containerClassName, onClick } = props;\n return (\n <SidebarItem\n title=\"Create New Drive\"\n icon={<Icon name=\"PlusSquare\" size={32} />}\n onClick={onClick}\n containerClassName={containerClassName}\n />\n );\n};\n","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","\"data:image/png;base64,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\"","import { Icon } from \"#design-system\";\nimport type { FC } from \"react\";\nimport { useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport interface AccountPopoverLoginProps {\n onLogin: (() => void) | undefined;\n}\n\nexport const AccountPopoverLogin: FC<AccountPopoverLoginProps> = ({\n onLogin,\n}) => {\n const [loading, setLoading] = useState(false);\n\n const allowLogin = !loading && !!onLogin;\n\n const content = loading ? (\n <Icon name=\"Reload\" size={14} className=\"animate-spin\" />\n ) : (\n <span>Connect</span>\n );\n\n const handleLogin = () => {\n if (onLogin) {\n setLoading(true);\n onLogin();\n }\n };\n\n return (\n <div className=\"p-4\">\n <div className=\"mb-4 flex justify-center\">\n <div className=\"flex h-5.5 w-20.75 items-center justify-center overflow-hidden text-gray-900 dark:text-slate-50\">\n <Icon name=\"RenownLight\" size={83} />\n </div>\n </div>\n <button\n onClick={allowLogin ? handleLogin : undefined}\n className={twMerge(\n \"mt-4 flex h-7 w-full cursor-pointer items-center justify-center rounded-lg border border-gray-300 bg-transparent text-sm text-gray-900 active:opacity-70 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100\",\n allowLogin ? \"cursor-pointer\" : \"cursor-wait\",\n )}\n type=\"button\"\n >\n {content}\n </button>\n </div>\n );\n};\n","import renownShortDark from \"#assets/renown-short-dark.png\";\nimport renownShortHoverDark from \"#assets/renown-short-hover-dark.png\";\nimport renownShortHover from \"#assets/renown-short-hover.png\";\nimport renownShort from \"#assets/renown-short.png\";\nimport { useTheme } from \"@powerhousedao/reactor-browser\";\nimport { twMerge } from \"tailwind-merge\";\nimport { AccountPopoverLogin } from \"../account-popover/account-popover-login.js\";\nimport { AccountPopover } from \"../account-popover/account-popover.js\";\n\nexport interface SidebarLoginProps {\n onLogin: (() => void) | undefined;\n}\n\nexport const SidebarLogin: React.FC<SidebarLoginProps> = ({ onLogin }) => {\n const content = <AccountPopoverLogin onLogin={onLogin} />;\n const { theme } = useTheme();\n const isDark = theme === \"dark\";\n const src = isDark ? renownShortDark : renownShort;\n const hoverSrc = isDark ? renownShortHoverDark : renownShortHover;\n\n return (\n <AccountPopover content={content}>\n <div\n className={twMerge(\n \"group/sidebar-footer flex w-full items-baseline justify-start text-sm/10 font-semibold text-gray-700 dark:text-slate-200\",\n onLogin ? \"cursor-pointer\" : \"cursor-wait\",\n )}\n >\n <img\n width={42}\n height={42}\n loading=\"lazy\"\n className=\"group-hover/sidebar-footer:hidden\"\n src={src}\n alt=\"Renown Login\"\n />\n <img\n width={42}\n height={42}\n loading=\"lazy\"\n className=\"hidden group-hover/sidebar-footer:block\"\n src={hoverSrc}\n alt=\"Renown Login Hover\"\n />\n </div>\n </AccountPopover>\n );\n};\n","import { Icon, PowerhouseButton } from \"#design-system\";\nimport type { FC } from \"react\";\nimport { useCallback, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport interface AccountPopoverUserProps {\n address: `0x${string}`;\n onDisconnect: (() => void) | undefined;\n etherscanUrl?: string;\n username?: string;\n}\n\n// short eth address\nconst shortAddress = (address: `0x${string}`) =>\n `${address.slice(0, 7)}...${address.slice(-5)}`;\n\nexport const AccountPopoverUser: FC<AccountPopoverUserProps> = ({\n address,\n onDisconnect,\n etherscanUrl,\n username = \"\",\n}: AccountPopoverUserProps) => {\n const [isCopied, setIsCopied] = useState(false);\n\n const copyToClipboard = useCallback(async (text: string) => {\n try {\n await navigator.clipboard.writeText(text);\n setIsCopied(true);\n setTimeout(() => setIsCopied(false), 2000);\n } catch (err) {\n console.error(\"Failed to copy address:\", err);\n }\n }, []);\n\n return (\n <div className=\"flex flex-col divide-y divide-gray-200 text-gray-900 dark:divide-slate-500 dark:text-slate-50\">\n <div className=\"px-3 py-2\">\n {username && <div className=\"text-sm font-medium\">{username}</div>}\n <div className=\"mt-1 flex items-center gap-2\">\n <PowerhouseButton\n size=\"small\"\n color=\"light\"\n onClick={() => void copyToClipboard(address)}\n className=\"w-full cursor-pointer bg-transparent p-0 active:opacity-70\"\n type=\"button\"\n >\n <div className=\"relative flex w-full items-center gap-1\">\n <div\n className={`flex items-center gap-1 transition-opacity duration-150 ${isCopied ? \"opacity-0\" : \"opacity-100\"}`}\n >\n <span className=\"text-xs\">{shortAddress(address)}</span>\n <Icon name=\"FilesEarmark\" color=\"#9EA0A1\" size={14} />\n </div>\n <div\n className={`absolute left-0 text-xs transition-opacity duration-150 ${isCopied ? \"opacity-100\" : \"opacity-0\"}`}\n >\n Copied to clipboard!\n </div>\n </div>\n </PowerhouseButton>\n </div>\n </div>\n {etherscanUrl && (\n <div className=\"px-3 py-2\">\n <a\n href={etherscanUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-sm text-gray-900 hover:text-gray-600 dark:text-slate-50 dark:hover:text-slate-300\"\n >\n <Icon name=\"Ethscan\" size={14} />\n View on Etherscan\n </a>\n </div>\n )}\n <div className=\"px-3 py-2\">\n <button\n onClick={onDisconnect}\n className={twMerge(\n \"flex w-full items-center gap-2 text-sm text-red-900 dark:text-red-400\",\n onDisconnect\n ? \"cursor-pointer hover:text-red-700 dark:hover:text-red-100\"\n : \"pointer-events-none cursor-wait\",\n )}\n type=\"button\"\n >\n <Icon name=\"Disconnect\" size={14} />\n Disconnect\n </button>\n </div>\n </div>\n );\n};\n","import { AccountPopoverUser } from \"../account-popover/account-popover-user.js\";\nimport { AccountPopover } from \"../account-popover/account-popover.js\";\nimport { ENSAvatar } from \"../ens-avatar/ens-avatar.js\";\n\nexport interface SidebarUserProps {\n address: `0x${string}`;\n ensName?: string;\n avatarUrl?: string;\n etherscanUrl: string;\n onDisconnect: (() => void) | undefined;\n}\n\nexport const SidebarUser: React.FC<SidebarUserProps> = ({\n address,\n ensName,\n avatarUrl,\n etherscanUrl,\n onDisconnect,\n}) => {\n const content = (\n <AccountPopoverUser\n address={address}\n username={ensName}\n onDisconnect={onDisconnect}\n etherscanUrl={etherscanUrl}\n />\n );\n\n return (\n <AccountPopover content={content}>\n <div className=\"flex items-center justify-center rounded-sm\">\n <ENSAvatar address={address} avatarUrl={avatarUrl} size=\"40px\" />\n </div>\n </AccountPopover>\n );\n};\n","import { Icon, SidebarFooter } from \"#design-system\";\nimport { Settings } from \"lucide-react\";\nimport type { ComponentProps } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { SidebarLogin } from \"./sidebar-login.js\";\nimport { SidebarUser } from \"./sidebar-user.js\";\nexport interface ConnectSidebarFooterProps extends ComponentProps<\n typeof SidebarFooter\n> {\n address: `0x${string}` | undefined;\n ensName?: string;\n avatarUrl?: string;\n onClickSettings: (() => void) | undefined;\n onLogin: (() => void) | undefined;\n etherscanUrl?: string;\n onDisconnect: (() => void) | undefined;\n onHomeClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n showDebug?: boolean;\n onDebugClick?: () => void;\n}\n\nexport const ConnectSidebarFooter: React.FC<ConnectSidebarFooterProps> = ({\n address,\n ensName,\n avatarUrl,\n className,\n onLogin,\n onClickSettings,\n onDisconnect,\n onHomeClick,\n showDebug,\n onDebugClick,\n etherscanUrl = \"\",\n ...props\n}) => {\n return (\n <SidebarFooter\n {...props}\n className={twMerge(\n \"flex flex-col items-center gap-3 border-t border-gray-300 px-2 py-4 dark:border-none dark:bg-slate-700 dark:text-slate-100\",\n className,\n )}\n >\n {onHomeClick && (\n <button\n aria-label=\"Home\"\n type=\"button\"\n className=\"cursor-pointer\"\n onClick={onHomeClick}\n >\n <Icon\n className=\"text-gray-700 dark:text-slate-200\"\n name=\"ConnectSmall\"\n size={24}\n />\n </button>\n )}\n {showDebug && onDebugClick && (\n <button\n aria-label=\"Debug Settings\"\n type=\"button\"\n id=\"connect-debug-button\"\n className=\"cursor-pointer\"\n onClick={onDebugClick}\n >\n <Icon className=\"text-gray-700 dark:text-slate-200\" name=\"Tube\" />\n </button>\n )}\n <div className={onHomeClick ? \"mt-3\" : \"\"}>\n {address ? (\n <SidebarUser\n address={address}\n ensName={ensName}\n avatarUrl={avatarUrl}\n onDisconnect={onDisconnect}\n etherscanUrl={etherscanUrl}\n />\n ) : (\n <SidebarLogin onLogin={onLogin} />\n )}\n </div>\n <button\n aria-label=\"Settings\"\n type=\"button\"\n className={twMerge(onClickSettings ? \"cursor-pointer\" : \"cursor-wait\")}\n onClick={onClickSettings}\n >\n <Settings\n className=\"text-gray-700 dark:text-slate-200\"\n size={24}\n strokeWidth={2}\n />\n <span className=\"hidden text-sm/6 font-semibold text-gray-900 dark:text-slate-100\">\n Settings\n </span>\n </button>\n </SidebarFooter>\n );\n};\n","import { SidebarHeader } from \"#design-system\";\nimport type { ComponentProps } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport interface ConnectSidebarHeaderProps extends ComponentProps<\n typeof SidebarHeader\n> {}\n\nexport const ConnectSidebarHeader: React.FC<ConnectSidebarHeaderProps> = ({\n className,\n children,\n ...props\n}) => {\n if (!children) {\n return null;\n }\n\n return (\n <SidebarHeader\n {...props}\n className={twMerge(\n \"flex justify-center gap-4 border-b border-gray-300 py-4 text-gray-500 dark:bg-slate-700 dark:text-slate-100\",\n className,\n )}\n >\n {children}\n </SidebarHeader>\n );\n};\n","import { Sidebar, SidebarPanel } from \"#design-system\";\nimport type { HTMLAttributes } from \"react\";\nimport type { ConnectSidebarFooterProps } from \"./sidebar-footer.js\";\nimport { ConnectSidebarFooter } from \"./sidebar-footer.js\";\nimport type { ConnectSidebarHeaderProps } from \"./sidebar-header.js\";\nimport { ConnectSidebarHeader } from \"./sidebar-header.js\";\n\nexport interface ConnectSidebarProps\n extends\n HTMLAttributes<HTMLElement>,\n ConnectSidebarHeaderProps,\n ConnectSidebarFooterProps {\n maxWidth?: string;\n minWidth?: string;\n headerContent?: React.ReactNode;\n loadingUser?: boolean;\n onLogin: (() => void) | undefined;\n onDisconnect: (() => void) | undefined;\n etherscanUrl?: string;\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n}\n\nexport const ConnectSidebar: React.FC<ConnectSidebarProps> = ({\n onClick,\n address,\n ensName,\n avatarUrl,\n headerContent,\n onClickSettings,\n maxWidth = \"304px\",\n minWidth = \"58px\",\n onLogin,\n onDisconnect,\n etherscanUrl,\n showDebug,\n onDebugClick,\n ...props\n}) => {\n return (\n <Sidebar {...props} maxWidth={maxWidth} minWidth={minWidth}>\n <SidebarPanel>\n <ConnectSidebarHeader>{headerContent}</ConnectSidebarHeader>\n <div className=\"flex flex-col\">{props.children}</div>\n </SidebarPanel>\n <ConnectSidebarFooter\n address={address}\n ensName={ensName}\n avatarUrl={avatarUrl}\n onClickSettings={onClickSettings}\n onLogin={onLogin}\n onDisconnect={onDisconnect}\n etherscanUrl={etherscanUrl}\n onHomeClick={onClick}\n showDebug={showDebug}\n onDebugClick={onDebugClick}\n />\n </Sidebar>\n );\n};\n","import { useTheme } from \"@powerhousedao/reactor-browser\";\nimport { Monitor, Moon, Sun } from \"lucide-react\";\nimport { twMerge } from \"tailwind-merge\";\n\ntype Theme = \"light\" | \"dark\" | \"system\";\n\nconst OPTIONS = [\n { value: \"light\", Icon: Sun, label: \"Light\" },\n { value: \"dark\", Icon: Moon, label: \"Dark\" },\n { value: \"system\", Icon: Monitor, label: \"System\" },\n] as const;\n\nexport function ThemeSwitch({ horizontal = false }: { horizontal?: boolean }) {\n const { theme, isSystem, setTheme } = useTheme();\n\n function select(val: Theme) {\n setTheme(val);\n }\n\n function isActive(value: Theme) {\n if (value === \"system\" && isSystem) return true;\n if (!isSystem && value === \"dark\" && theme === \"dark\") return true;\n if (!isSystem && value === \"light\" && theme === \"light\") return true;\n return false;\n }\n\n if (horizontal) {\n return (\n <div\n role=\"radiogroup\"\n aria-label=\"Theme\"\n className=\"flex h-9 items-center gap-x-0.5 pl-3\"\n >\n {OPTIONS.map(({ value, Icon, label }) => (\n <div\n key={value}\n role=\"radio\"\n aria-checked={isActive(value)}\n aria-label={label}\n tabIndex={0}\n onClick={() => select(value)}\n onKeyDown={(e) =>\n (e.key === \"Enter\" || e.key === \" \") && select(value)\n }\n className={twMerge(\n \"flex cursor-pointer items-center justify-center rounded-md p-1 transition-colors\",\n isActive(value)\n ? \"bg-gray-50 text-gray-700 dark:bg-slate-800 dark:text-slate-200\"\n : \"text-gray-400 hover:text-gray-600 dark:text-slate-500 dark:hover:text-slate-400\",\n )}\n >\n <Icon size={16} aria-hidden=\"true\" />\n </div>\n ))}\n </div>\n );\n }\n\n return (\n <div\n role=\"radiogroup\"\n aria-label=\"Theme\"\n className=\"flex w-fit flex-col items-center gap-4 rounded-xl\"\n >\n {OPTIONS.map(({ value, Icon, label }) => (\n <div\n key={value}\n role=\"radio\"\n aria-checked={isActive(value)}\n aria-label={label}\n tabIndex={0}\n onClick={() => select(value)}\n onKeyDown={(e) =>\n (e.key === \"Enter\" || e.key === \" \") && select(value)\n }\n className={twMerge(\n \"flex size-fit cursor-pointer content-center items-center transition-colors\",\n isActive(value)\n ? \"text-gray-900 dark:text-slate-50\"\n : \"text-gray-500 dark:text-slate-400\",\n )}\n >\n <Icon size={24} strokeWidth={2} aria-hidden=\"true\" />\n </div>\n ))}\n </div>\n );\n}\n","type SyncStatus =\n | \"INITIAL_SYNC\"\n | \"SYNCING\"\n | \"SUCCESS\"\n | \"CONFLICT\"\n | \"MISSING\"\n | \"ERROR\";\n\nexport type FileStatus = { path: string; status?: SyncStatus };\n\n/**\n * Retrieves the sync status of a folder based on its path and their children files.\n *\n * @param folderPath - The path of the folder.\n * @param sortedFiles - The sorted list of files.\n * @returns The sync status of the folder.\n */\nexport const getFolderStatus = (\n folderPath: string,\n sortedFiles: FileStatus[],\n): SyncStatus => {\n for (const file of sortedFiles) {\n if (file.path.startsWith(folderPath)) {\n return file.status || \"SUCCESS\";\n }\n }\n\n return \"SUCCESS\";\n};\n\n/**\n * Sorts an array of files by their status.\n * The order priority is:\n * - ERROR\n * - CONFLICT\n * - SYNCING\n * - MISSING\n * - SUCCESS\n *\n * @param files - The array of files to be sorted.\n * @returns The sorted array of files.\n */\nexport const sortFilesByStatus = (files: FileStatus[]) => {\n return files.sort((a, b) => {\n const statusOrder = [\n \"ERROR\",\n \"CONFLICT\",\n \"SYNCING\",\n \"MISSING\",\n \"SYNCING\",\n \"SUCCESS\",\n ];\n\n return (\n statusOrder.indexOf(a.status || \"SUCCESS\") -\n statusOrder.indexOf(b.status || \"SUCCESS\")\n );\n });\n};\n\n/**\n * Removes files with a status of 'SUCCESS' from the given array of FileStatus objects.\n * @param files - An array of FileStatus objects.\n * @returns A new array containing only the FileStatus objects with a status other than 'SUCCESS'.\n */\nexport const removeSuccessFiles = (files: FileStatus[]) => {\n return files.filter((file) => file.status !== \"SUCCESS\");\n};\n"],"mappings":"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"}
|