comfyui-frontend-package 1.38.5__py3-none-any.whl → 1.38.6__py3-none-any.whl
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.
- comfyui_frontend_package/static/assets/{AboutPanel-CHse5rOA.js → AboutPanel-lkjGFasi.js} +2 -2
- comfyui_frontend_package/static/assets/{AboutPanel-CHse5rOA.js.map → AboutPanel-lkjGFasi.js.map} +1 -1
- comfyui_frontend_package/static/assets/{AudioPreviewPlayer-CAa8V66L.js → AudioPreviewPlayer-BxCSKPl9.js} +2 -2
- comfyui_frontend_package/static/assets/{AudioPreviewPlayer-CAa8V66L.js.map → AudioPreviewPlayer-BxCSKPl9.js.map} +1 -1
- comfyui_frontend_package/static/assets/AudioPreviewPlayer-CkxKvcVf.js +1 -0
- comfyui_frontend_package/static/assets/{BaseViewTemplate-DA6zfigT.js → BaseViewTemplate-CjODF2hh.js} +2 -2
- comfyui_frontend_package/static/assets/{BaseViewTemplate-DA6zfigT.js.map → BaseViewTemplate-CjODF2hh.js.map} +1 -1
- comfyui_frontend_package/static/assets/{CloudAuthTimeoutView-9OPBS1hE.js → CloudAuthTimeoutView-D-QkjPNh.js} +2 -2
- comfyui_frontend_package/static/assets/{CloudAuthTimeoutView-9OPBS1hE.js.map → CloudAuthTimeoutView-D-QkjPNh.js.map} +1 -1
- comfyui_frontend_package/static/assets/{CloudBadge-BnLiAHDN.js → CloudBadge-B4nmLus2.js} +2 -2
- comfyui_frontend_package/static/assets/{CloudBadge-BnLiAHDN.js.map → CloudBadge-B4nmLus2.js.map} +1 -1
- comfyui_frontend_package/static/assets/{CloudForgotPasswordView-BqDR_C7K.js → CloudForgotPasswordView-DOEV9hGr.js} +2 -2
- comfyui_frontend_package/static/assets/{CloudForgotPasswordView-BqDR_C7K.js.map → CloudForgotPasswordView-DOEV9hGr.js.map} +1 -1
- comfyui_frontend_package/static/assets/{CloudLayoutView-vTrrVUOY.js → CloudLayoutView-ShKH6rRV.js} +2 -2
- comfyui_frontend_package/static/assets/{CloudLayoutView-vTrrVUOY.js.map → CloudLayoutView-ShKH6rRV.js.map} +1 -1
- comfyui_frontend_package/static/assets/{CloudLoginView-T17euJly.js → CloudLoginView-C3Te42U9.js} +2 -2
- comfyui_frontend_package/static/assets/{CloudLoginView-T17euJly.js.map → CloudLoginView-C3Te42U9.js.map} +1 -1
- comfyui_frontend_package/static/assets/CloudRunButtonWrapper-Cub7EB34.js +3 -0
- comfyui_frontend_package/static/assets/{CloudRunButtonWrapper-hQc4BNkX.js.map → CloudRunButtonWrapper-Cub7EB34.js.map} +1 -1
- comfyui_frontend_package/static/assets/{CloudSignupView-vEDby5k3.js → CloudSignupView-X2oiL3ZR.js} +2 -2
- comfyui_frontend_package/static/assets/{CloudSignupView-vEDby5k3.js.map → CloudSignupView-X2oiL3ZR.js.map} +1 -1
- comfyui_frontend_package/static/assets/{CloudSubscriptionRedirectView-DPyO745g.js → CloudSubscriptionRedirectView-UjNv8emo.js} +2 -2
- comfyui_frontend_package/static/assets/{CloudSubscriptionRedirectView-DPyO745g.js.map → CloudSubscriptionRedirectView-UjNv8emo.js.map} +1 -1
- comfyui_frontend_package/static/assets/{CloudSurveyView-CBtTd9Ru.js → CloudSurveyView-IaiucCTP.js} +2 -2
- comfyui_frontend_package/static/assets/{CloudSurveyView-CBtTd9Ru.js.map → CloudSurveyView-IaiucCTP.js.map} +1 -1
- comfyui_frontend_package/static/assets/ComfyQueueButton-BppnHbrl.js +1 -0
- comfyui_frontend_package/static/assets/{ComfyQueueButton-MZrp7wYJ.js → ComfyQueueButton-HjSIKZKO.js} +2 -2
- comfyui_frontend_package/static/assets/{ComfyQueueButton-MZrp7wYJ.js.map → ComfyQueueButton-HjSIKZKO.js.map} +1 -1
- comfyui_frontend_package/static/assets/{ExtensionPanel-CrWVGUtg.js → ExtensionPanel-Bzb9QtKj.js} +2 -2
- comfyui_frontend_package/static/assets/{ExtensionPanel-CrWVGUtg.js.map → ExtensionPanel-Bzb9QtKj.js.map} +1 -1
- comfyui_frontend_package/static/assets/{GlobalToast-BiCmpIvO.js → GlobalToast-BSCvu6Hw.js} +2 -2
- comfyui_frontend_package/static/assets/{GlobalToast-BiCmpIvO.js.map → GlobalToast-BSCvu6Hw.js.map} +1 -1
- comfyui_frontend_package/static/assets/{GraphView-BCkpNGgz.js → GraphView-gYVCtm1V.js} +5 -5
- comfyui_frontend_package/static/assets/GraphView-gYVCtm1V.js.map +1 -0
- comfyui_frontend_package/static/assets/{KeybindingPanel-CAXL5TlV.js → KeybindingPanel-DF-bG4iO.js} +2 -2
- comfyui_frontend_package/static/assets/{KeybindingPanel-CAXL5TlV.js.map → KeybindingPanel-DF-bG4iO.js.map} +1 -1
- comfyui_frontend_package/static/assets/{LegacyCreditsPanel-6vR8koQy.js → LegacyCreditsPanel-D-CboO8k.js} +2 -2
- comfyui_frontend_package/static/assets/{LegacyCreditsPanel-6vR8koQy.js.map → LegacyCreditsPanel-D-CboO8k.js.map} +1 -1
- comfyui_frontend_package/static/assets/Load3D-c9UwgGoI.js +1 -0
- comfyui_frontend_package/static/assets/{Load3D-ei1BUF9O.js → Load3D-vYr8M3jJ.js} +2 -2
- comfyui_frontend_package/static/assets/{Load3D-ei1BUF9O.js.map → Load3D-vYr8M3jJ.js.map} +1 -1
- comfyui_frontend_package/static/assets/{PanelTemplate-BjN5XNg2.js → PanelTemplate-BJda9e5J.js} +2 -2
- comfyui_frontend_package/static/assets/{PanelTemplate-BjN5XNg2.js.map → PanelTemplate-BJda9e5J.js.map} +1 -1
- comfyui_frontend_package/static/assets/{ServerConfigPanel-CxovH9Qk.js → ServerConfigPanel-VsC6xlZJ.js} +2 -2
- comfyui_frontend_package/static/assets/{ServerConfigPanel-CxovH9Qk.js.map → ServerConfigPanel-VsC6xlZJ.js.map} +1 -1
- comfyui_frontend_package/static/assets/{SubscribeButton-CTOQRkfg.js → SubscribeButton-DZBycfCA.js} +2 -2
- comfyui_frontend_package/static/assets/{SubscribeButton-CTOQRkfg.js.map → SubscribeButton-DZBycfCA.js.map} +1 -1
- comfyui_frontend_package/static/assets/{SubscribeToRun-DnXzV8y0.js → SubscribeToRun-4YolxBOL.js} +2 -2
- comfyui_frontend_package/static/assets/{SubscribeToRun-DnXzV8y0.js.map → SubscribeToRun-4YolxBOL.js.map} +1 -1
- comfyui_frontend_package/static/assets/{SubscriptionPanel-D9uv7z8f.js → SubscriptionPanel-B6txX4Vm.js} +2 -2
- comfyui_frontend_package/static/assets/{SubscriptionPanel-D9uv7z8f.js.map → SubscriptionPanel-B6txX4Vm.js.map} +1 -1
- comfyui_frontend_package/static/assets/{SubscriptionRequiredDialogContent--VmT16oc.js → SubscriptionRequiredDialogContent-COEF2VQ_.js} +2 -2
- comfyui_frontend_package/static/assets/{SubscriptionRequiredDialogContent--VmT16oc.js.map → SubscriptionRequiredDialogContent-COEF2VQ_.js.map} +1 -1
- comfyui_frontend_package/static/assets/{UserCheckView-spD3LyMu.js → UserCheckView-x-fkcYzc.js} +2 -2
- comfyui_frontend_package/static/assets/{UserCheckView-spD3LyMu.js.map → UserCheckView-x-fkcYzc.js.map} +1 -1
- comfyui_frontend_package/static/assets/{UserPanel-Su6NtJ5q.js → UserPanel-7N9QknQj.js} +2 -2
- comfyui_frontend_package/static/assets/{UserPanel-Su6NtJ5q.js.map → UserPanel-7N9QknQj.js.map} +1 -1
- comfyui_frontend_package/static/assets/{UserSelectView-C5LBOPcv.js → UserSelectView-BYjOkfSa.js} +2 -2
- comfyui_frontend_package/static/assets/{UserSelectView-C5LBOPcv.js.map → UserSelectView-BYjOkfSa.js.map} +1 -1
- comfyui_frontend_package/static/assets/{ValueControlPopover-BdlDzT8l.js → ValueControlPopover-BPAa35QG.js} +2 -2
- comfyui_frontend_package/static/assets/{ValueControlPopover-BdlDzT8l.js.map → ValueControlPopover-BPAa35QG.js.map} +1 -1
- comfyui_frontend_package/static/assets/{WidgetAudioUI-BDZxDx_r.js → WidgetAudioUI-Dw-r3Ews.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetAudioUI-BDZxDx_r.js.map → WidgetAudioUI-Dw-r3Ews.js.map} +1 -1
- comfyui_frontend_package/static/assets/{WidgetImageCrop-CYRW7t2Q.js → WidgetImageCrop-kERy9g5I.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetImageCrop-CYRW7t2Q.js.map → WidgetImageCrop-kERy9g5I.js.map} +1 -1
- comfyui_frontend_package/static/assets/{WidgetInputNumber-BOKO36G3.js → WidgetInputNumber-BaClCNAC.js} +1 -1
- comfyui_frontend_package/static/assets/WidgetInputNumber-DU_D0Fzy.js +3 -0
- comfyui_frontend_package/static/assets/WidgetInputNumber-DU_D0Fzy.js.map +1 -0
- comfyui_frontend_package/static/assets/{WidgetLegacy-Bslv9wZZ.js → WidgetLegacy-B4nipUM9.js} +1 -1
- comfyui_frontend_package/static/assets/{WidgetRecordAudio-Bzy8PIzN.js → WidgetRecordAudio-Nk8dH238.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetRecordAudio-Bzy8PIzN.js.map → WidgetRecordAudio-Nk8dH238.js.map} +1 -1
- comfyui_frontend_package/static/assets/WidgetSelect-DzZPpO_-.js +1 -0
- comfyui_frontend_package/static/assets/{WidgetSelect-zgrFVzHH.js → WidgetSelect-nSQrk_hd.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetSelect-zgrFVzHH.js.map → WidgetSelect-nSQrk_hd.js.map} +1 -1
- comfyui_frontend_package/static/assets/{WidgetWithControl-Dh2FWOiA.js → WidgetWithControl-Da6zUB5e.js} +3 -3
- comfyui_frontend_package/static/assets/{WidgetWithControl-Dh2FWOiA.js.map → WidgetWithControl-Da6zUB5e.js.map} +1 -1
- comfyui_frontend_package/static/assets/{api-CUAc7rDA.js → api-Dwq2LQIW.js} +4 -4
- comfyui_frontend_package/static/assets/api-Dwq2LQIW.js.map +1 -0
- comfyui_frontend_package/static/assets/{audioService-DvndbCi2.js → audioService-DvVaKhuU.js} +2 -2
- comfyui_frontend_package/static/assets/{audioService-DvndbCi2.js.map → audioService-DvVaKhuU.js.map} +1 -1
- comfyui_frontend_package/static/assets/{audioUtils-DpjpcKbH.js → audioUtils-DD4rUYVZ.js} +2 -2
- comfyui_frontend_package/static/assets/{audioUtils-DpjpcKbH.js.map → audioUtils-DD4rUYVZ.js.map} +1 -1
- comfyui_frontend_package/static/assets/{auth-B8ZZ0KKQ.js → auth-B9axG-yZ.js} +2 -2
- comfyui_frontend_package/static/assets/{auth-B8ZZ0KKQ.js.map → auth-B9axG-yZ.js.map} +1 -1
- comfyui_frontend_package/static/assets/auth-D74DTev8.js +1 -0
- comfyui_frontend_package/static/assets/{cloudBadges-C1a7fBky.js → cloudBadges-D5mGJbRy.js} +2 -2
- comfyui_frontend_package/static/assets/{cloudBadges-C1a7fBky.js.map → cloudBadges-D5mGJbRy.js.map} +1 -1
- comfyui_frontend_package/static/assets/{cloudFeedbackTopbarButton-DR0T8sWG.js → cloudFeedbackTopbarButton-RZUssOmb.js} +2 -2
- comfyui_frontend_package/static/assets/{cloudFeedbackTopbarButton-DR0T8sWG.js.map → cloudFeedbackTopbarButton-RZUssOmb.js.map} +1 -1
- comfyui_frontend_package/static/assets/{cloudRemoteConfig-DhMjC5TB.js → cloudRemoteConfig-F9J0iGyF.js} +2 -2
- comfyui_frontend_package/static/assets/{cloudRemoteConfig-DhMjC5TB.js.map → cloudRemoteConfig-F9J0iGyF.js.map} +1 -1
- comfyui_frontend_package/static/assets/{cloudSessionCookie-Duxk6ux1.js → cloudSessionCookie-MEORlqtg.js} +2 -2
- comfyui_frontend_package/static/assets/{cloudSessionCookie-Duxk6ux1.js.map → cloudSessionCookie-MEORlqtg.js.map} +1 -1
- comfyui_frontend_package/static/assets/{cloudSubscription-B8l6B9Nx.js → cloudSubscription-CuWNXKVx.js} +2 -2
- comfyui_frontend_package/static/assets/{cloudSubscription-B8l6B9Nx.js.map → cloudSubscription-CuWNXKVx.js.map} +1 -1
- comfyui_frontend_package/static/assets/{core-DBfeqMDR.js → core-IYu8XAIx.js} +4 -4
- comfyui_frontend_package/static/assets/{core-DBfeqMDR.js.map → core-IYu8XAIx.js.map} +1 -1
- comfyui_frontend_package/static/assets/{dialogService-BZ1FmjZL.js → dialogService-YG0RH337.js} +9 -9
- comfyui_frontend_package/static/assets/{dialogService-BZ1FmjZL.js.map → dialogService-YG0RH337.js.map} +1 -1
- comfyui_frontend_package/static/assets/firebaseAuthStore-DnNaPbuZ.js +1 -0
- comfyui_frontend_package/static/assets/{graphHasMissingNodes-C79Wi51S.js → graphHasMissingNodes-BhD1N6zI.js} +2 -2
- comfyui_frontend_package/static/assets/{graphHasMissingNodes-C79Wi51S.js.map → graphHasMissingNodes-BhD1N6zI.js.map} +1 -1
- comfyui_frontend_package/static/assets/{index-CGxJFSof.js → index-BMy3twho.js} +3 -3
- comfyui_frontend_package/static/assets/{index-CGxJFSof.js.map → index-BMy3twho.js.map} +1 -1
- comfyui_frontend_package/static/assets/{index-DNpOhRra.css → index-KMO9qFHH.css} +1 -1
- comfyui_frontend_package/static/assets/{keybindingService-B88NjeAU.js → keybindingService-CBLPjYHI.js} +2 -2
- comfyui_frontend_package/static/assets/{keybindingService-B88NjeAU.js.map → keybindingService-CBLPjYHI.js.map} +1 -1
- comfyui_frontend_package/static/assets/{releaseStore-x0vHjxrw.js → releaseStore-DDOxzkVb.js} +2 -2
- comfyui_frontend_package/static/assets/{releaseStore-x0vHjxrw.js.map → releaseStore-DDOxzkVb.js.map} +1 -1
- comfyui_frontend_package/static/assets/releaseStore-iVkqunL8.js +1 -0
- comfyui_frontend_package/static/assets/{subscriptionCheckoutUtil-B_OvUP2T.js → subscriptionCheckoutUtil-DswSOreM.js} +2 -2
- comfyui_frontend_package/static/assets/{subscriptionCheckoutUtil-B_OvUP2T.js.map → subscriptionCheckoutUtil-DswSOreM.js.map} +1 -1
- comfyui_frontend_package/static/assets/{useCurrentUser-BJcn2Vgo.js → useCurrentUser-NdaCJzIK.js} +1 -1
- comfyui_frontend_package/static/assets/{useErrorHandling-CI8_F4yx.js → useErrorHandling-Cfa5N_7c.js} +2 -2
- comfyui_frontend_package/static/assets/{useErrorHandling-CI8_F4yx.js.map → useErrorHandling-Cfa5N_7c.js.map} +1 -1
- comfyui_frontend_package/static/assets/{useSubscriptionDialog-Chxkdny5.js → useSubscriptionDialog-792qfEJ2.js} +3 -3
- comfyui_frontend_package/static/assets/{useSubscriptionDialog-Chxkdny5.js.map → useSubscriptionDialog-792qfEJ2.js.map} +1 -1
- comfyui_frontend_package/static/assets/useSubscriptionDialog-B-eGeK3j.js +1 -0
- comfyui_frontend_package/static/assets/{userStore-BkgQPjq6.js → userStore-BAS9m9W6.js} +2 -2
- comfyui_frontend_package/static/assets/{userStore-BkgQPjq6.js.map → userStore-BAS9m9W6.js.map} +1 -1
- comfyui_frontend_package/static/assets/vendor-three-BFcUNSs9.js.map +1 -1
- comfyui_frontend_package/static/index.html +1 -1
- {comfyui_frontend_package-1.38.5.dist-info → comfyui_frontend_package-1.38.6.dist-info}/METADATA +1 -1
- {comfyui_frontend_package-1.38.5.dist-info → comfyui_frontend_package-1.38.6.dist-info}/RECORD +126 -126
- comfyui_frontend_package/static/assets/AudioPreviewPlayer-BoEdyGI_.js +0 -1
- comfyui_frontend_package/static/assets/CloudRunButtonWrapper-hQc4BNkX.js +0 -3
- comfyui_frontend_package/static/assets/ComfyQueueButton-BbQnRThI.js +0 -1
- comfyui_frontend_package/static/assets/GraphView-BCkpNGgz.js.map +0 -1
- comfyui_frontend_package/static/assets/Load3D-DHBmC_AU.js +0 -1
- comfyui_frontend_package/static/assets/WidgetInputNumber-DGKypM5j.js +0 -3
- comfyui_frontend_package/static/assets/WidgetInputNumber-DGKypM5j.js.map +0 -1
- comfyui_frontend_package/static/assets/WidgetSelect-DsJGH12l.js +0 -1
- comfyui_frontend_package/static/assets/api-CUAc7rDA.js.map +0 -1
- comfyui_frontend_package/static/assets/auth-D3RiiqZ8.js +0 -1
- comfyui_frontend_package/static/assets/firebaseAuthStore-CZgxeMyf.js +0 -1
- comfyui_frontend_package/static/assets/releaseStore-CubqSv5t.js +0 -1
- comfyui_frontend_package/static/assets/useSubscriptionDialog-BzMzio2H.js +0 -1
- {comfyui_frontend_package-1.38.5.dist-info → comfyui_frontend_package-1.38.6.dist-info}/WHEEL +0 -0
- {comfyui_frontend_package-1.38.5.dist-info → comfyui_frontend_package-1.38.6.dist-info}/top_level.txt +0 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var p=Object.defineProperty;var n=(t,c)=>p(t,"name",{value:c,configurable:!0});import{Ar as i,Or as k,P as C,Xn as I,jr as S,kr as K,yr as h}from"./dialogService-
|
|
1
|
+
var p=Object.defineProperty;var n=(t,c)=>p(t,"name",{value:c,configurable:!0});import{Ar as i,Or as k,P as C,Xn as I,jr as S,kr as K,yr as h}from"./dialogService-YG0RH337.js";const E=[{combo:{ctrl:!0,key:"Enter"},commandId:"Comfy.QueuePrompt"},{combo:{ctrl:!0,shift:!0,key:"Enter"},commandId:"Comfy.QueuePromptFront"},{combo:{ctrl:!0,alt:!0,key:"Enter"},commandId:"Comfy.Interrupt"},{combo:{key:"r"},commandId:"Comfy.RefreshNodeDefinitions"},{combo:{key:"w"},commandId:"Workspace.ToggleSidebarTab.workflows"},{combo:{key:"n"},commandId:"Workspace.ToggleSidebarTab.node-library"},{combo:{key:"m"},commandId:"Workspace.ToggleSidebarTab.model-library"},{combo:{key:"s",ctrl:!0},commandId:"Comfy.SaveWorkflow"},{combo:{key:"o",ctrl:!0},commandId:"Comfy.OpenWorkflow"},{combo:{key:"g",ctrl:!0},commandId:"Comfy.Graph.GroupSelectedNodes"},{combo:{key:",",ctrl:!0},commandId:"Comfy.ShowSettingsDialog"},{combo:{key:"=",alt:!0},commandId:"Comfy.Canvas.ZoomIn",targetElementId:"graph-canvas"},{combo:{key:"+",alt:!0,shift:!0},commandId:"Comfy.Canvas.ZoomIn",targetElementId:"graph-canvas"},{combo:{key:"+",alt:!0},commandId:"Comfy.Canvas.ZoomIn",targetElementId:"graph-canvas"},{combo:{key:"-",alt:!0},commandId:"Comfy.Canvas.ZoomOut",targetElementId:"graph-canvas"},{combo:{key:"."},commandId:"Comfy.Canvas.FitView",targetElementId:"graph-canvas-container"},{combo:{key:"p"},commandId:"Comfy.Canvas.ToggleSelected.Pin",targetElementId:"graph-canvas-container"},{combo:{key:"c",alt:!0},commandId:"Comfy.Canvas.ToggleSelectedNodes.Collapse",targetElementId:"graph-canvas-container"},{combo:{key:"b",ctrl:!0},commandId:"Comfy.Canvas.ToggleSelectedNodes.Bypass",targetElementId:"graph-canvas-container"},{combo:{key:"m",ctrl:!0},commandId:"Comfy.Canvas.ToggleSelectedNodes.Mute",targetElementId:"graph-canvas-container"},{combo:{key:"`",ctrl:!0},commandId:"Workspace.ToggleBottomPanelTab.logs-terminal"},{combo:{key:"e",ctrl:!0,shift:!0},commandId:"Comfy.Graph.ConvertToSubgraph"},{combo:{key:"m",alt:!0},commandId:"Comfy.Canvas.ToggleMinimap"},{combo:{ctrl:!0,shift:!0,key:"k"},commandId:"Workspace.ToggleBottomPanel.Shortcuts"},{combo:{key:"v"},commandId:"Comfy.Canvas.Unlock"},{combo:{key:"h"},commandId:"Comfy.Canvas.Lock"},{combo:{key:"Escape"},commandId:"Comfy.Graph.ExitSubgraph"}],T=n(()=>{const t=S(),c=k(),d=h(),y=I(),l=n(e=>e.ctrlKey||e.altKey||e.metaKey?!1:["Delete","Backspace"].includes(e.key),"shouldForwardToCanvas"),g=n(async function(e){const m=K.fromEvent(e);if(m.isModifier)return;const o=e.composedPath()[0];if(m.isReservedByTextInput&&(o.tagName==="TEXTAREA"||o.tagName==="INPUT"||o.contentEditable==="true"||o.tagName==="SPAN"&&o.classList.contains("property_value")))return;const a=t.getKeybinding(m);if(a&&a.targetElementId!=="graph-canvas"){if(e.key==="Escape"&&!e.ctrlKey&&!e.altKey&&!e.metaKey&&y.dialogStack.length>0)return;e.preventDefault(),new Set(["Comfy.QueuePrompt","Comfy.QueuePromptFront","Comfy.QueueSelectedOutputNodes"]).has(a.commandId)?await c.execute(a.commandId,{metadata:{trigger_source:"keybinding"}}):await c.execute(a.commandId);return}if(!a&&l(e)){const r=C.canvas;if(r&&r.processKey&&typeof r.processKey=="function"){r.processKey(e);return}}if(!(e.ctrlKey||e.altKey||e.metaKey)&&e.key==="Escape"){const r=document.querySelectorAll(".comfy-modal");for(const s of r)if(window.getComputedStyle(s).getPropertyValue("display")!=="none"){s.style.display="none";break}for(const s of document.querySelectorAll("dialog"))s.close()}},"keybindHandler"),u=n(()=>{for(const e of E)t.addDefaultKeybinding(new i(e))},"registerCoreKeybindings");function f(){const e=d.get("Comfy.Keybinding.UnsetBindings");for(const o of e)t.unsetKeybinding(new i(o));const m=d.get("Comfy.Keybinding.NewBindings");for(const o of m)t.addUserKeybinding(new i(o))}n(f,"registerUserKeybindings");async function b(){await d.set("Comfy.Keybinding.NewBindings",Object.values(t.getUserKeybindings())),await d.set("Comfy.Keybinding.UnsetBindings",Object.values(t.getUserUnsetKeybindings()))}return n(b,"persistUserKeybindings"),{keybindHandler:g,registerCoreKeybindings:u,registerUserKeybindings:f,persistUserKeybindings:b}},"useKeybindingService");export{T as t};
|
|
2
2
|
|
|
3
|
-
//# sourceMappingURL=keybindingService-
|
|
3
|
+
//# sourceMappingURL=keybindingService-CBLPjYHI.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keybindingService-B88NjeAU.js","names":[],"sources":["../../src/constants/coreKeybindings.ts","../../src/services/keybindingService.ts"],"sourcesContent":["import type { Keybinding } from '@/schemas/keyBindingSchema'\n\nexport const CORE_KEYBINDINGS: Keybinding[] = [\n {\n combo: {\n ctrl: true,\n key: 'Enter'\n },\n commandId: 'Comfy.QueuePrompt'\n },\n {\n combo: {\n ctrl: true,\n shift: true,\n key: 'Enter'\n },\n commandId: 'Comfy.QueuePromptFront'\n },\n {\n combo: {\n ctrl: true,\n alt: true,\n key: 'Enter'\n },\n commandId: 'Comfy.Interrupt'\n },\n {\n combo: {\n key: 'r'\n },\n commandId: 'Comfy.RefreshNodeDefinitions'\n },\n {\n combo: {\n key: 'w'\n },\n commandId: 'Workspace.ToggleSidebarTab.workflows'\n },\n {\n combo: {\n key: 'n'\n },\n commandId: 'Workspace.ToggleSidebarTab.node-library'\n },\n {\n combo: {\n key: 'm'\n },\n commandId: 'Workspace.ToggleSidebarTab.model-library'\n },\n {\n combo: {\n key: 's',\n ctrl: true\n },\n commandId: 'Comfy.SaveWorkflow'\n },\n {\n combo: {\n key: 'o',\n ctrl: true\n },\n commandId: 'Comfy.OpenWorkflow'\n },\n {\n combo: {\n key: 'g',\n ctrl: true\n },\n commandId: 'Comfy.Graph.GroupSelectedNodes'\n },\n {\n combo: {\n key: ',',\n ctrl: true\n },\n commandId: 'Comfy.ShowSettingsDialog'\n },\n // For '=' both holding shift and not holding shift\n {\n combo: {\n key: '=',\n alt: true\n },\n commandId: 'Comfy.Canvas.ZoomIn',\n targetElementId: 'graph-canvas'\n },\n {\n combo: {\n key: '+',\n alt: true,\n shift: true\n },\n commandId: 'Comfy.Canvas.ZoomIn',\n targetElementId: 'graph-canvas'\n },\n // For number pad '+'\n {\n combo: {\n key: '+',\n alt: true\n },\n commandId: 'Comfy.Canvas.ZoomIn',\n targetElementId: 'graph-canvas'\n },\n {\n combo: {\n key: '-',\n alt: true\n },\n commandId: 'Comfy.Canvas.ZoomOut',\n targetElementId: 'graph-canvas'\n },\n {\n combo: {\n key: '.'\n },\n commandId: 'Comfy.Canvas.FitView',\n targetElementId: 'graph-canvas-container'\n },\n {\n combo: {\n key: 'p'\n },\n commandId: 'Comfy.Canvas.ToggleSelected.Pin',\n targetElementId: 'graph-canvas-container'\n },\n {\n combo: {\n key: 'c',\n alt: true\n },\n commandId: 'Comfy.Canvas.ToggleSelectedNodes.Collapse',\n targetElementId: 'graph-canvas-container'\n },\n {\n combo: {\n key: 'b',\n ctrl: true\n },\n commandId: 'Comfy.Canvas.ToggleSelectedNodes.Bypass',\n targetElementId: 'graph-canvas-container'\n },\n {\n combo: {\n key: 'm',\n ctrl: true\n },\n commandId: 'Comfy.Canvas.ToggleSelectedNodes.Mute',\n targetElementId: 'graph-canvas-container'\n },\n {\n combo: {\n key: '`',\n ctrl: true\n },\n commandId: 'Workspace.ToggleBottomPanelTab.logs-terminal'\n },\n {\n combo: {\n key: 'e',\n ctrl: true,\n shift: true\n },\n commandId: 'Comfy.Graph.ConvertToSubgraph'\n },\n {\n combo: {\n key: 'm',\n alt: true\n },\n commandId: 'Comfy.Canvas.ToggleMinimap'\n },\n {\n combo: {\n ctrl: true,\n shift: true,\n key: 'k'\n },\n commandId: 'Workspace.ToggleBottomPanel.Shortcuts'\n },\n {\n combo: {\n key: 'v'\n },\n commandId: 'Comfy.Canvas.Unlock'\n },\n {\n combo: {\n key: 'h'\n },\n commandId: 'Comfy.Canvas.Lock'\n },\n {\n combo: {\n key: 'Escape'\n },\n commandId: 'Comfy.Graph.ExitSubgraph'\n }\n]\n","import { CORE_KEYBINDINGS } from '@/constants/coreKeybindings'\nimport { useSettingStore } from '@/platform/settings/settingStore'\nimport { app } from '@/scripts/app'\nimport { useCommandStore } from '@/stores/commandStore'\nimport { useDialogStore } from '@/stores/dialogStore'\nimport {\n KeyComboImpl,\n KeybindingImpl,\n useKeybindingStore\n} from '@/stores/keybindingStore'\n\nexport const useKeybindingService = () => {\n const keybindingStore = useKeybindingStore()\n const commandStore = useCommandStore()\n const settingStore = useSettingStore()\n const dialogStore = useDialogStore()\n\n // Helper function to determine if an event should be forwarded to canvas\n const shouldForwardToCanvas = (event: KeyboardEvent): boolean => {\n // Don't forward if modifier keys are pressed (except shift)\n if (event.ctrlKey || event.altKey || event.metaKey) {\n return false\n }\n\n // Keys that LiteGraph handles but aren't in core keybindings\n const canvasKeys = ['Delete', 'Backspace']\n\n return canvasKeys.includes(event.key)\n }\n\n const keybindHandler = async function (event: KeyboardEvent) {\n const keyCombo = KeyComboImpl.fromEvent(event)\n if (keyCombo.isModifier) {\n return\n }\n\n // Ignore reserved or non-modifier keybindings if typing in input fields\n const target = event.composedPath()[0] as HTMLElement\n if (\n keyCombo.isReservedByTextInput &&\n (target.tagName === 'TEXTAREA' ||\n target.tagName === 'INPUT' ||\n target.contentEditable === 'true' ||\n (target.tagName === 'SPAN' &&\n target.classList.contains('property_value')))\n ) {\n return\n }\n\n const keybinding = keybindingStore.getKeybinding(keyCombo)\n if (keybinding && keybinding.targetElementId !== 'graph-canvas') {\n // Special handling for Escape key - let dialogs handle it first\n if (\n event.key === 'Escape' &&\n !event.ctrlKey &&\n !event.altKey &&\n !event.metaKey\n ) {\n // If dialogs are open, don't execute the keybinding - let the dialog handle it\n if (dialogStore.dialogStack.length > 0) {\n return\n }\n }\n\n // Prevent default browser behavior first, then execute the command\n event.preventDefault()\n const runCommandIds = new Set([\n 'Comfy.QueuePrompt',\n 'Comfy.QueuePromptFront',\n 'Comfy.QueueSelectedOutputNodes'\n ])\n if (runCommandIds.has(keybinding.commandId)) {\n await commandStore.execute(keybinding.commandId, {\n metadata: {\n trigger_source: 'keybinding'\n }\n })\n } else {\n await commandStore.execute(keybinding.commandId)\n }\n return\n }\n\n // Forward unhandled canvas-targeted events to LiteGraph\n if (!keybinding && shouldForwardToCanvas(event)) {\n const canvas = app.canvas\n if (\n canvas &&\n canvas.processKey &&\n typeof canvas.processKey === 'function'\n ) {\n // Let LiteGraph handle the event\n canvas.processKey(event)\n return\n }\n }\n\n // Only clear dialogs if not using modifiers\n if (event.ctrlKey || event.altKey || event.metaKey) {\n return\n }\n\n // Escape key: close the first open modal found, and all dialogs\n if (event.key === 'Escape') {\n const modals = document.querySelectorAll<HTMLElement>('.comfy-modal')\n for (const modal of modals) {\n const modalDisplay = window\n .getComputedStyle(modal)\n .getPropertyValue('display')\n\n if (modalDisplay !== 'none') {\n modal.style.display = 'none'\n break\n }\n }\n\n for (const d of document.querySelectorAll('dialog')) d.close()\n }\n }\n\n const registerCoreKeybindings = () => {\n for (const keybinding of CORE_KEYBINDINGS) {\n keybindingStore.addDefaultKeybinding(new KeybindingImpl(keybinding))\n }\n }\n\n function registerUserKeybindings() {\n // Unset bindings first as new bindings might conflict with default bindings.\n const unsetBindings = settingStore.get('Comfy.Keybinding.UnsetBindings')\n for (const keybinding of unsetBindings) {\n keybindingStore.unsetKeybinding(new KeybindingImpl(keybinding))\n }\n const newBindings = settingStore.get('Comfy.Keybinding.NewBindings')\n for (const keybinding of newBindings) {\n keybindingStore.addUserKeybinding(new KeybindingImpl(keybinding))\n }\n }\n\n async function persistUserKeybindings() {\n // TODO(https://github.com/Comfy-Org/ComfyUI_frontend/issues/1079):\n // Allow setting multiple values at once in settingStore\n await settingStore.set(\n 'Comfy.Keybinding.NewBindings',\n Object.values(keybindingStore.getUserKeybindings())\n )\n await settingStore.set(\n 'Comfy.Keybinding.UnsetBindings',\n Object.values(keybindingStore.getUserUnsetKeybindings())\n )\n }\n\n return {\n keybindHandler,\n registerCoreKeybindings,\n registerUserKeybindings,\n persistUserKeybindings\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"keybindingService-CBLPjYHI.js","names":[],"sources":["../../src/constants/coreKeybindings.ts","../../src/services/keybindingService.ts"],"sourcesContent":["import type { Keybinding } from '@/schemas/keyBindingSchema'\n\nexport const CORE_KEYBINDINGS: Keybinding[] = [\n {\n combo: {\n ctrl: true,\n key: 'Enter'\n },\n commandId: 'Comfy.QueuePrompt'\n },\n {\n combo: {\n ctrl: true,\n shift: true,\n key: 'Enter'\n },\n commandId: 'Comfy.QueuePromptFront'\n },\n {\n combo: {\n ctrl: true,\n alt: true,\n key: 'Enter'\n },\n commandId: 'Comfy.Interrupt'\n },\n {\n combo: {\n key: 'r'\n },\n commandId: 'Comfy.RefreshNodeDefinitions'\n },\n {\n combo: {\n key: 'w'\n },\n commandId: 'Workspace.ToggleSidebarTab.workflows'\n },\n {\n combo: {\n key: 'n'\n },\n commandId: 'Workspace.ToggleSidebarTab.node-library'\n },\n {\n combo: {\n key: 'm'\n },\n commandId: 'Workspace.ToggleSidebarTab.model-library'\n },\n {\n combo: {\n key: 's',\n ctrl: true\n },\n commandId: 'Comfy.SaveWorkflow'\n },\n {\n combo: {\n key: 'o',\n ctrl: true\n },\n commandId: 'Comfy.OpenWorkflow'\n },\n {\n combo: {\n key: 'g',\n ctrl: true\n },\n commandId: 'Comfy.Graph.GroupSelectedNodes'\n },\n {\n combo: {\n key: ',',\n ctrl: true\n },\n commandId: 'Comfy.ShowSettingsDialog'\n },\n // For '=' both holding shift and not holding shift\n {\n combo: {\n key: '=',\n alt: true\n },\n commandId: 'Comfy.Canvas.ZoomIn',\n targetElementId: 'graph-canvas'\n },\n {\n combo: {\n key: '+',\n alt: true,\n shift: true\n },\n commandId: 'Comfy.Canvas.ZoomIn',\n targetElementId: 'graph-canvas'\n },\n // For number pad '+'\n {\n combo: {\n key: '+',\n alt: true\n },\n commandId: 'Comfy.Canvas.ZoomIn',\n targetElementId: 'graph-canvas'\n },\n {\n combo: {\n key: '-',\n alt: true\n },\n commandId: 'Comfy.Canvas.ZoomOut',\n targetElementId: 'graph-canvas'\n },\n {\n combo: {\n key: '.'\n },\n commandId: 'Comfy.Canvas.FitView',\n targetElementId: 'graph-canvas-container'\n },\n {\n combo: {\n key: 'p'\n },\n commandId: 'Comfy.Canvas.ToggleSelected.Pin',\n targetElementId: 'graph-canvas-container'\n },\n {\n combo: {\n key: 'c',\n alt: true\n },\n commandId: 'Comfy.Canvas.ToggleSelectedNodes.Collapse',\n targetElementId: 'graph-canvas-container'\n },\n {\n combo: {\n key: 'b',\n ctrl: true\n },\n commandId: 'Comfy.Canvas.ToggleSelectedNodes.Bypass',\n targetElementId: 'graph-canvas-container'\n },\n {\n combo: {\n key: 'm',\n ctrl: true\n },\n commandId: 'Comfy.Canvas.ToggleSelectedNodes.Mute',\n targetElementId: 'graph-canvas-container'\n },\n {\n combo: {\n key: '`',\n ctrl: true\n },\n commandId: 'Workspace.ToggleBottomPanelTab.logs-terminal'\n },\n {\n combo: {\n key: 'e',\n ctrl: true,\n shift: true\n },\n commandId: 'Comfy.Graph.ConvertToSubgraph'\n },\n {\n combo: {\n key: 'm',\n alt: true\n },\n commandId: 'Comfy.Canvas.ToggleMinimap'\n },\n {\n combo: {\n ctrl: true,\n shift: true,\n key: 'k'\n },\n commandId: 'Workspace.ToggleBottomPanel.Shortcuts'\n },\n {\n combo: {\n key: 'v'\n },\n commandId: 'Comfy.Canvas.Unlock'\n },\n {\n combo: {\n key: 'h'\n },\n commandId: 'Comfy.Canvas.Lock'\n },\n {\n combo: {\n key: 'Escape'\n },\n commandId: 'Comfy.Graph.ExitSubgraph'\n }\n]\n","import { CORE_KEYBINDINGS } from '@/constants/coreKeybindings'\nimport { useSettingStore } from '@/platform/settings/settingStore'\nimport { app } from '@/scripts/app'\nimport { useCommandStore } from '@/stores/commandStore'\nimport { useDialogStore } from '@/stores/dialogStore'\nimport {\n KeyComboImpl,\n KeybindingImpl,\n useKeybindingStore\n} from '@/stores/keybindingStore'\n\nexport const useKeybindingService = () => {\n const keybindingStore = useKeybindingStore()\n const commandStore = useCommandStore()\n const settingStore = useSettingStore()\n const dialogStore = useDialogStore()\n\n // Helper function to determine if an event should be forwarded to canvas\n const shouldForwardToCanvas = (event: KeyboardEvent): boolean => {\n // Don't forward if modifier keys are pressed (except shift)\n if (event.ctrlKey || event.altKey || event.metaKey) {\n return false\n }\n\n // Keys that LiteGraph handles but aren't in core keybindings\n const canvasKeys = ['Delete', 'Backspace']\n\n return canvasKeys.includes(event.key)\n }\n\n const keybindHandler = async function (event: KeyboardEvent) {\n const keyCombo = KeyComboImpl.fromEvent(event)\n if (keyCombo.isModifier) {\n return\n }\n\n // Ignore reserved or non-modifier keybindings if typing in input fields\n const target = event.composedPath()[0] as HTMLElement\n if (\n keyCombo.isReservedByTextInput &&\n (target.tagName === 'TEXTAREA' ||\n target.tagName === 'INPUT' ||\n target.contentEditable === 'true' ||\n (target.tagName === 'SPAN' &&\n target.classList.contains('property_value')))\n ) {\n return\n }\n\n const keybinding = keybindingStore.getKeybinding(keyCombo)\n if (keybinding && keybinding.targetElementId !== 'graph-canvas') {\n // Special handling for Escape key - let dialogs handle it first\n if (\n event.key === 'Escape' &&\n !event.ctrlKey &&\n !event.altKey &&\n !event.metaKey\n ) {\n // If dialogs are open, don't execute the keybinding - let the dialog handle it\n if (dialogStore.dialogStack.length > 0) {\n return\n }\n }\n\n // Prevent default browser behavior first, then execute the command\n event.preventDefault()\n const runCommandIds = new Set([\n 'Comfy.QueuePrompt',\n 'Comfy.QueuePromptFront',\n 'Comfy.QueueSelectedOutputNodes'\n ])\n if (runCommandIds.has(keybinding.commandId)) {\n await commandStore.execute(keybinding.commandId, {\n metadata: {\n trigger_source: 'keybinding'\n }\n })\n } else {\n await commandStore.execute(keybinding.commandId)\n }\n return\n }\n\n // Forward unhandled canvas-targeted events to LiteGraph\n if (!keybinding && shouldForwardToCanvas(event)) {\n const canvas = app.canvas\n if (\n canvas &&\n canvas.processKey &&\n typeof canvas.processKey === 'function'\n ) {\n // Let LiteGraph handle the event\n canvas.processKey(event)\n return\n }\n }\n\n // Only clear dialogs if not using modifiers\n if (event.ctrlKey || event.altKey || event.metaKey) {\n return\n }\n\n // Escape key: close the first open modal found, and all dialogs\n if (event.key === 'Escape') {\n const modals = document.querySelectorAll<HTMLElement>('.comfy-modal')\n for (const modal of modals) {\n const modalDisplay = window\n .getComputedStyle(modal)\n .getPropertyValue('display')\n\n if (modalDisplay !== 'none') {\n modal.style.display = 'none'\n break\n }\n }\n\n for (const d of document.querySelectorAll('dialog')) d.close()\n }\n }\n\n const registerCoreKeybindings = () => {\n for (const keybinding of CORE_KEYBINDINGS) {\n keybindingStore.addDefaultKeybinding(new KeybindingImpl(keybinding))\n }\n }\n\n function registerUserKeybindings() {\n // Unset bindings first as new bindings might conflict with default bindings.\n const unsetBindings = settingStore.get('Comfy.Keybinding.UnsetBindings')\n for (const keybinding of unsetBindings) {\n keybindingStore.unsetKeybinding(new KeybindingImpl(keybinding))\n }\n const newBindings = settingStore.get('Comfy.Keybinding.NewBindings')\n for (const keybinding of newBindings) {\n keybindingStore.addUserKeybinding(new KeybindingImpl(keybinding))\n }\n }\n\n async function persistUserKeybindings() {\n // TODO(https://github.com/Comfy-Org/ComfyUI_frontend/issues/1079):\n // Allow setting multiple values at once in settingStore\n await settingStore.set(\n 'Comfy.Keybinding.NewBindings',\n Object.values(keybindingStore.getUserKeybindings())\n )\n await settingStore.set(\n 'Comfy.Keybinding.UnsetBindings',\n Object.values(keybindingStore.getUserUnsetKeybindings())\n )\n }\n\n return {\n keybindHandler,\n registerCoreKeybindings,\n registerUserKeybindings,\n persistUserKeybindings\n }\n}\n"],"mappings":"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"}
|
comfyui_frontend_package/static/assets/{releaseStore-x0vHjxrw.js → releaseStore-DDOxzkVb.js}
RENAMED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var I=Object.defineProperty;var o=(l,u)=>I(l,"name",{value:u,configurable:!0});import{Ji as N,di as _,en as j,wo as H,za as a,zo as g}from"./vendor-other-DlQF6V2E.js";import{p as x}from"./vendor-vue-D9IUuwPJ.js";import{Bt as R,Lt as d,nt as M}from"./api-
|
|
1
|
+
var I=Object.defineProperty;var o=(l,u)=>I(l,"name",{value:u,configurable:!0});import{Ji as N,di as _,en as j,wo as H,za as a,zo as g}from"./vendor-other-DlQF6V2E.js";import{p as x}from"./vendor-vue-D9IUuwPJ.js";import{Bt as R,Lt as d,nt as M}from"./api-Dwq2LQIW.js";import{O,T as J}from"./PanelTemplate-BJda9e5J.js";import{Hr as $,yr as P}from"./dialogService-YG0RH337.js";var U=_.create({baseURL:$(),headers:{"Content-Type":"application/json"}});const W=o(()=>{const l=g(!1),u=g(null);H(()=>$(),e=>{U.defaults.baseURL=e});const m=o((e,t,i)=>{if(!_.isAxiosError(e))return e instanceof Error?`${t}: ${e.message}`:`${t}: Unknown error occurred`;const n=e;if(n.response){const{status:c,data:f}=n.response;if(i&&i[c])return i[c];switch(c){case 400:return`Bad request: ${f?.message||"Invalid input"}`;case 401:return"Unauthorized: Authentication required";case 403:return`Forbidden: ${f?.message||"Access denied"}`;case 404:return`Not found: ${f?.message||"Resource not found"}`;case 500:return`Server error: ${f?.message||"Internal server error"}`;default:return`${t}: ${f?.message||n.message}`}}return`${t}: ${n.message}`},"handleApiError"),p=o(async(e,t,i)=>{l.value=!0,u.value=null;try{return(await e()).data}catch(n){return M(n)||(u.value=m(n,t,i)),null}finally{l.value=!1}},"executeApiRequest");return{isLoading:l,error:u,getReleases:o(async(e,t)=>{const i="/releases";return await p(()=>U.get(i,{params:e,signal:t}),"Failed to get releases",{400:"Invalid project or version parameter"})},"getReleases")}},"useReleaseService");var h=j();const ee=x("release",()=>{const l=g([]),u=g(!1),m=g(null),p=W(),v=O(),e=P(),t=a(()=>d?v?.systemStats?.system?.cloud_version??"":v?.systemStats?.system?.comfyui_version??""),i=a(()=>e.get("Comfy.Locale")),n=a(()=>e.get("Comfy.Release.Version")),c=a(()=>e.get("Comfy.Release.Status")),f=a(()=>e.get("Comfy.Release.Timestamp")),y=a(()=>e.get("Comfy.Notification.ShowVersionUpdates")),r=a(()=>l.value[0]??null),L=a(()=>l.value.slice(0,3)),E=4320*60*1e3,C=o((s,S)=>(0,h.valid)(s)&&(0,h.valid)(S)?(0,h.compare)(s,S):s===S?0:1,"compareVersions"),w=a(()=>!!r.value&&C(r.value.version,t.value||"0.0.0")>0),V=a(()=>!!r.value&&C(r.value.version,t.value||"0.0.0")===0),A=a(()=>{const s=r.value?.attention;return s==="medium"||s==="high"}),b=a(()=>!(!R()||d||!y.value||!w.value||!A.value||n.value===r.value?.version&&["skipped","changelog seen"].includes(c.value))),k=a(()=>{if(!R()||d||!y.value||!w.value)return!1;const{version:s}=r.value;return n.value===s&&c.value==="changelog seen"?!1:A.value?!0:!(n.value===s&&c.value==="skipped"&&f.value&&Date.now()-f.value>=E)}),D=a(()=>!(!R()&&!d||!y.value||!r.value||(0,h.valid)(t.value)&&!V.value||n.value===r.value.version&&c.value==="what's new seen"));async function z(s){s!==r.value?.version||c.value==="changelog seen"||(await e.set("Comfy.Release.Version",s),await e.set("Comfy.Release.Status","skipped"),await e.set("Comfy.Release.Timestamp",Date.now()))}o(z,"handleSkipRelease");async function q(s){s===r.value?.version&&(await e.set("Comfy.Release.Version",s),await e.set("Comfy.Release.Status","changelog seen"),await e.set("Comfy.Release.Timestamp",Date.now()))}o(q,"handleShowChangelog");async function B(s){s===r.value?.version&&(await e.set("Comfy.Release.Version",s),await e.set("Comfy.Release.Status","what's new seen"),await e.set("Comfy.Release.Timestamp",Date.now()))}o(B,"handleWhatsNewSeen");async function T(){if(!u.value&&!(!d&&!y.value)&&!v.systemStats?.system?.argv?.includes("--disable-api-nodes")){u.value=!0,m.value=null;try{v.systemStats||await N(v.isInitialized);const s=await p.getReleases({project:d?"cloud":"comfyui",current_version:t.value,form_factor:v.getFormFactor(),locale:J(i.value)});s!==null?l.value=s:p.error.value&&(m.value=p.error.value)}catch(s){m.value=s instanceof Error?s.message:"Unknown error occurred"}finally{u.value=!1}}}o(T,"fetchReleases");async function F(){await T()}return o(F,"initialize"),{releases:l,isLoading:u,error:m,recentRelease:r,recentReleases:L,shouldShowToast:b,shouldShowRedDot:k,shouldShowPopup:D,shouldShowUpdateButton:w,handleSkipRelease:z,handleShowChangelog:q,handleWhatsNewSeen:B,fetchReleases:T,initialize:F}});export{ee as t};
|
|
2
2
|
|
|
3
|
-
//# sourceMappingURL=releaseStore-
|
|
3
|
+
//# sourceMappingURL=releaseStore-DDOxzkVb.js.map
|
comfyui_frontend_package/static/assets/{releaseStore-x0vHjxrw.js.map → releaseStore-DDOxzkVb.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"releaseStore-x0vHjxrw.js","names":[],"sources":["../../src/platform/updates/common/releaseService.ts","../../src/platform/updates/common/releaseStore.ts"],"sourcesContent":["import type { AxiosError, AxiosResponse } from 'axios'\nimport axios from 'axios'\nimport { ref, watch } from 'vue'\n\nimport { getComfyApiBaseUrl } from '@/config/comfyApi'\nimport type { components, operations } from '@/types/comfyRegistryTypes'\nimport { isAbortError } from '@/utils/typeGuardUtil'\n\n// Use generated types from OpenAPI spec\nexport type ReleaseNote = components['schemas']['ReleaseNote']\ntype GetReleasesParams = operations['getReleaseNotes']['parameters']['query']\n\n// Use generated error response type\ntype ErrorResponse = components['schemas']['ErrorResponse']\n\nconst releaseApiClient = axios.create({\n baseURL: getComfyApiBaseUrl(),\n headers: {\n 'Content-Type': 'application/json'\n }\n})\n\n// Release service for fetching release notes\nexport const useReleaseService = () => {\n const isLoading = ref(false)\n const error = ref<string | null>(null)\n\n watch(\n () => getComfyApiBaseUrl(),\n (url) => {\n releaseApiClient.defaults.baseURL = url\n }\n )\n\n // No transformation needed - API response matches the generated type\n\n // Handle API errors with context\n const handleApiError = (\n err: unknown,\n context: string,\n routeSpecificErrors?: Record<number, string>\n ): string => {\n if (!axios.isAxiosError(err))\n return err instanceof Error\n ? `${context}: ${err.message}`\n : `${context}: Unknown error occurred`\n\n const axiosError = err as AxiosError<ErrorResponse>\n\n if (axiosError.response) {\n const { status, data } = axiosError.response\n\n if (routeSpecificErrors && routeSpecificErrors[status])\n return routeSpecificErrors[status]\n\n switch (status) {\n case 400:\n return `Bad request: ${data?.message || 'Invalid input'}`\n case 401:\n return 'Unauthorized: Authentication required'\n case 403:\n return `Forbidden: ${data?.message || 'Access denied'}`\n case 404:\n return `Not found: ${data?.message || 'Resource not found'}`\n case 500:\n return `Server error: ${data?.message || 'Internal server error'}`\n default:\n return `${context}: ${data?.message || axiosError.message}`\n }\n }\n\n return `${context}: ${axiosError.message}`\n }\n\n // Execute API request with error handling\n const executeApiRequest = async <T>(\n apiCall: () => Promise<AxiosResponse<T>>,\n errorContext: string,\n routeSpecificErrors?: Record<number, string>\n ): Promise<T | null> => {\n isLoading.value = true\n error.value = null\n\n try {\n const response = await apiCall()\n return response.data\n } catch (err) {\n // Don't treat cancellations as errors\n if (isAbortError(err)) return null\n\n error.value = handleApiError(err, errorContext, routeSpecificErrors)\n return null\n } finally {\n isLoading.value = false\n }\n }\n\n // Fetch release notes from API\n const getReleases = async (\n params: GetReleasesParams,\n signal?: AbortSignal\n ): Promise<ReleaseNote[] | null> => {\n const endpoint = '/releases'\n const errorContext = 'Failed to get releases'\n const routeSpecificErrors = {\n 400: 'Invalid project or version parameter'\n }\n\n const apiResponse = await executeApiRequest(\n () =>\n releaseApiClient.get<ReleaseNote[]>(endpoint, {\n params,\n signal\n }),\n errorContext,\n routeSpecificErrors\n )\n\n return apiResponse\n }\n\n return {\n isLoading,\n error,\n getReleases\n }\n}\n","import { until } from '@vueuse/core'\nimport { defineStore } from 'pinia'\nimport { compare, valid } from 'semver'\nimport { computed, ref } from 'vue'\n\nimport { isCloud } from '@/platform/distribution/types'\nimport { useSettingStore } from '@/platform/settings/settingStore'\nimport { useSystemStatsStore } from '@/stores/systemStatsStore'\nimport { isElectron } from '@/utils/envUtil'\nimport { stringToLocale } from '@/utils/formatUtil'\n\nimport { useReleaseService } from './releaseService'\nimport type { ReleaseNote } from './releaseService'\n\n// Store for managing release notes\nexport const useReleaseStore = defineStore('release', () => {\n // State\n const releases = ref<ReleaseNote[]>([])\n const isLoading = ref(false)\n const error = ref<string | null>(null)\n\n // Services\n const releaseService = useReleaseService()\n const systemStatsStore = useSystemStatsStore()\n const settingStore = useSettingStore()\n\n const currentVersion = computed(() => {\n if (isCloud) {\n return systemStatsStore?.systemStats?.system?.cloud_version ?? ''\n }\n return systemStatsStore?.systemStats?.system?.comfyui_version ?? ''\n })\n\n // Release data from settings\n const locale = computed(() => settingStore.get('Comfy.Locale'))\n const releaseVersion = computed(() =>\n settingStore.get('Comfy.Release.Version')\n )\n const releaseStatus = computed(() => settingStore.get('Comfy.Release.Status'))\n const releaseTimestamp = computed(() =>\n settingStore.get('Comfy.Release.Timestamp')\n )\n const showVersionUpdates = computed(() =>\n settingStore.get('Comfy.Notification.ShowVersionUpdates')\n )\n\n // Most recent release\n const recentRelease = computed(() => {\n return releases.value[0] ?? null\n })\n\n // 3 most recent releases\n const recentReleases = computed(() => {\n return releases.value.slice(0, 3)\n })\n\n // Helper constants\n const THREE_DAYS_MS = 3 * 24 * 60 * 60 * 1000 // 3 days\n\n const compareVersions = (\n releaseVersion: string,\n currentVer: string\n ): number => {\n if (valid(releaseVersion) && valid(currentVer)) {\n return compare(releaseVersion, currentVer)\n }\n // Non-semver (e.g. git hash): assume different = newer\n return releaseVersion === currentVer ? 0 : 1\n }\n\n // New version available?\n const isNewVersionAvailable = computed(\n () =>\n !!recentRelease.value &&\n compareVersions(\n recentRelease.value.version,\n currentVersion.value || '0.0.0'\n ) > 0\n )\n\n const isLatestVersion = computed(\n () =>\n !!recentRelease.value &&\n compareVersions(\n recentRelease.value.version,\n currentVersion.value || '0.0.0'\n ) === 0\n )\n\n const hasMediumOrHighAttention = computed(() => {\n const attention = recentRelease.value?.attention\n return attention === 'medium' || attention === 'high'\n })\n\n // Show toast if needed\n const shouldShowToast = computed(() => {\n // Only show on desktop version\n if (!isElectron() || isCloud) {\n return false\n }\n\n // Skip if notifications are disabled\n if (!showVersionUpdates.value) {\n return false\n }\n\n if (!isNewVersionAvailable.value) {\n return false\n }\n\n // Skip if low attention\n if (!hasMediumOrHighAttention.value) {\n return false\n }\n\n // Skip if user already skipped or changelog seen\n if (\n releaseVersion.value === recentRelease.value?.version &&\n ['skipped', 'changelog seen'].includes(releaseStatus.value)\n ) {\n return false\n }\n\n return true\n })\n\n // Show red-dot indicator\n const shouldShowRedDot = computed(() => {\n // Only show on desktop version\n if (!isElectron() || isCloud) {\n return false\n }\n\n // Skip if notifications are disabled\n if (!showVersionUpdates.value) {\n return false\n }\n\n // Already latest → no dot\n if (!isNewVersionAvailable.value) {\n return false\n }\n\n const { version } = recentRelease.value\n\n // Changelog seen → clear dot\n if (\n releaseVersion.value === version &&\n releaseStatus.value === 'changelog seen'\n ) {\n return false\n }\n\n // Attention medium / high (levels 2 & 3)\n if (hasMediumOrHighAttention.value) {\n // Persist until changelog is opened\n return true\n }\n\n // Attention low (level 1) and skipped → keep up to 3 d\n if (\n releaseVersion.value === version &&\n releaseStatus.value === 'skipped' &&\n releaseTimestamp.value &&\n Date.now() - releaseTimestamp.value >= THREE_DAYS_MS\n ) {\n return false\n }\n\n // Not skipped → show\n return true\n })\n\n const shouldShowPopup = computed(() => {\n if (!isElectron() && !isCloud) {\n return false\n }\n\n if (!showVersionUpdates.value) {\n return false\n }\n\n if (!recentRelease.value) {\n return false\n }\n\n // Skip version check if current version isn't semver (e.g. git hash)\n const skipVersionCheck = !valid(currentVersion.value)\n if (!skipVersionCheck && !isLatestVersion.value) {\n return false\n }\n\n if (\n releaseVersion.value === recentRelease.value.version &&\n releaseStatus.value === \"what's new seen\"\n ) {\n return false\n }\n\n return true\n })\n\n // Action handlers for user interactions\n async function handleSkipRelease(version: string): Promise<void> {\n if (\n version !== recentRelease.value?.version ||\n releaseStatus.value === 'changelog seen'\n ) {\n return\n }\n\n await settingStore.set('Comfy.Release.Version', version)\n await settingStore.set('Comfy.Release.Status', 'skipped')\n await settingStore.set('Comfy.Release.Timestamp', Date.now())\n }\n\n async function handleShowChangelog(version: string): Promise<void> {\n if (version !== recentRelease.value?.version) {\n return\n }\n\n await settingStore.set('Comfy.Release.Version', version)\n await settingStore.set('Comfy.Release.Status', 'changelog seen')\n await settingStore.set('Comfy.Release.Timestamp', Date.now())\n }\n\n async function handleWhatsNewSeen(version: string): Promise<void> {\n if (version !== recentRelease.value?.version) {\n return\n }\n\n await settingStore.set('Comfy.Release.Version', version)\n await settingStore.set('Comfy.Release.Status', \"what's new seen\")\n await settingStore.set('Comfy.Release.Timestamp', Date.now())\n }\n\n // Fetch releases from API\n async function fetchReleases(): Promise<void> {\n if (isLoading.value) {\n return\n }\n\n if (!isCloud && !showVersionUpdates.value) {\n return\n }\n\n // Skip fetching if API nodes are disabled via argv\n if (\n systemStatsStore.systemStats?.system?.argv?.includes(\n '--disable-api-nodes'\n )\n ) {\n return\n }\n isLoading.value = true\n error.value = null\n\n try {\n // Ensure system stats are loaded\n if (!systemStatsStore.systemStats) {\n await until(systemStatsStore.isInitialized)\n }\n\n const fetchedReleases = await releaseService.getReleases({\n project: isCloud ? 'cloud' : 'comfyui',\n current_version: currentVersion.value,\n form_factor: systemStatsStore.getFormFactor(),\n locale: stringToLocale(locale.value)\n })\n\n if (fetchedReleases !== null) {\n releases.value = fetchedReleases\n } else if (releaseService.error.value) {\n error.value = releaseService.error.value\n }\n } catch (err) {\n error.value =\n err instanceof Error ? err.message : 'Unknown error occurred'\n } finally {\n isLoading.value = false\n }\n }\n\n // Initialize store\n async function initialize(): Promise<void> {\n await fetchReleases()\n }\n\n return {\n releases,\n isLoading,\n error,\n recentRelease,\n recentReleases,\n shouldShowToast,\n shouldShowRedDot,\n shouldShowPopup,\n shouldShowUpdateButton: isNewVersionAvailable,\n handleSkipRelease,\n handleShowChangelog,\n handleWhatsNewSeen,\n fetchReleases,\n initialize\n }\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"releaseStore-DDOxzkVb.js","names":[],"sources":["../../src/platform/updates/common/releaseService.ts","../../src/platform/updates/common/releaseStore.ts"],"sourcesContent":["import type { AxiosError, AxiosResponse } from 'axios'\nimport axios from 'axios'\nimport { ref, watch } from 'vue'\n\nimport { getComfyApiBaseUrl } from '@/config/comfyApi'\nimport type { components, operations } from '@/types/comfyRegistryTypes'\nimport { isAbortError } from '@/utils/typeGuardUtil'\n\n// Use generated types from OpenAPI spec\nexport type ReleaseNote = components['schemas']['ReleaseNote']\ntype GetReleasesParams = operations['getReleaseNotes']['parameters']['query']\n\n// Use generated error response type\ntype ErrorResponse = components['schemas']['ErrorResponse']\n\nconst releaseApiClient = axios.create({\n baseURL: getComfyApiBaseUrl(),\n headers: {\n 'Content-Type': 'application/json'\n }\n})\n\n// Release service for fetching release notes\nexport const useReleaseService = () => {\n const isLoading = ref(false)\n const error = ref<string | null>(null)\n\n watch(\n () => getComfyApiBaseUrl(),\n (url) => {\n releaseApiClient.defaults.baseURL = url\n }\n )\n\n // No transformation needed - API response matches the generated type\n\n // Handle API errors with context\n const handleApiError = (\n err: unknown,\n context: string,\n routeSpecificErrors?: Record<number, string>\n ): string => {\n if (!axios.isAxiosError(err))\n return err instanceof Error\n ? `${context}: ${err.message}`\n : `${context}: Unknown error occurred`\n\n const axiosError = err as AxiosError<ErrorResponse>\n\n if (axiosError.response) {\n const { status, data } = axiosError.response\n\n if (routeSpecificErrors && routeSpecificErrors[status])\n return routeSpecificErrors[status]\n\n switch (status) {\n case 400:\n return `Bad request: ${data?.message || 'Invalid input'}`\n case 401:\n return 'Unauthorized: Authentication required'\n case 403:\n return `Forbidden: ${data?.message || 'Access denied'}`\n case 404:\n return `Not found: ${data?.message || 'Resource not found'}`\n case 500:\n return `Server error: ${data?.message || 'Internal server error'}`\n default:\n return `${context}: ${data?.message || axiosError.message}`\n }\n }\n\n return `${context}: ${axiosError.message}`\n }\n\n // Execute API request with error handling\n const executeApiRequest = async <T>(\n apiCall: () => Promise<AxiosResponse<T>>,\n errorContext: string,\n routeSpecificErrors?: Record<number, string>\n ): Promise<T | null> => {\n isLoading.value = true\n error.value = null\n\n try {\n const response = await apiCall()\n return response.data\n } catch (err) {\n // Don't treat cancellations as errors\n if (isAbortError(err)) return null\n\n error.value = handleApiError(err, errorContext, routeSpecificErrors)\n return null\n } finally {\n isLoading.value = false\n }\n }\n\n // Fetch release notes from API\n const getReleases = async (\n params: GetReleasesParams,\n signal?: AbortSignal\n ): Promise<ReleaseNote[] | null> => {\n const endpoint = '/releases'\n const errorContext = 'Failed to get releases'\n const routeSpecificErrors = {\n 400: 'Invalid project or version parameter'\n }\n\n const apiResponse = await executeApiRequest(\n () =>\n releaseApiClient.get<ReleaseNote[]>(endpoint, {\n params,\n signal\n }),\n errorContext,\n routeSpecificErrors\n )\n\n return apiResponse\n }\n\n return {\n isLoading,\n error,\n getReleases\n }\n}\n","import { until } from '@vueuse/core'\nimport { defineStore } from 'pinia'\nimport { compare, valid } from 'semver'\nimport { computed, ref } from 'vue'\n\nimport { isCloud } from '@/platform/distribution/types'\nimport { useSettingStore } from '@/platform/settings/settingStore'\nimport { useSystemStatsStore } from '@/stores/systemStatsStore'\nimport { isElectron } from '@/utils/envUtil'\nimport { stringToLocale } from '@/utils/formatUtil'\n\nimport { useReleaseService } from './releaseService'\nimport type { ReleaseNote } from './releaseService'\n\n// Store for managing release notes\nexport const useReleaseStore = defineStore('release', () => {\n // State\n const releases = ref<ReleaseNote[]>([])\n const isLoading = ref(false)\n const error = ref<string | null>(null)\n\n // Services\n const releaseService = useReleaseService()\n const systemStatsStore = useSystemStatsStore()\n const settingStore = useSettingStore()\n\n const currentVersion = computed(() => {\n if (isCloud) {\n return systemStatsStore?.systemStats?.system?.cloud_version ?? ''\n }\n return systemStatsStore?.systemStats?.system?.comfyui_version ?? ''\n })\n\n // Release data from settings\n const locale = computed(() => settingStore.get('Comfy.Locale'))\n const releaseVersion = computed(() =>\n settingStore.get('Comfy.Release.Version')\n )\n const releaseStatus = computed(() => settingStore.get('Comfy.Release.Status'))\n const releaseTimestamp = computed(() =>\n settingStore.get('Comfy.Release.Timestamp')\n )\n const showVersionUpdates = computed(() =>\n settingStore.get('Comfy.Notification.ShowVersionUpdates')\n )\n\n // Most recent release\n const recentRelease = computed(() => {\n return releases.value[0] ?? null\n })\n\n // 3 most recent releases\n const recentReleases = computed(() => {\n return releases.value.slice(0, 3)\n })\n\n // Helper constants\n const THREE_DAYS_MS = 3 * 24 * 60 * 60 * 1000 // 3 days\n\n const compareVersions = (\n releaseVersion: string,\n currentVer: string\n ): number => {\n if (valid(releaseVersion) && valid(currentVer)) {\n return compare(releaseVersion, currentVer)\n }\n // Non-semver (e.g. git hash): assume different = newer\n return releaseVersion === currentVer ? 0 : 1\n }\n\n // New version available?\n const isNewVersionAvailable = computed(\n () =>\n !!recentRelease.value &&\n compareVersions(\n recentRelease.value.version,\n currentVersion.value || '0.0.0'\n ) > 0\n )\n\n const isLatestVersion = computed(\n () =>\n !!recentRelease.value &&\n compareVersions(\n recentRelease.value.version,\n currentVersion.value || '0.0.0'\n ) === 0\n )\n\n const hasMediumOrHighAttention = computed(() => {\n const attention = recentRelease.value?.attention\n return attention === 'medium' || attention === 'high'\n })\n\n // Show toast if needed\n const shouldShowToast = computed(() => {\n // Only show on desktop version\n if (!isElectron() || isCloud) {\n return false\n }\n\n // Skip if notifications are disabled\n if (!showVersionUpdates.value) {\n return false\n }\n\n if (!isNewVersionAvailable.value) {\n return false\n }\n\n // Skip if low attention\n if (!hasMediumOrHighAttention.value) {\n return false\n }\n\n // Skip if user already skipped or changelog seen\n if (\n releaseVersion.value === recentRelease.value?.version &&\n ['skipped', 'changelog seen'].includes(releaseStatus.value)\n ) {\n return false\n }\n\n return true\n })\n\n // Show red-dot indicator\n const shouldShowRedDot = computed(() => {\n // Only show on desktop version\n if (!isElectron() || isCloud) {\n return false\n }\n\n // Skip if notifications are disabled\n if (!showVersionUpdates.value) {\n return false\n }\n\n // Already latest → no dot\n if (!isNewVersionAvailable.value) {\n return false\n }\n\n const { version } = recentRelease.value\n\n // Changelog seen → clear dot\n if (\n releaseVersion.value === version &&\n releaseStatus.value === 'changelog seen'\n ) {\n return false\n }\n\n // Attention medium / high (levels 2 & 3)\n if (hasMediumOrHighAttention.value) {\n // Persist until changelog is opened\n return true\n }\n\n // Attention low (level 1) and skipped → keep up to 3 d\n if (\n releaseVersion.value === version &&\n releaseStatus.value === 'skipped' &&\n releaseTimestamp.value &&\n Date.now() - releaseTimestamp.value >= THREE_DAYS_MS\n ) {\n return false\n }\n\n // Not skipped → show\n return true\n })\n\n const shouldShowPopup = computed(() => {\n if (!isElectron() && !isCloud) {\n return false\n }\n\n if (!showVersionUpdates.value) {\n return false\n }\n\n if (!recentRelease.value) {\n return false\n }\n\n // Skip version check if current version isn't semver (e.g. git hash)\n const skipVersionCheck = !valid(currentVersion.value)\n if (!skipVersionCheck && !isLatestVersion.value) {\n return false\n }\n\n if (\n releaseVersion.value === recentRelease.value.version &&\n releaseStatus.value === \"what's new seen\"\n ) {\n return false\n }\n\n return true\n })\n\n // Action handlers for user interactions\n async function handleSkipRelease(version: string): Promise<void> {\n if (\n version !== recentRelease.value?.version ||\n releaseStatus.value === 'changelog seen'\n ) {\n return\n }\n\n await settingStore.set('Comfy.Release.Version', version)\n await settingStore.set('Comfy.Release.Status', 'skipped')\n await settingStore.set('Comfy.Release.Timestamp', Date.now())\n }\n\n async function handleShowChangelog(version: string): Promise<void> {\n if (version !== recentRelease.value?.version) {\n return\n }\n\n await settingStore.set('Comfy.Release.Version', version)\n await settingStore.set('Comfy.Release.Status', 'changelog seen')\n await settingStore.set('Comfy.Release.Timestamp', Date.now())\n }\n\n async function handleWhatsNewSeen(version: string): Promise<void> {\n if (version !== recentRelease.value?.version) {\n return\n }\n\n await settingStore.set('Comfy.Release.Version', version)\n await settingStore.set('Comfy.Release.Status', \"what's new seen\")\n await settingStore.set('Comfy.Release.Timestamp', Date.now())\n }\n\n // Fetch releases from API\n async function fetchReleases(): Promise<void> {\n if (isLoading.value) {\n return\n }\n\n if (!isCloud && !showVersionUpdates.value) {\n return\n }\n\n // Skip fetching if API nodes are disabled via argv\n if (\n systemStatsStore.systemStats?.system?.argv?.includes(\n '--disable-api-nodes'\n )\n ) {\n return\n }\n isLoading.value = true\n error.value = null\n\n try {\n // Ensure system stats are loaded\n if (!systemStatsStore.systemStats) {\n await until(systemStatsStore.isInitialized)\n }\n\n const fetchedReleases = await releaseService.getReleases({\n project: isCloud ? 'cloud' : 'comfyui',\n current_version: currentVersion.value,\n form_factor: systemStatsStore.getFormFactor(),\n locale: stringToLocale(locale.value)\n })\n\n if (fetchedReleases !== null) {\n releases.value = fetchedReleases\n } else if (releaseService.error.value) {\n error.value = releaseService.error.value\n }\n } catch (err) {\n error.value =\n err instanceof Error ? err.message : 'Unknown error occurred'\n } finally {\n isLoading.value = false\n }\n }\n\n // Initialize store\n async function initialize(): Promise<void> {\n await fetchReleases()\n }\n\n return {\n releases,\n isLoading,\n error,\n recentRelease,\n recentReleases,\n shouldShowToast,\n shouldShowRedDot,\n shouldShowPopup,\n shouldShowUpdateButton: isNewVersionAvailable,\n handleSkipRelease,\n handleShowChangelog,\n handleWhatsNewSeen,\n fetchReleases,\n initialize\n }\n})\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./vendor-primevue-DcMRXJN3.js";import"./vendor-other-DlQF6V2E.js";import"./api-Dwq2LQIW.js";import"./remoteConfig-CZcEXsZS.js";import"./colorUtil-CzxntCbX.js";import"./useErrorHandling-Cfa5N_7c.js";import"./Button-Do2I1OAA.js";import"./PanelTemplate-BJda9e5J.js";import"./dialogService-YG0RH337.js";import"./vendor-tiptap-_UqYL7N_.js";import"./vendor-xterm-BU_lcTPR.js";import"./vendor-three-BFcUNSs9.js";import"./markdownRendererUtil-DglHsU8t.js";import"./userStore-BAS9m9W6.js";import{t as b}from"./releaseStore-DDOxzkVb.js";export{b as useReleaseStore};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var f=Object.defineProperty;var r=(e,o)=>f(e,"name",{value:o,configurable:!0});import{A as c,Lt as p}from"./api-
|
|
1
|
+
var f=Object.defineProperty;var r=(e,o)=>f(e,"name",{value:o,configurable:!0});import{A as c,Lt as p}from"./api-Dwq2LQIW.js";import{Br as u,Hr as T,Vr as d}from"./dialogService-YG0RH337.js";var w=r((e,o)=>o==="yearly"?`${e}-yearly`:e,"getCheckoutTier");async function y(e,o,n=!0){if(!p)return;const{getAuthHeader:h}=d(),i=await h();if(!i)throw new u(c("toastMessages.userNotAuthenticated"));const l=w(e,o),t=await fetch(`${T()}/customers/cloud-subscription-checkout/${l}`,{method:"POST",headers:{...i,"Content-Type":"application/json"}});if(!t.ok){let s="Failed to initiate checkout";try{s=(await t.json()).message||s}catch{try{s=await t.text()||`HTTP ${t.status} ${t.statusText}`}catch{s=`HTTP ${t.status} ${t.statusText}`}}throw new u(c("toastMessages.failedToInitiateSubscription",{error:s}))}const a=await t.json();a.checkout_url&&(n?window.open(a.checkout_url,"_blank"):globalThis.location.href=a.checkout_url)}r(y,"performSubscriptionCheckout");export{y as t};
|
|
2
2
|
|
|
3
|
-
//# sourceMappingURL=subscriptionCheckoutUtil-
|
|
3
|
+
//# sourceMappingURL=subscriptionCheckoutUtil-DswSOreM.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subscriptionCheckoutUtil-
|
|
1
|
+
{"version":3,"file":"subscriptionCheckoutUtil-DswSOreM.js","names":[],"sources":["../../src/platform/cloud/subscription/utils/subscriptionCheckoutUtil.ts"],"sourcesContent":["import { getComfyApiBaseUrl } from '@/config/comfyApi'\nimport { t } from '@/i18n'\nimport { isCloud } from '@/platform/distribution/types'\nimport {\n FirebaseAuthStoreError,\n useFirebaseAuthStore\n} from '@/stores/firebaseAuthStore'\nimport type { TierKey } from '@/platform/cloud/subscription/constants/tierPricing'\nimport type { BillingCycle } from './subscriptionTierRank'\n\ntype CheckoutTier = TierKey | `${TierKey}-yearly`\n\nconst getCheckoutTier = (\n tierKey: TierKey,\n billingCycle: BillingCycle\n): CheckoutTier => (billingCycle === 'yearly' ? `${tierKey}-yearly` : tierKey)\n\n/**\n * Core subscription checkout logic shared between PricingTable and\n * SubscriptionRedirectView. Handles:\n * - Ensuring the user is authenticated\n * - Calling the backend checkout endpoint\n * - Normalizing error responses\n * - Opening the checkout URL in a new tab when available\n *\n * Callers are responsible for:\n * - Guarding on cloud-only behavior (isCloud)\n * - Managing loading state\n * - Wrapping with error handling (e.g. useErrorHandling)\n */\nexport async function performSubscriptionCheckout(\n tierKey: TierKey,\n currentBillingCycle: BillingCycle,\n openInNewTab: boolean = true\n): Promise<void> {\n if (!isCloud) return\n\n const { getAuthHeader } = useFirebaseAuthStore()\n const authHeader = await getAuthHeader()\n\n if (!authHeader) {\n throw new FirebaseAuthStoreError(t('toastMessages.userNotAuthenticated'))\n }\n\n const checkoutTier = getCheckoutTier(tierKey, currentBillingCycle)\n\n const response = await fetch(\n `${getComfyApiBaseUrl()}/customers/cloud-subscription-checkout/${checkoutTier}`,\n {\n method: 'POST',\n headers: { ...authHeader, 'Content-Type': 'application/json' }\n }\n )\n\n if (!response.ok) {\n let errorMessage = 'Failed to initiate checkout'\n try {\n const errorData = await response.json()\n errorMessage = errorData.message || errorMessage\n } catch {\n // If JSON parsing fails, try to get text response or use HTTP status\n try {\n const errorText = await response.text()\n errorMessage =\n errorText || `HTTP ${response.status} ${response.statusText}`\n } catch {\n errorMessage = `HTTP ${response.status} ${response.statusText}`\n }\n }\n\n throw new FirebaseAuthStoreError(\n t('toastMessages.failedToInitiateSubscription', {\n error: errorMessage\n })\n )\n }\n\n const data = await response.json()\n\n if (data.checkout_url) {\n if (openInNewTab) {\n window.open(data.checkout_url, '_blank')\n } else {\n globalThis.location.href = data.checkout_url\n }\n }\n}\n"],"mappings":"8LAYA,IAAM,EAAA,EAAA,CACJ,EACA,IACkB,IAAiB,SAAW,GAAG,CAAA,UAAmB,EAHhE,mBAkBN,eAAsB,EACpB,EACA,EACA,EAAwB,GACT,CACf,GAAI,CAAC,EAAS,OAEd,KAAM,CAAE,cAAA,CAAA,EAAkB,EAAA,EACpB,EAAa,MAAM,EAAA,EAEzB,GAAI,CAAC,EACH,MAAM,IAAI,EAAuB,EAAE,oCAAA,CAAqC,EAG1E,MAAM,EAAe,EAAgB,EAAS,CAAA,EAExC,EAAW,MAAM,MACrB,GAAG,EAAA,CAAoB,0CAA0C,CAAA,GACjE,CACE,OAAQ,OACR,QAAS,CAAE,GAAG,EAAY,eAAgB,oBAC3C,EAGH,GAAI,CAAC,EAAS,GAAI,CAChB,IAAI,EAAe,8BACnB,GAAI,CAEF,GADkB,MAAM,EAAS,KAAA,GACR,SAAW,OAC9B,CAEN,GAAI,CAEF,EADkB,MAAM,EAAS,KAAA,GAElB,QAAQ,EAAS,MAAA,IAAU,EAAS,UAAA,QAC7C,CACN,EAAe,QAAQ,EAAS,MAAA,IAAU,EAAS,UAAA,IAIvD,MAAM,IAAI,EACR,EAAE,6CAA8C,CAC9C,MAAO,CAAA,CACR,CAAC,EAIN,MAAM,EAAO,MAAM,EAAS,KAAA,EAExB,EAAK,eACH,EACF,OAAO,KAAK,EAAK,aAAc,QAAA,EAE/B,WAAW,SAAS,KAAO,EAAK,cArDhB,EAAA,EAAA"}
|
comfyui_frontend_package/static/assets/{useCurrentUser-BJcn2Vgo.js → useCurrentUser-NdaCJzIK.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./vendor-primevue-DcMRXJN3.js";import"./vendor-other-DlQF6V2E.js";import"./api-
|
|
1
|
+
import"./vendor-primevue-DcMRXJN3.js";import"./vendor-other-DlQF6V2E.js";import"./api-Dwq2LQIW.js";import"./remoteConfig-CZcEXsZS.js";import"./colorUtil-CzxntCbX.js";import"./useErrorHandling-Cfa5N_7c.js";import"./Button-Do2I1OAA.js";import"./PanelTemplate-BJda9e5J.js";import{Dr as a}from"./dialogService-YG0RH337.js";import"./vendor-tiptap-_UqYL7N_.js";import"./vendor-xterm-BU_lcTPR.js";import"./vendor-three-BFcUNSs9.js";import"./markdownRendererUtil-DglHsU8t.js";import"./userStore-BAS9m9W6.js";export{a as useCurrentUser};
|
comfyui_frontend_package/static/assets/{useErrorHandling-CI8_F4yx.js → useErrorHandling-Cfa5N_7c.js}
RENAMED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var p=Object.defineProperty;var E=(e,_)=>p(e,"name",{value:_,configurable:!0});import{Lo as N,Ro as c,za as m}from"./vendor-other-DlQF6V2E.js";import{A as D,It as S,r}from"./api-
|
|
1
|
+
var p=Object.defineProperty;var E=(e,_)=>p(e,"name",{value:_,configurable:!0});import{Lo as N,Ro as c,za as m}from"./vendor-other-DlQF6V2E.js";import{A as D,It as S,r}from"./api-Dwq2LQIW.js";import{r as t}from"./remoteConfig-CZcEXsZS.js";let a=(function(e){return e.SUPPORTS_PREVIEW_METADATA="supports_preview_metadata",e.MAX_UPLOAD_SIZE="max_upload_size",e.MANAGER_SUPPORTS_V4="extension.manager.supports_v4",e.MODEL_UPLOAD_BUTTON_ENABLED="model_upload_button_enabled",e.ASSET_DELETION_ENABLED="asset_deletion_enabled",e.ASSET_RENAME_ENABLED="asset_rename_enabled",e.PRIVATE_MODELS_ENABLED="private_models_enabled",e.ONBOARDING_SURVEY_ENABLED="onboarding_survey_enabled",e.HUGGINGFACE_MODEL_IMPORT_ENABLED="huggingface_model_import_enabled",e.LINEAR_TOGGLE_ENABLED="linear_toggle_enabled",e.ASYNC_MODEL_UPLOAD_ENABLED="async_model_upload_enabled",e.TEAM_WORKSPACES_ENABLED="team_workspaces_enabled",e})({});function v(){const e=N({get supportsPreviewMetadata(){return r.getServerFeature(a.SUPPORTS_PREVIEW_METADATA)},get maxUploadSize(){return r.getServerFeature(a.MAX_UPLOAD_SIZE)},get supportsManagerV4(){return r.getServerFeature(a.MANAGER_SUPPORTS_V4)},get modelUploadButtonEnabled(){return t.value.model_upload_button_enabled??r.getServerFeature(a.MODEL_UPLOAD_BUTTON_ENABLED,!1)},get assetDeletionEnabled(){return t.value.asset_deletion_enabled??r.getServerFeature(a.ASSET_DELETION_ENABLED,!1)},get assetRenameEnabled(){return t.value.asset_rename_enabled??r.getServerFeature(a.ASSET_RENAME_ENABLED,!1)},get privateModelsEnabled(){return t.value.private_models_enabled??r.getServerFeature(a.PRIVATE_MODELS_ENABLED,!1)},get onboardingSurveyEnabled(){return t.value.onboarding_survey_enabled??r.getServerFeature(a.ONBOARDING_SURVEY_ENABLED,!0)},get huggingfaceModelImportEnabled(){return t.value.huggingface_model_import_enabled??r.getServerFeature(a.HUGGINGFACE_MODEL_IMPORT_ENABLED,!1)},get linearToggleEnabled(){return t.value.linear_toggle_enabled??r.getServerFeature(a.LINEAR_TOGGLE_ENABLED,!1)},get asyncModelUploadEnabled(){return t.value.async_model_upload_enabled??r.getServerFeature(a.ASYNC_MODEL_UPLOAD_ENABLED,!1)},get teamWorkspacesEnabled(){return t.value.team_workspaces_enabled??r.getServerFeature(a.TEAM_WORKSPACES_ENABLED,!1)}}),_=E((A,g)=>m(()=>r.getServerFeature(A,g)),"featureFlag");return{flags:c(e),featureFlag:_}}E(v,"useFeatureFlags");function M(){const e=S(),_=E(n=>{e.add({severity:"error",summary:D("g.error"),detail:n instanceof Error?n.message:D("g.unknownError")}),console.error(n)},"toastErrorHandler");return{wrapWithErrorHandling:E((n,l,s)=>(...d)=>{try{return n(...d)}catch(o){(l??_)(o)}finally{s?.()}},"wrapWithErrorHandling"),wrapWithErrorHandlingAsync:E((n,l,s,d=[])=>async(...o)=>{try{return await n(...o)}catch(u){for(const i of d)if(i.shouldHandle(u))try{await i.recover(u,n,o);return}catch(L){console.error("Recovery strategy failed:",L)}(l??_)(u)}finally{s?.()}},"wrapWithErrorHandlingAsync"),toastErrorHandler:_}}E(M,"useErrorHandling");export{v as n,M as t};
|
|
2
2
|
|
|
3
|
-
//# sourceMappingURL=useErrorHandling-
|
|
3
|
+
//# sourceMappingURL=useErrorHandling-Cfa5N_7c.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useErrorHandling-
|
|
1
|
+
{"version":3,"file":"useErrorHandling-Cfa5N_7c.js","names":[],"sources":["../../src/composables/useFeatureFlags.ts","../../src/composables/useErrorHandling.ts"],"sourcesContent":["import { computed, reactive, readonly } from 'vue'\n\nimport { remoteConfig } from '@/platform/remoteConfig/remoteConfig'\nimport { api } from '@/scripts/api'\n\n/**\n * Known server feature flags (top-level, not extensions)\n */\nexport enum ServerFeatureFlag {\n SUPPORTS_PREVIEW_METADATA = 'supports_preview_metadata',\n MAX_UPLOAD_SIZE = 'max_upload_size',\n MANAGER_SUPPORTS_V4 = 'extension.manager.supports_v4',\n MODEL_UPLOAD_BUTTON_ENABLED = 'model_upload_button_enabled',\n ASSET_DELETION_ENABLED = 'asset_deletion_enabled',\n ASSET_RENAME_ENABLED = 'asset_rename_enabled',\n PRIVATE_MODELS_ENABLED = 'private_models_enabled',\n ONBOARDING_SURVEY_ENABLED = 'onboarding_survey_enabled',\n HUGGINGFACE_MODEL_IMPORT_ENABLED = 'huggingface_model_import_enabled',\n LINEAR_TOGGLE_ENABLED = 'linear_toggle_enabled',\n ASYNC_MODEL_UPLOAD_ENABLED = 'async_model_upload_enabled',\n TEAM_WORKSPACES_ENABLED = 'team_workspaces_enabled'\n}\n\n/**\n * Composable for reactive access to server-side feature flags\n */\nexport function useFeatureFlags() {\n const flags = reactive({\n get supportsPreviewMetadata() {\n return api.getServerFeature(ServerFeatureFlag.SUPPORTS_PREVIEW_METADATA)\n },\n get maxUploadSize() {\n return api.getServerFeature(ServerFeatureFlag.MAX_UPLOAD_SIZE)\n },\n get supportsManagerV4() {\n return api.getServerFeature(ServerFeatureFlag.MANAGER_SUPPORTS_V4)\n },\n get modelUploadButtonEnabled() {\n // Check remote config first (from /api/features), fall back to websocket feature flags\n return (\n remoteConfig.value.model_upload_button_enabled ??\n api.getServerFeature(\n ServerFeatureFlag.MODEL_UPLOAD_BUTTON_ENABLED,\n false\n )\n )\n },\n get assetDeletionEnabled() {\n return (\n remoteConfig.value.asset_deletion_enabled ??\n api.getServerFeature(ServerFeatureFlag.ASSET_DELETION_ENABLED, false)\n )\n },\n get assetRenameEnabled() {\n return (\n remoteConfig.value.asset_rename_enabled ??\n api.getServerFeature(ServerFeatureFlag.ASSET_RENAME_ENABLED, false)\n )\n },\n get privateModelsEnabled() {\n // Check remote config first (from /api/features), fall back to websocket feature flags\n return (\n remoteConfig.value.private_models_enabled ??\n api.getServerFeature(ServerFeatureFlag.PRIVATE_MODELS_ENABLED, false)\n )\n },\n get onboardingSurveyEnabled() {\n return (\n remoteConfig.value.onboarding_survey_enabled ??\n api.getServerFeature(ServerFeatureFlag.ONBOARDING_SURVEY_ENABLED, true)\n )\n },\n get huggingfaceModelImportEnabled() {\n return (\n remoteConfig.value.huggingface_model_import_enabled ??\n api.getServerFeature(\n ServerFeatureFlag.HUGGINGFACE_MODEL_IMPORT_ENABLED,\n false\n )\n )\n },\n get linearToggleEnabled() {\n return (\n remoteConfig.value.linear_toggle_enabled ??\n api.getServerFeature(ServerFeatureFlag.LINEAR_TOGGLE_ENABLED, false)\n )\n },\n get asyncModelUploadEnabled() {\n return (\n remoteConfig.value.async_model_upload_enabled ??\n api.getServerFeature(\n ServerFeatureFlag.ASYNC_MODEL_UPLOAD_ENABLED,\n false\n )\n )\n },\n get teamWorkspacesEnabled() {\n return (\n remoteConfig.value.team_workspaces_enabled ??\n api.getServerFeature(ServerFeatureFlag.TEAM_WORKSPACES_ENABLED, false)\n )\n }\n })\n\n const featureFlag = <T = unknown>(featurePath: string, defaultValue?: T) =>\n computed(() => api.getServerFeature(featurePath, defaultValue))\n\n return {\n flags: readonly(flags),\n featureFlag\n }\n}\n","import { t } from '@/i18n'\nimport { useToastStore } from '@/platform/updates/common/toastStore'\n\n/**\n * Strategy for recovering from specific error conditions.\n * Allows operations to be retried after resolving the error condition.\n *\n * @template TArgs - The argument types of the operation to be retried\n * @template TReturn - The return type of the operation\n *\n * @example\n * ```typescript\n * const networkRecovery: ErrorRecoveryStrategy = {\n * shouldHandle: (error) => error instanceof NetworkError,\n * recover: async (error, retry) => {\n * await waitForNetwork()\n * await retry()\n * }\n * }\n * ```\n */\nexport interface ErrorRecoveryStrategy<\n TArgs extends unknown[] = unknown[],\n TReturn = unknown\n> {\n /**\n * Determines if this strategy should handle the given error.\n * @param error - The error to check\n * @returns true if this strategy can handle the error\n */\n shouldHandle: (error: unknown) => boolean\n\n /**\n * Attempts to recover from the error and retry the operation.\n * This function is responsible for:\n * 1. Resolving the error condition (e.g., reauthentication, network reconnect)\n * 2. Calling retry() to re-execute the original operation\n * 3. Handling the retry result (success or failure)\n *\n * @param error - The error that occurred\n * @param retry - Function to retry the original operation\n * @param args - Original arguments passed to the operation\n * @returns Promise that resolves when recovery completes (whether successful or not)\n */\n recover: (\n error: unknown,\n retry: (...args: TArgs) => Promise<TReturn> | TReturn,\n args: TArgs\n ) => Promise<void>\n}\n\nexport function useErrorHandling() {\n const toast = useToastStore()\n const toastErrorHandler = (error: unknown) => {\n toast.add({\n severity: 'error',\n summary: t('g.error'),\n detail: error instanceof Error ? error.message : t('g.unknownError')\n })\n console.error(error)\n }\n\n const wrapWithErrorHandling =\n <TArgs extends unknown[], TReturn>(\n action: (...args: TArgs) => TReturn,\n errorHandler?: (error: unknown) => void,\n finallyHandler?: () => void\n ) =>\n (...args: TArgs): TReturn | undefined => {\n try {\n return action(...args)\n } catch (e) {\n ;(errorHandler ?? toastErrorHandler)(e)\n } finally {\n finallyHandler?.()\n }\n }\n\n const wrapWithErrorHandlingAsync =\n <TArgs extends unknown[], TReturn>(\n action: (...args: TArgs) => Promise<TReturn> | TReturn,\n errorHandler?: (error: unknown) => void,\n finallyHandler?: () => void,\n recoveryStrategies: ErrorRecoveryStrategy<TArgs, TReturn>[] = []\n ) =>\n async (...args: TArgs): Promise<TReturn | undefined> => {\n try {\n return await action(...args)\n } catch (e) {\n for (const strategy of recoveryStrategies) {\n if (strategy.shouldHandle(e)) {\n try {\n await strategy.recover(e, action, args)\n return\n } catch (recoveryError) {\n console.error('Recovery strategy failed:', recoveryError)\n }\n }\n }\n\n ;(errorHandler ?? toastErrorHandler)(e)\n } finally {\n finallyHandler?.()\n }\n }\n\n return {\n wrapWithErrorHandling,\n wrapWithErrorHandlingAsync,\n toastErrorHandler\n }\n}\n"],"mappings":"8OAQA,IAAY,GAAA,SAAA,EAAL,CACL,OAAA,EAAA,0BAAA,4BACA,EAAA,gBAAA,kBACA,EAAA,oBAAA,gCACA,EAAA,4BAAA,8BACA,EAAA,uBAAA,yBACA,EAAA,qBAAA,uBACA,EAAA,uBAAA,yBACA,EAAA,0BAAA,4BACA,EAAA,iCAAA,mCACA,EAAA,sBAAA,wBACA,EAAA,2BAAA,6BACA,EAAA,wBAAA,kCAMF,SAAgB,GAAkB,CAChC,MAAM,EAAQ,EAAS,CACrB,IAAI,yBAA0B,CAC5B,OAAO,EAAI,iBAAiB,EAAkB,yBAAA,GAEhD,IAAI,eAAgB,CAClB,OAAO,EAAI,iBAAiB,EAAkB,eAAA,GAEhD,IAAI,mBAAoB,CACtB,OAAO,EAAI,iBAAiB,EAAkB,mBAAA,GAEhD,IAAI,0BAA2B,CAE7B,OACE,EAAa,MAAM,6BACnB,EAAI,iBACF,EAAkB,4BAClB,EAAA,GAIN,IAAI,sBAAuB,CACzB,OACE,EAAa,MAAM,wBACnB,EAAI,iBAAiB,EAAkB,uBAAwB,EAAA,GAGnE,IAAI,oBAAqB,CACvB,OACE,EAAa,MAAM,sBACnB,EAAI,iBAAiB,EAAkB,qBAAsB,EAAA,GAGjE,IAAI,sBAAuB,CAEzB,OACE,EAAa,MAAM,wBACnB,EAAI,iBAAiB,EAAkB,uBAAwB,EAAA,GAGnE,IAAI,yBAA0B,CAC5B,OACE,EAAa,MAAM,2BACnB,EAAI,iBAAiB,EAAkB,0BAA2B,EAAA,GAGtE,IAAI,+BAAgC,CAClC,OACE,EAAa,MAAM,kCACnB,EAAI,iBACF,EAAkB,iCAClB,EAAA,GAIN,IAAI,qBAAsB,CACxB,OACE,EAAa,MAAM,uBACnB,EAAI,iBAAiB,EAAkB,sBAAuB,EAAA,GAGlE,IAAI,yBAA0B,CAC5B,OACE,EAAa,MAAM,4BACnB,EAAI,iBACF,EAAkB,2BAClB,EAAA,GAIN,IAAI,uBAAwB,CAC1B,OACE,EAAa,MAAM,yBACnB,EAAI,iBAAiB,EAAkB,wBAAyB,EAAA,GAGrE,EAEK,EAAA,EAAA,CAA4B,EAAqB,IACrD,EAAA,IAAe,EAAI,iBAAiB,EAAa,CAAA,CAAa,EAD1D,eAGN,MAAO,CACL,MAAO,EAAS,CAAA,EAChB,YAAA,GAnFY,EAAA,EAAA,mBCyBhB,SAAgB,GAAmB,CACjC,MAAM,EAAQ,EAAA,EACR,EAAA,EAAqB,GAAmB,CAC5C,EAAM,IAAI,CACR,SAAU,QACV,QAAS,EAAE,SAAA,EACX,OAAQ,aAAiB,MAAQ,EAAM,QAAU,EAAE,gBAAA,EACpD,EACD,QAAQ,MAAM,CAAA,GANV,qBAqDN,MAAO,CACL,sBA7CI,EAAA,CAEF,EACA,EACA,IAAA,IAEE,IAAqC,CACvC,GAAI,CACF,OAAO,EAAO,GAAG,CAAA,QACV,EAAG,EACR,GAAgB,GAAmB,CAAA,UAErC,IAAA,IAZA,yBA8CJ,2BA9BI,EAAA,CAEF,EACA,EACA,EACA,EAA8D,CAAA,IAEhE,SAAU,IAA8C,CACtD,GAAI,CACF,OAAO,MAAM,EAAO,GAAG,CAAA,QAChB,EAAG,CACV,UAAW,KAAY,EACrB,GAAI,EAAS,aAAa,CAAA,EACxB,GAAI,CACF,MAAM,EAAS,QAAQ,EAAG,EAAQ,CAAA,EAClC,aACO,EAAe,CACtB,QAAQ,MAAM,4BAA6B,CAAA,GAK/C,GAAgB,GAAmB,CAAA,UAErC,IAAA,IAxBA,8BA+BJ,kBAAA,GA1DY,EAAA,EAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./SubscriptionRequiredDialogContent
|
|
2
|
-
var i=Object.defineProperty;var o=(r,e)=>i(r,"name",{value:e,configurable:!0});import{dt as n}from"./vendor-primevue-DcMRXJN3.js";import{Ja as d}from"./vendor-other-DlQF6V2E.js";import{Xn as p,t as l}from"./dialogService-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./SubscriptionRequiredDialogContent-COEF2VQ_.js","./_plugin-vue_export-helper-PHE0iSCb.js","./vendor-primevue-DcMRXJN3.js","./vendor-other-DlQF6V2E.js","./rolldown-runtime-BN4meiq5.js","./vendor-other-CaaUC6Qe.css","./dialogService-YG0RH337.js","./vendor-vue-D9IUuwPJ.js","./vendor-three-BFcUNSs9.js","./vendor-tiptap-_UqYL7N_.js","./vendor-xterm-BU_lcTPR.js","./vendor-xterm-kHJ-D0s7.css","./PanelTemplate-BJda9e5J.js","./api-Dwq2LQIW.js","./widget-DNFXpyU8.js","./colorUtil-CzxntCbX.js","./src-DTrob8OL.js","./Button-Do2I1OAA.js","./vendor-reka-ui-CmnTduBl.js","./Slider-De1ykl8L.js","./useErrorHandling-Cfa5N_7c.js","./remoteConfig-CZcEXsZS.js","./userStore-BAS9m9W6.js","./markdownRendererUtil-DglHsU8t.js","./dialogService-BMbgJ9MG.css","./CloudBadge-B4nmLus2.js","./SubscribeButton-DZBycfCA.js","./subscriptionCheckoutUtil-DswSOreM.js","./SubscriptionRequiredDialogContent-CiHdewCw.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
var i=Object.defineProperty;var o=(r,e)=>i(r,"name",{value:e,configurable:!0});import{dt as n}from"./vendor-primevue-DcMRXJN3.js";import{Ja as d}from"./vendor-other-DlQF6V2E.js";import{Xn as p,t as l}from"./dialogService-YG0RH337.js";var a="subscription-required";const b=o(()=>{const r=l(),e=p();function t(){e.closeDialog({key:a})}o(t,"hide");function s(){r.showLayoutDialog({key:a,component:d(()=>n(()=>import("./SubscriptionRequiredDialogContent-COEF2VQ_.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28]),import.meta.url)),props:{onClose:t},dialogComponentProps:{style:"width: min(1328px, 95vw); max-height: 90vh;",pt:{root:{class:"rounded-2xl bg-transparent"},content:{class:"!p-0 rounded-2xl border border-border-default bg-base-background/60 backdrop-blur-md shadow-[0_25px_80px_rgba(5,6,12,0.45)]"}}}})}return o(s,"show"),{show:s,hide:t}},"useSubscriptionDialog");export{b as t};
|
|
3
3
|
|
|
4
|
-
//# sourceMappingURL=useSubscriptionDialog-
|
|
4
|
+
//# sourceMappingURL=useSubscriptionDialog-792qfEJ2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"mappings":";0OAIA,IAAM,EAAa,wBAEnB,MAAa,QAA8B,CACzC,MAAM,EAAgB,IAChB,EAAc,IAEpB,SAAS,GAAO,CACd,EAAY,YAAY,CAAE,IAAK,EAAY,EADpC,YAIT,SAAS,GAAO,CACd,EAAc,iBAAiB,CAC7B,IAAK,EACL,UAAW,YAEP,OAAO,qKAEX,MAAO,CACL,QAAS,GAEX,qBAAsB,CACpB,MAAO,8CACP,GAAI,CACF,KAAM,CACJ,MAAO,8BAET,QAAS,CACP,MACE,iIAIT,EAtBM,mBAyBF,CACL,OACA,SAnCS","names":[],"ignoreList":[],"sources":["../../src/platform/cloud/subscription/composables/useSubscriptionDialog.ts"],"sourcesContent":["import { defineAsyncComponent } from 'vue'\nimport { useDialogService } from '@/services/dialogService'\nimport { useDialogStore } from '@/stores/dialogStore'\n\nconst DIALOG_KEY = 'subscription-required'\n\nexport const useSubscriptionDialog = () => {\n const dialogService = useDialogService()\n const dialogStore = useDialogStore()\n\n function hide() {\n dialogStore.closeDialog({ key: DIALOG_KEY })\n }\n\n function show() {\n dialogService.showLayoutDialog({\n key: DIALOG_KEY,\n component: defineAsyncComponent(\n () =>\n import('@/platform/cloud/subscription/components/SubscriptionRequiredDialogContent.vue')\n ),\n props: {\n onClose: hide\n },\n dialogComponentProps: {\n style: 'width: min(1328px, 95vw); max-height: 90vh;',\n pt: {\n root: {\n class: 'rounded-2xl bg-transparent'\n },\n content: {\n class:\n '!p-0 rounded-2xl border border-border-default bg-base-background/60 backdrop-blur-md shadow-[0_25px_80px_rgba(5,6,12,0.45)]'\n }\n }\n }\n })\n }\n\n return {\n show,\n hide\n }\n}\n"],"file":"useSubscriptionDialog-
|
|
1
|
+
{"version":3,"mappings":";0OAIA,IAAM,EAAa,wBAEnB,MAAa,QAA8B,CACzC,MAAM,EAAgB,IAChB,EAAc,IAEpB,SAAS,GAAO,CACd,EAAY,YAAY,CAAE,IAAK,EAAY,EADpC,YAIT,SAAS,GAAO,CACd,EAAc,iBAAiB,CAC7B,IAAK,EACL,UAAW,YAEP,OAAO,qKAEX,MAAO,CACL,QAAS,GAEX,qBAAsB,CACpB,MAAO,8CACP,GAAI,CACF,KAAM,CACJ,MAAO,8BAET,QAAS,CACP,MACE,iIAIT,EAtBM,mBAyBF,CACL,OACA,SAnCS","names":[],"ignoreList":[],"sources":["../../src/platform/cloud/subscription/composables/useSubscriptionDialog.ts"],"sourcesContent":["import { defineAsyncComponent } from 'vue'\nimport { useDialogService } from '@/services/dialogService'\nimport { useDialogStore } from '@/stores/dialogStore'\n\nconst DIALOG_KEY = 'subscription-required'\n\nexport const useSubscriptionDialog = () => {\n const dialogService = useDialogService()\n const dialogStore = useDialogStore()\n\n function hide() {\n dialogStore.closeDialog({ key: DIALOG_KEY })\n }\n\n function show() {\n dialogService.showLayoutDialog({\n key: DIALOG_KEY,\n component: defineAsyncComponent(\n () =>\n import('@/platform/cloud/subscription/components/SubscriptionRequiredDialogContent.vue')\n ),\n props: {\n onClose: hide\n },\n dialogComponentProps: {\n style: 'width: min(1328px, 95vw); max-height: 90vh;',\n pt: {\n root: {\n class: 'rounded-2xl bg-transparent'\n },\n content: {\n class:\n '!p-0 rounded-2xl border border-border-default bg-base-background/60 backdrop-blur-md shadow-[0_25px_80px_rgba(5,6,12,0.45)]'\n }\n }\n }\n })\n }\n\n return {\n show,\n hide\n }\n}\n"],"file":"useSubscriptionDialog-792qfEJ2.js"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./vendor-primevue-DcMRXJN3.js";import"./vendor-other-DlQF6V2E.js";import"./api-Dwq2LQIW.js";import"./remoteConfig-CZcEXsZS.js";import"./colorUtil-CzxntCbX.js";import"./useErrorHandling-Cfa5N_7c.js";import"./Button-Do2I1OAA.js";import"./PanelTemplate-BJda9e5J.js";import"./dialogService-YG0RH337.js";import"./vendor-tiptap-_UqYL7N_.js";import"./vendor-xterm-BU_lcTPR.js";import"./vendor-three-BFcUNSs9.js";import"./markdownRendererUtil-DglHsU8t.js";import"./userStore-BAS9m9W6.js";import{t as n}from"./useSubscriptionDialog-792qfEJ2.js";export{n as useSubscriptionDialog};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var S=Object.defineProperty;var s=(a,r)=>S(a,"name",{value:r,configurable:!0});import{To as C,za as o,zo as i}from"./vendor-other-DlQF6V2E.js";import{p as U}from"./vendor-vue-D9IUuwPJ.js";import{r as n}from"./api-
|
|
1
|
+
var S=Object.defineProperty;var s=(a,r)=>S(a,"name",{value:r,configurable:!0});import{To as C,za as o,zo as i}from"./vendor-other-DlQF6V2E.js";import{p as U}from"./vendor-vue-D9IUuwPJ.js";import{r as n}from"./api-Dwq2LQIW.js";const h=U("user",()=>{const a=i(null),r=i(null),u=o(()=>a.value&&"users"in a.value),f=o(()=>!r.value&&u.value),l=o(()=>Object.entries(a.value?.users??{}).map(([e,t])=>({userId:e,username:t}))),v=o(()=>l.value.find(e=>e.userId===r.value)??null),m=o(()=>a.value!==null);async function d(){a.value=await n.getUserConfig(),r.value=localStorage["Comfy.userId"]}s(d,"initialize");async function g(e){const t=await n.createUser(e),c=await t.json();if(t.status>=300)throw new Error(c.error??"Error creating user: "+t.status+" "+t.statusText);return{userId:c,username:e}}s(g,"createUser");async function p({userId:e,username:t}){r.value=e,localStorage["Comfy.userId"]=e,localStorage["Comfy.userName"]=t}s(p,"login"),C(()=>{u.value&&r.value&&(n.user=r.value)});async function y(){delete localStorage["Comfy.userId"],delete localStorage["Comfy.userName"]}return s(y,"logout"),{users:l,currentUser:v,isMultiUserServer:u,needsLogin:f,initialized:m,initialize:d,createUser:g,login:p,logout:y}});export{h as t};
|
|
2
2
|
|
|
3
|
-
//# sourceMappingURL=userStore-
|
|
3
|
+
//# sourceMappingURL=userStore-BAS9m9W6.js.map
|
comfyui_frontend_package/static/assets/{userStore-BkgQPjq6.js.map → userStore-BAS9m9W6.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userStore-
|
|
1
|
+
{"version":3,"file":"userStore-BAS9m9W6.js","names":[],"sources":["../../src/stores/userStore.ts"],"sourcesContent":["import { defineStore } from 'pinia'\nimport { computed, ref, watchEffect } from 'vue'\n\nimport type { User as UserConfig } from '@/schemas/apiSchema'\nimport { api } from '@/scripts/api'\n\nexport interface User {\n userId: string\n username: string\n}\n\nexport const useUserStore = defineStore('user', () => {\n /**\n * The user config. null if not loaded.\n */\n const userConfig = ref<UserConfig | null>(null)\n /**\n * The current user id. null if not logged in or in single user mode.\n */\n const currentUserId = ref<string | null>(null)\n const isMultiUserServer = computed(\n () => userConfig.value && 'users' in userConfig.value\n )\n const needsLogin = computed(\n () => !currentUserId.value && isMultiUserServer.value\n )\n const users = computed<User[]>(() =>\n Object.entries(userConfig.value?.users ?? {}).map(([userId, username]) => ({\n userId,\n username\n }))\n )\n const currentUser = computed<User | null>(\n () =>\n users.value.find((user) => user.userId === currentUserId.value) ?? null\n )\n const initialized = computed(() => userConfig.value !== null)\n\n /**\n * Initialize the user store.\n */\n async function initialize() {\n userConfig.value = await api.getUserConfig()\n currentUserId.value = localStorage['Comfy.userId']\n }\n\n /**\n * Create a new user.\n *\n * @param username - The username.\n * @returns The new user.\n */\n async function createUser(username: string): Promise<User> {\n const resp = await api.createUser(username)\n const data = await resp.json()\n if (resp.status >= 300) {\n throw new Error(\n data.error ??\n 'Error creating user: ' + resp.status + ' ' + resp.statusText\n )\n }\n return {\n userId: data,\n username\n }\n }\n\n /**\n * Login the current user.\n *\n * @param user - The user.\n */\n async function login({\n userId,\n username\n }: {\n userId: string\n username: string\n }) {\n currentUserId.value = userId\n localStorage['Comfy.userId'] = userId\n localStorage['Comfy.userName'] = username\n }\n\n watchEffect(() => {\n if (isMultiUserServer.value && currentUserId.value) {\n api.user = currentUserId.value\n }\n })\n\n /**\n * Logout the current user.\n */\n async function logout() {\n delete localStorage['Comfy.userId']\n delete localStorage['Comfy.userName']\n }\n\n return {\n users,\n currentUser,\n isMultiUserServer,\n needsLogin,\n initialized,\n initialize,\n createUser,\n login,\n logout\n }\n})\n"],"mappings":"kOAWA,MAAa,EAAe,EAAY,OAAA,IAAc,CAIpD,MAAM,EAAa,EAAuB,IAAA,EAIpC,EAAgB,EAAmB,IAAA,EACnC,EAAoB,EAAA,IAClB,EAAW,OAAS,UAAW,EAAW,KAAA,EAE5C,EAAa,EAAA,IACX,CAAC,EAAc,OAAS,EAAkB,KAAA,EAE5C,EAAQ,EAAA,IACZ,OAAO,QAAQ,EAAW,OAAO,OAAS,CAAA,CAAE,EAAE,IAAA,CAAK,CAAC,EAAQ,CAAA,KAAe,CACzE,OAAA,EACA,SAAA,GACD,CAAE,EAEC,EAAc,EAAA,IAEhB,EAAM,MAAM,KAAM,GAAS,EAAK,SAAW,EAAc,KAAA,GAAU,IAAA,EAEjE,EAAc,EAAA,IAAe,EAAW,QAAU,IAAA,EAKxD,eAAe,GAAa,CAC1B,EAAW,MAAQ,MAAM,EAAI,cAAA,EAC7B,EAAc,MAAQ,aAAa,cAAA,EAFtB,EAAA,EAAA,cAWf,eAAe,EAAW,EAAiC,CACzD,MAAM,EAAO,MAAM,EAAI,WAAW,CAAA,EAC5B,EAAO,MAAM,EAAK,KAAA,EACxB,GAAI,EAAK,QAAU,IACjB,MAAM,IAAI,MACR,EAAK,OACH,wBAA0B,EAAK,OAAS,IAAM,EAAK,UAAA,EAGzD,MAAO,CACL,OAAQ,EACR,SAAA,GAXW,EAAA,EAAA,cAoBf,eAAe,EAAM,CACnB,OAAA,EACA,SAAA,CAAA,EAIC,CACD,EAAc,MAAQ,EACtB,aAAa,cAAA,EAAkB,EAC/B,aAAa,gBAAA,EAAoB,EATpB,EAAA,EAAA,SAYf,EAAA,IAAkB,CACZ,EAAkB,OAAS,EAAc,QAC3C,EAAI,KAAO,EAAc,SAO7B,eAAe,GAAS,CACtB,OAAO,aAAa,cAAA,EACpB,OAAO,aAAa,gBAAA,EAFP,OAAA,EAAA,EAAA,UAKR,CACL,MAAA,EACA,YAAA,EACA,kBAAA,EACA,WAAA,EACA,YAAA,EACA,WAAA,EACA,WAAA,EACA,MAAA,EACA,OAAA"}
|