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.
Files changed (139) hide show
  1. comfyui_frontend_package/static/assets/{AboutPanel-CHse5rOA.js → AboutPanel-lkjGFasi.js} +2 -2
  2. comfyui_frontend_package/static/assets/{AboutPanel-CHse5rOA.js.map → AboutPanel-lkjGFasi.js.map} +1 -1
  3. comfyui_frontend_package/static/assets/{AudioPreviewPlayer-CAa8V66L.js → AudioPreviewPlayer-BxCSKPl9.js} +2 -2
  4. comfyui_frontend_package/static/assets/{AudioPreviewPlayer-CAa8V66L.js.map → AudioPreviewPlayer-BxCSKPl9.js.map} +1 -1
  5. comfyui_frontend_package/static/assets/AudioPreviewPlayer-CkxKvcVf.js +1 -0
  6. comfyui_frontend_package/static/assets/{BaseViewTemplate-DA6zfigT.js → BaseViewTemplate-CjODF2hh.js} +2 -2
  7. comfyui_frontend_package/static/assets/{BaseViewTemplate-DA6zfigT.js.map → BaseViewTemplate-CjODF2hh.js.map} +1 -1
  8. comfyui_frontend_package/static/assets/{CloudAuthTimeoutView-9OPBS1hE.js → CloudAuthTimeoutView-D-QkjPNh.js} +2 -2
  9. comfyui_frontend_package/static/assets/{CloudAuthTimeoutView-9OPBS1hE.js.map → CloudAuthTimeoutView-D-QkjPNh.js.map} +1 -1
  10. comfyui_frontend_package/static/assets/{CloudBadge-BnLiAHDN.js → CloudBadge-B4nmLus2.js} +2 -2
  11. comfyui_frontend_package/static/assets/{CloudBadge-BnLiAHDN.js.map → CloudBadge-B4nmLus2.js.map} +1 -1
  12. comfyui_frontend_package/static/assets/{CloudForgotPasswordView-BqDR_C7K.js → CloudForgotPasswordView-DOEV9hGr.js} +2 -2
  13. comfyui_frontend_package/static/assets/{CloudForgotPasswordView-BqDR_C7K.js.map → CloudForgotPasswordView-DOEV9hGr.js.map} +1 -1
  14. comfyui_frontend_package/static/assets/{CloudLayoutView-vTrrVUOY.js → CloudLayoutView-ShKH6rRV.js} +2 -2
  15. comfyui_frontend_package/static/assets/{CloudLayoutView-vTrrVUOY.js.map → CloudLayoutView-ShKH6rRV.js.map} +1 -1
  16. comfyui_frontend_package/static/assets/{CloudLoginView-T17euJly.js → CloudLoginView-C3Te42U9.js} +2 -2
  17. comfyui_frontend_package/static/assets/{CloudLoginView-T17euJly.js.map → CloudLoginView-C3Te42U9.js.map} +1 -1
  18. comfyui_frontend_package/static/assets/CloudRunButtonWrapper-Cub7EB34.js +3 -0
  19. comfyui_frontend_package/static/assets/{CloudRunButtonWrapper-hQc4BNkX.js.map → CloudRunButtonWrapper-Cub7EB34.js.map} +1 -1
  20. comfyui_frontend_package/static/assets/{CloudSignupView-vEDby5k3.js → CloudSignupView-X2oiL3ZR.js} +2 -2
  21. comfyui_frontend_package/static/assets/{CloudSignupView-vEDby5k3.js.map → CloudSignupView-X2oiL3ZR.js.map} +1 -1
  22. comfyui_frontend_package/static/assets/{CloudSubscriptionRedirectView-DPyO745g.js → CloudSubscriptionRedirectView-UjNv8emo.js} +2 -2
  23. comfyui_frontend_package/static/assets/{CloudSubscriptionRedirectView-DPyO745g.js.map → CloudSubscriptionRedirectView-UjNv8emo.js.map} +1 -1
  24. comfyui_frontend_package/static/assets/{CloudSurveyView-CBtTd9Ru.js → CloudSurveyView-IaiucCTP.js} +2 -2
  25. comfyui_frontend_package/static/assets/{CloudSurveyView-CBtTd9Ru.js.map → CloudSurveyView-IaiucCTP.js.map} +1 -1
  26. comfyui_frontend_package/static/assets/ComfyQueueButton-BppnHbrl.js +1 -0
  27. comfyui_frontend_package/static/assets/{ComfyQueueButton-MZrp7wYJ.js → ComfyQueueButton-HjSIKZKO.js} +2 -2
  28. comfyui_frontend_package/static/assets/{ComfyQueueButton-MZrp7wYJ.js.map → ComfyQueueButton-HjSIKZKO.js.map} +1 -1
  29. comfyui_frontend_package/static/assets/{ExtensionPanel-CrWVGUtg.js → ExtensionPanel-Bzb9QtKj.js} +2 -2
  30. comfyui_frontend_package/static/assets/{ExtensionPanel-CrWVGUtg.js.map → ExtensionPanel-Bzb9QtKj.js.map} +1 -1
  31. comfyui_frontend_package/static/assets/{GlobalToast-BiCmpIvO.js → GlobalToast-BSCvu6Hw.js} +2 -2
  32. comfyui_frontend_package/static/assets/{GlobalToast-BiCmpIvO.js.map → GlobalToast-BSCvu6Hw.js.map} +1 -1
  33. comfyui_frontend_package/static/assets/{GraphView-BCkpNGgz.js → GraphView-gYVCtm1V.js} +5 -5
  34. comfyui_frontend_package/static/assets/GraphView-gYVCtm1V.js.map +1 -0
  35. comfyui_frontend_package/static/assets/{KeybindingPanel-CAXL5TlV.js → KeybindingPanel-DF-bG4iO.js} +2 -2
  36. comfyui_frontend_package/static/assets/{KeybindingPanel-CAXL5TlV.js.map → KeybindingPanel-DF-bG4iO.js.map} +1 -1
  37. comfyui_frontend_package/static/assets/{LegacyCreditsPanel-6vR8koQy.js → LegacyCreditsPanel-D-CboO8k.js} +2 -2
  38. comfyui_frontend_package/static/assets/{LegacyCreditsPanel-6vR8koQy.js.map → LegacyCreditsPanel-D-CboO8k.js.map} +1 -1
  39. comfyui_frontend_package/static/assets/Load3D-c9UwgGoI.js +1 -0
  40. comfyui_frontend_package/static/assets/{Load3D-ei1BUF9O.js → Load3D-vYr8M3jJ.js} +2 -2
  41. comfyui_frontend_package/static/assets/{Load3D-ei1BUF9O.js.map → Load3D-vYr8M3jJ.js.map} +1 -1
  42. comfyui_frontend_package/static/assets/{PanelTemplate-BjN5XNg2.js → PanelTemplate-BJda9e5J.js} +2 -2
  43. comfyui_frontend_package/static/assets/{PanelTemplate-BjN5XNg2.js.map → PanelTemplate-BJda9e5J.js.map} +1 -1
  44. comfyui_frontend_package/static/assets/{ServerConfigPanel-CxovH9Qk.js → ServerConfigPanel-VsC6xlZJ.js} +2 -2
  45. comfyui_frontend_package/static/assets/{ServerConfigPanel-CxovH9Qk.js.map → ServerConfigPanel-VsC6xlZJ.js.map} +1 -1
  46. comfyui_frontend_package/static/assets/{SubscribeButton-CTOQRkfg.js → SubscribeButton-DZBycfCA.js} +2 -2
  47. comfyui_frontend_package/static/assets/{SubscribeButton-CTOQRkfg.js.map → SubscribeButton-DZBycfCA.js.map} +1 -1
  48. comfyui_frontend_package/static/assets/{SubscribeToRun-DnXzV8y0.js → SubscribeToRun-4YolxBOL.js} +2 -2
  49. comfyui_frontend_package/static/assets/{SubscribeToRun-DnXzV8y0.js.map → SubscribeToRun-4YolxBOL.js.map} +1 -1
  50. comfyui_frontend_package/static/assets/{SubscriptionPanel-D9uv7z8f.js → SubscriptionPanel-B6txX4Vm.js} +2 -2
  51. comfyui_frontend_package/static/assets/{SubscriptionPanel-D9uv7z8f.js.map → SubscriptionPanel-B6txX4Vm.js.map} +1 -1
  52. comfyui_frontend_package/static/assets/{SubscriptionRequiredDialogContent--VmT16oc.js → SubscriptionRequiredDialogContent-COEF2VQ_.js} +2 -2
  53. comfyui_frontend_package/static/assets/{SubscriptionRequiredDialogContent--VmT16oc.js.map → SubscriptionRequiredDialogContent-COEF2VQ_.js.map} +1 -1
  54. comfyui_frontend_package/static/assets/{UserCheckView-spD3LyMu.js → UserCheckView-x-fkcYzc.js} +2 -2
  55. comfyui_frontend_package/static/assets/{UserCheckView-spD3LyMu.js.map → UserCheckView-x-fkcYzc.js.map} +1 -1
  56. comfyui_frontend_package/static/assets/{UserPanel-Su6NtJ5q.js → UserPanel-7N9QknQj.js} +2 -2
  57. comfyui_frontend_package/static/assets/{UserPanel-Su6NtJ5q.js.map → UserPanel-7N9QknQj.js.map} +1 -1
  58. comfyui_frontend_package/static/assets/{UserSelectView-C5LBOPcv.js → UserSelectView-BYjOkfSa.js} +2 -2
  59. comfyui_frontend_package/static/assets/{UserSelectView-C5LBOPcv.js.map → UserSelectView-BYjOkfSa.js.map} +1 -1
  60. comfyui_frontend_package/static/assets/{ValueControlPopover-BdlDzT8l.js → ValueControlPopover-BPAa35QG.js} +2 -2
  61. comfyui_frontend_package/static/assets/{ValueControlPopover-BdlDzT8l.js.map → ValueControlPopover-BPAa35QG.js.map} +1 -1
  62. comfyui_frontend_package/static/assets/{WidgetAudioUI-BDZxDx_r.js → WidgetAudioUI-Dw-r3Ews.js} +2 -2
  63. comfyui_frontend_package/static/assets/{WidgetAudioUI-BDZxDx_r.js.map → WidgetAudioUI-Dw-r3Ews.js.map} +1 -1
  64. comfyui_frontend_package/static/assets/{WidgetImageCrop-CYRW7t2Q.js → WidgetImageCrop-kERy9g5I.js} +2 -2
  65. comfyui_frontend_package/static/assets/{WidgetImageCrop-CYRW7t2Q.js.map → WidgetImageCrop-kERy9g5I.js.map} +1 -1
  66. comfyui_frontend_package/static/assets/{WidgetInputNumber-BOKO36G3.js → WidgetInputNumber-BaClCNAC.js} +1 -1
  67. comfyui_frontend_package/static/assets/WidgetInputNumber-DU_D0Fzy.js +3 -0
  68. comfyui_frontend_package/static/assets/WidgetInputNumber-DU_D0Fzy.js.map +1 -0
  69. comfyui_frontend_package/static/assets/{WidgetLegacy-Bslv9wZZ.js → WidgetLegacy-B4nipUM9.js} +1 -1
  70. comfyui_frontend_package/static/assets/{WidgetRecordAudio-Bzy8PIzN.js → WidgetRecordAudio-Nk8dH238.js} +2 -2
  71. comfyui_frontend_package/static/assets/{WidgetRecordAudio-Bzy8PIzN.js.map → WidgetRecordAudio-Nk8dH238.js.map} +1 -1
  72. comfyui_frontend_package/static/assets/WidgetSelect-DzZPpO_-.js +1 -0
  73. comfyui_frontend_package/static/assets/{WidgetSelect-zgrFVzHH.js → WidgetSelect-nSQrk_hd.js} +2 -2
  74. comfyui_frontend_package/static/assets/{WidgetSelect-zgrFVzHH.js.map → WidgetSelect-nSQrk_hd.js.map} +1 -1
  75. comfyui_frontend_package/static/assets/{WidgetWithControl-Dh2FWOiA.js → WidgetWithControl-Da6zUB5e.js} +3 -3
  76. comfyui_frontend_package/static/assets/{WidgetWithControl-Dh2FWOiA.js.map → WidgetWithControl-Da6zUB5e.js.map} +1 -1
  77. comfyui_frontend_package/static/assets/{api-CUAc7rDA.js → api-Dwq2LQIW.js} +4 -4
  78. comfyui_frontend_package/static/assets/api-Dwq2LQIW.js.map +1 -0
  79. comfyui_frontend_package/static/assets/{audioService-DvndbCi2.js → audioService-DvVaKhuU.js} +2 -2
  80. comfyui_frontend_package/static/assets/{audioService-DvndbCi2.js.map → audioService-DvVaKhuU.js.map} +1 -1
  81. comfyui_frontend_package/static/assets/{audioUtils-DpjpcKbH.js → audioUtils-DD4rUYVZ.js} +2 -2
  82. comfyui_frontend_package/static/assets/{audioUtils-DpjpcKbH.js.map → audioUtils-DD4rUYVZ.js.map} +1 -1
  83. comfyui_frontend_package/static/assets/{auth-B8ZZ0KKQ.js → auth-B9axG-yZ.js} +2 -2
  84. comfyui_frontend_package/static/assets/{auth-B8ZZ0KKQ.js.map → auth-B9axG-yZ.js.map} +1 -1
  85. comfyui_frontend_package/static/assets/auth-D74DTev8.js +1 -0
  86. comfyui_frontend_package/static/assets/{cloudBadges-C1a7fBky.js → cloudBadges-D5mGJbRy.js} +2 -2
  87. comfyui_frontend_package/static/assets/{cloudBadges-C1a7fBky.js.map → cloudBadges-D5mGJbRy.js.map} +1 -1
  88. comfyui_frontend_package/static/assets/{cloudFeedbackTopbarButton-DR0T8sWG.js → cloudFeedbackTopbarButton-RZUssOmb.js} +2 -2
  89. comfyui_frontend_package/static/assets/{cloudFeedbackTopbarButton-DR0T8sWG.js.map → cloudFeedbackTopbarButton-RZUssOmb.js.map} +1 -1
  90. comfyui_frontend_package/static/assets/{cloudRemoteConfig-DhMjC5TB.js → cloudRemoteConfig-F9J0iGyF.js} +2 -2
  91. comfyui_frontend_package/static/assets/{cloudRemoteConfig-DhMjC5TB.js.map → cloudRemoteConfig-F9J0iGyF.js.map} +1 -1
  92. comfyui_frontend_package/static/assets/{cloudSessionCookie-Duxk6ux1.js → cloudSessionCookie-MEORlqtg.js} +2 -2
  93. comfyui_frontend_package/static/assets/{cloudSessionCookie-Duxk6ux1.js.map → cloudSessionCookie-MEORlqtg.js.map} +1 -1
  94. comfyui_frontend_package/static/assets/{cloudSubscription-B8l6B9Nx.js → cloudSubscription-CuWNXKVx.js} +2 -2
  95. comfyui_frontend_package/static/assets/{cloudSubscription-B8l6B9Nx.js.map → cloudSubscription-CuWNXKVx.js.map} +1 -1
  96. comfyui_frontend_package/static/assets/{core-DBfeqMDR.js → core-IYu8XAIx.js} +4 -4
  97. comfyui_frontend_package/static/assets/{core-DBfeqMDR.js.map → core-IYu8XAIx.js.map} +1 -1
  98. comfyui_frontend_package/static/assets/{dialogService-BZ1FmjZL.js → dialogService-YG0RH337.js} +9 -9
  99. comfyui_frontend_package/static/assets/{dialogService-BZ1FmjZL.js.map → dialogService-YG0RH337.js.map} +1 -1
  100. comfyui_frontend_package/static/assets/firebaseAuthStore-DnNaPbuZ.js +1 -0
  101. comfyui_frontend_package/static/assets/{graphHasMissingNodes-C79Wi51S.js → graphHasMissingNodes-BhD1N6zI.js} +2 -2
  102. comfyui_frontend_package/static/assets/{graphHasMissingNodes-C79Wi51S.js.map → graphHasMissingNodes-BhD1N6zI.js.map} +1 -1
  103. comfyui_frontend_package/static/assets/{index-CGxJFSof.js → index-BMy3twho.js} +3 -3
  104. comfyui_frontend_package/static/assets/{index-CGxJFSof.js.map → index-BMy3twho.js.map} +1 -1
  105. comfyui_frontend_package/static/assets/{index-DNpOhRra.css → index-KMO9qFHH.css} +1 -1
  106. comfyui_frontend_package/static/assets/{keybindingService-B88NjeAU.js → keybindingService-CBLPjYHI.js} +2 -2
  107. comfyui_frontend_package/static/assets/{keybindingService-B88NjeAU.js.map → keybindingService-CBLPjYHI.js.map} +1 -1
  108. comfyui_frontend_package/static/assets/{releaseStore-x0vHjxrw.js → releaseStore-DDOxzkVb.js} +2 -2
  109. comfyui_frontend_package/static/assets/{releaseStore-x0vHjxrw.js.map → releaseStore-DDOxzkVb.js.map} +1 -1
  110. comfyui_frontend_package/static/assets/releaseStore-iVkqunL8.js +1 -0
  111. comfyui_frontend_package/static/assets/{subscriptionCheckoutUtil-B_OvUP2T.js → subscriptionCheckoutUtil-DswSOreM.js} +2 -2
  112. comfyui_frontend_package/static/assets/{subscriptionCheckoutUtil-B_OvUP2T.js.map → subscriptionCheckoutUtil-DswSOreM.js.map} +1 -1
  113. comfyui_frontend_package/static/assets/{useCurrentUser-BJcn2Vgo.js → useCurrentUser-NdaCJzIK.js} +1 -1
  114. comfyui_frontend_package/static/assets/{useErrorHandling-CI8_F4yx.js → useErrorHandling-Cfa5N_7c.js} +2 -2
  115. comfyui_frontend_package/static/assets/{useErrorHandling-CI8_F4yx.js.map → useErrorHandling-Cfa5N_7c.js.map} +1 -1
  116. comfyui_frontend_package/static/assets/{useSubscriptionDialog-Chxkdny5.js → useSubscriptionDialog-792qfEJ2.js} +3 -3
  117. comfyui_frontend_package/static/assets/{useSubscriptionDialog-Chxkdny5.js.map → useSubscriptionDialog-792qfEJ2.js.map} +1 -1
  118. comfyui_frontend_package/static/assets/useSubscriptionDialog-B-eGeK3j.js +1 -0
  119. comfyui_frontend_package/static/assets/{userStore-BkgQPjq6.js → userStore-BAS9m9W6.js} +2 -2
  120. comfyui_frontend_package/static/assets/{userStore-BkgQPjq6.js.map → userStore-BAS9m9W6.js.map} +1 -1
  121. comfyui_frontend_package/static/assets/vendor-three-BFcUNSs9.js.map +1 -1
  122. comfyui_frontend_package/static/index.html +1 -1
  123. {comfyui_frontend_package-1.38.5.dist-info → comfyui_frontend_package-1.38.6.dist-info}/METADATA +1 -1
  124. {comfyui_frontend_package-1.38.5.dist-info → comfyui_frontend_package-1.38.6.dist-info}/RECORD +126 -126
  125. comfyui_frontend_package/static/assets/AudioPreviewPlayer-BoEdyGI_.js +0 -1
  126. comfyui_frontend_package/static/assets/CloudRunButtonWrapper-hQc4BNkX.js +0 -3
  127. comfyui_frontend_package/static/assets/ComfyQueueButton-BbQnRThI.js +0 -1
  128. comfyui_frontend_package/static/assets/GraphView-BCkpNGgz.js.map +0 -1
  129. comfyui_frontend_package/static/assets/Load3D-DHBmC_AU.js +0 -1
  130. comfyui_frontend_package/static/assets/WidgetInputNumber-DGKypM5j.js +0 -3
  131. comfyui_frontend_package/static/assets/WidgetInputNumber-DGKypM5j.js.map +0 -1
  132. comfyui_frontend_package/static/assets/WidgetSelect-DsJGH12l.js +0 -1
  133. comfyui_frontend_package/static/assets/api-CUAc7rDA.js.map +0 -1
  134. comfyui_frontend_package/static/assets/auth-D3RiiqZ8.js +0 -1
  135. comfyui_frontend_package/static/assets/firebaseAuthStore-CZgxeMyf.js +0 -1
  136. comfyui_frontend_package/static/assets/releaseStore-CubqSv5t.js +0 -1
  137. comfyui_frontend_package/static/assets/useSubscriptionDialog-BzMzio2H.js +0 -1
  138. {comfyui_frontend_package-1.38.5.dist-info → comfyui_frontend_package-1.38.6.dist-info}/WHEEL +0 -0
  139. {comfyui_frontend_package-1.38.5.dist-info → comfyui_frontend_package-1.38.6.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,7 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./cloudRemoteConfig-DhMjC5TB.js","./vendor-primevue-DcMRXJN3.js","./vendor-other-DlQF6V2E.js","./rolldown-runtime-BN4meiq5.js","./vendor-other-CaaUC6Qe.css","./dialogService-BZ1FmjZL.js","./_plugin-vue_export-helper-PHE0iSCb.js","./vendor-vue-D9IUuwPJ.js","./vendor-three-BFcUNSs9.js","./vendor-tiptap-_UqYL7N_.js","./vendor-xterm-BU_lcTPR.js","./vendor-xterm-kHJ-D0s7.css","./PanelTemplate-BjN5XNg2.js","./api-CUAc7rDA.js","./widget-DNFXpyU8.js","./colorUtil-CzxntCbX.js","./src-DTrob8OL.js","./Button-Do2I1OAA.js","./vendor-reka-ui-CmnTduBl.js","./Slider-De1ykl8L.js","./useErrorHandling-CI8_F4yx.js","./remoteConfig-CZcEXsZS.js","./userStore-BkgQPjq6.js","./markdownRendererUtil-DglHsU8t.js","./dialogService-BMbgJ9MG.css","./cloudBadges-C1a7fBky.js","./cloudSessionCookie-Duxk6ux1.js","./cloudFeedbackTopbarButton-DR0T8sWG.js","./cloudSubscription-B8l6B9Nx.js"])))=>i.map(i=>d[i]);
2
- var ft=Object.defineProperty;var u=(e,t)=>ft(e,"name",{value:t,configurable:!0});import{r as ht}from"./rolldown-runtime-BN4meiq5.js";import{dt as se}from"./vendor-primevue-DcMRXJN3.js";import{Bo as mt,Pr as q,io as Ee,kr as yt,n as wt}from"./vendor-other-DlQF6V2E.js";import{A as _,Bt as vt,It as M,Lt as bt,N as Nt,S as It,Z as Ct,_ as kt,b as he,f as k,ft as G,m as L,r as E,v as Dt,wt as _t,y as xt,zt as ot}from"./api-CUAc7rDA.js";import"./remoteConfig-CZcEXsZS.js";import"./colorUtil-CzxntCbX.js";import"./useErrorHandling-CI8_F4yx.js";import"./Button-Do2I1OAA.js";import{k as Tt,v as St,w as Mt}from"./PanelTemplate-BjN5XNg2.js";import{B as Et,Cr as Ot,Dn as At,Fn as Lt,Gr as Oe,In as Pt,Ln as Gt,N as S,On as Wt,P as g,R as Rt,Rn as Ft,Sn as K,Sr as Ut,Tn as $,Tr as Bt,U as Vt,W as V,Wr as Ae,Xn as nt,Yr as J,Zr as Be,_r as $t,at as ge,br as Ve,cn as zt,dn as jt,dt as Ht,fn as ue,gr as it,hr as N,it as qt,mt as Yt,nt as P,ot as st,pn as W,t as re,tt as ae,un as me,vr as rt,w as Xt,wn as Jt,wr as Kt,xr as xe,yr as ne,z as at}from"./dialogService-BZ1FmjZL.js";import"./vendor-tiptap-_UqYL7N_.js";import"./vendor-xterm-BU_lcTPR.js";import"./vendor-three-BFcUNSs9.js";import"./markdownRendererUtil-DglHsU8t.js";import"./userStore-BkgQPjq6.js";import{t as Le}from"./Load3D-ei1BUF9O.js";import{i as lt,r as ye}from"./audioUtils-DpjpcKbH.js";import{t as Z}from"./audioService-DvndbCi2.js";var ee=class B extends it{static{u(this,"ClipspaceDialog")}static items=[];static instance=null;static registerButton(t,i,n){const o=N("button",{type:"button",textContent:t,contextPredicate:i,onclick:n});B.items.push(o)}static invalidatePreview(){if(S.clipspace&&S.clipspace.imgs&&S.clipspace.imgs.length>0){const t=document.getElementById("clipspace_preview");t&&(t.src=S.clipspace.imgs[S.clipspace.selectedIndex].src,t.style.maxHeight="100%",t.style.maxWidth="100%")}}static invalidate(){if(B.instance){const t=B.instance,i=N("div.comfy-modal-content",[t.createImgSettings(),...t.createButtons()]);t.element?(t.element.firstChild&&t.element.removeChild(t.element.firstChild),t.element.appendChild(i)):t.element=N("div.comfy-modal",{parent:document.body},[i]),t.element.children[0].children.length<=1&&t.element.children[0].appendChild(N("p",{},["Unable to find the features to edit content of a format stored in the current Clipspace."])),B.invalidatePreview()}}constructor(){super()}createButtons(){const t=[];for(let i in B.items){const n=B.items[i];(!n.contextPredicate||n.contextPredicate())&&t.push(B.items[i])}return t.push(N("button",{type:"button",textContent:"Close",onclick:u(()=>{this.close()},"onclick")})),t}createImgSettings(){if(S.clipspace?.imgs){const t=[],i=S.clipspace.imgs;for(let r=0;r<i.length;r++)t.push(N("option",{value:r},[`${r}`]));const n=N("select",{id:"clipspace_img_selector",onchange:u(r=>{r.target&&S.clipspace&&(S.clipspace.selectedIndex=r.target.selectedIndex,B.invalidatePreview())},"onchange")},t),o=N("tr",{},[N("td",{},[N("font",{color:"white"},["Select Image"])]),N("td",{},[n])]),s=N("select",{id:"clipspace_img_paste_mode",onchange:u(r=>{r.target&&S.clipspace&&(S.clipspace.img_paste_mode=r.target.value)},"onchange")},[N("option",{value:"selected"},"selected"),N("option",{value:"all"},"all")]);return s.value=S.clipspace.img_paste_mode,N("table",{},[o,N("tr",{},[N("td",{},[N("font",{color:"white"},["Paste Mode"])]),N("td",{},[s])]),N("tr",{},[N("td",{align:"center",width:"100px",height:"100px",colSpan:"2"},[N("img",{id:"clipspace_preview",ondragstart:u(()=>!1,"ondragstart")},[])])])])}else return[]}createImgPreview(){return S.clipspace?.imgs?N("img",{id:"clipspace_preview",ondragstart:u(()=>!1,"ondragstart")}):[]}show(){B.invalidate(),this.element.style.display="block"}};g.registerExtension({name:"Comfy.Clipspace",init(e){e.openClipspace=function(){ee.instance||(ee.instance=new ee,S.clipspace_invalidate_handler=ee.invalidate),S.clipspace?ee.instance.show():e.ui.dialog.show("Clipspace is Empty!")}}});window.comfyAPI=window.comfyAPI||{};window.comfyAPI.clipspace=window.comfyAPI.clipspace||{};window.comfyAPI.clipspace.ClipspaceDialog=ee;g.registerExtension({name:"Comfy.ContextMenuFilter",init(){const e=k.ContextMenu;k.ContextMenu=function(t,i){const n=new e(t,i);if(i?.className==="dark"&&t?.length>4){const o=document.createElement("input");o.classList.add("comfy-context-menu-filter"),o.placeholder="Filter list",n.root.prepend(o);const s=Array.from(n.root.querySelectorAll(".litemenu-entry"));let r=[...s],a=r.length;requestAnimationFrame(()=>{const l=L.active_canvas.current_node?.widgets?.filter(w=>It(w)&&w.options.values?.length===t.length).find(w=>w.options.values?.every((p,y)=>p===t[y]))?.value;let d=l?t.findIndex(w=>w===l):0;d<0&&(d=0);let c=r[d];m();function m(){c?.style.setProperty("background-color",""),c?.style.setProperty("color",""),c=r[d],c?.style.setProperty("background-color","#ccc","important"),c?.style.setProperty("color","#000","important")}u(m,"updateSelected");const h=u(()=>{if(n.root.getBoundingClientRect().top<0){const w=1-n.root.getBoundingClientRect().height/n.root.clientHeight,p=n.root.clientHeight*w/2;n.root.style.top=-p+"px"}},"positionList");o.addEventListener("keydown",w=>{switch(w.key){case"ArrowUp":w.preventDefault(),d===0?d=a-1:d--,m();break;case"ArrowRight":w.preventDefault(),d=a-1,m();break;case"ArrowDown":w.preventDefault(),d===a-1?d=0:d++,m();break;case"ArrowLeft":w.preventDefault(),d=0,m();break;case"Enter":c?.click();break;case"Escape":n.close();break}}),o.addEventListener("input",()=>{const w=o.value.toLocaleLowerCase();if(r=s.filter(p=>{const y=!w||p.textContent?.toLocaleLowerCase().includes(w);return p.style.display=y?"block":"none",y}),d=0,r.includes(c)&&(d=r.findIndex(p=>p===c)),a=r.length,m(),i.event){let p=i.event.clientY-10;const y=document.body.getBoundingClientRect(),v=n.root.getBoundingClientRect();y.height&&p>y.height-v.height-10&&(p=Math.max(0,y.height-v.height-10)),n.root.style.top=p+"px",h()}}),requestAnimationFrame(()=>{o.focus(),h()})})}return n},k.ContextMenu.prototype=e.prototype}});function Qt(e=[]){if(!this.outputs[0].links?.length||!this.graph)return;const t=[...this.outputs[0].links.map(n=>this.graph.links[n]),...e];let i=this.widgets?.[0].value;for(const n of t){const o=this.graph?.getNodeById(n.target_id),s=o?.inputs[n.target_slot];if(!s){console.warn("Unable to resolve node or input for link",n);continue}const r=s.widget?.name;if(!r){console.warn("Invalid widget or widget name",s.widget);continue}const a=o.widgets?.find(l=>l.name===r);if(!a){console.warn(`Unable to find widget "${r}" on node [${o.id}]`);continue}a.value=i,a.callback?.(a.value,g.canvas,o,g.canvas.graph_mouse,{})}}u(Qt,"applyToGraph");function Zt(){this.applyToGraph=J(this.applyToGraph,Qt);const e=this.widgets[0],t=mt([]);e.options.values=t;const i=u(()=>{t.splice(0,t.length,...this.widgets.filter(o=>o.name.startsWith("option")&&o.value).map(o=>`${o.value}`)),!g.configuringGraph&&(t.includes(`${e.value}`)||(e.value=t[0]??"",e.callback?.(e.value)))},"updateCombo");e.callback=J(e.callback,()=>this.applyToGraph());function n(o){if(!o.widgets)return;const s=o.widgets.length-1;o.addWidget("string",`option${s}`,"",()=>{});const r=o.widgets.at(-1);if(!r)return;let a="";Object.defineProperty(r,"value",{get(){return a},set(l){if(a=l,i(),!o.widgets)return;const d=o.widgets.at(-1);if(d===this){l&&n(o);return}l||o.widgets.at(-2)!==this||d?.value||(o.widgets.pop(),o.computeSize(o.size),this.callback(l))}})}u(n,"addOption"),n(this)}u(Zt,"onNodeCreated");g.registerExtension({name:"Comfy.CustomCombo",beforeRegisterNodeDef(e,t){t?.name==="CustomCombo"&&(e.prototype.onNodeCreated=J(e.prototype.onNodeCreated,Zt))}});K().registerExtension({name:"Comfy.DynamicPrompts",nodeCreated(e){if(e.widgets){const t=e.widgets.filter(i=>i.dynamicPrompts);for(const i of t)i.serializeValue=(n,o)=>{if(typeof i.value!="string")return i.value;const s=Mt(i.value);return n?.widgets_values&&(n.widgets_values[o]=s),s}}}});g.registerExtension({name:"Comfy.EditAttention",init(){const e=g.ui.settings.addSetting({id:"Comfy.EditAttention.Delta",category:["Comfy","EditTokenWeight","Delta"],name:"Ctrl+up/down precision",type:"slider",attrs:{min:.01,max:.5,step:.01},defaultValue:.05});function t(s,r){const a=parseFloat(s);if(isNaN(a))return s;const l=a+r;return String(Number(l.toFixed(10)))}u(t,"incrementWeight");function i(s,r){let a=r,l=r,d=0,c=0;for(;a>=0&&(a--,!(s[a]==="("&&d===c));)s[a]==="("&&d++,s[a]===")"&&c++;if(a<0)return null;for(d=0,c=0;l<s.length&&!(s[l]===")"&&d===c);)s[l]==="("&&d++,s[l]===")"&&c++,l++;return l===s.length?null:{start:a+1,end:l}}u(i,"findNearestEnclosure");function n(s){const r=s.match(/^\((.*)\)$/),a=s.match(/:([+-]?(\d*\.)?\d+([eE][+-]?\d+)?)/);return r&&!a?`(${r[1]}:1.0)`:s}u(n,"addWeightToParentheses");function o(s){const r=s.composedPath()[0],a=parseFloat(e.value);if(r.tagName!=="TEXTAREA"||!(s.key==="ArrowUp"||s.key==="ArrowDown")||!s.ctrlKey&&!s.metaKey)return;s.preventDefault();let l=r.selectionStart,d=r.selectionEnd,c=r.value.substring(l,d);if(!c){const w=i(r.value,l);if(w)l=w.start,d=w.end,c=r.value.substring(l,d);else{const p=" .,\\/!?%^*;:{}=-_`~()\r\n ";for(;!p.includes(r.value[l-1])&&l>0;)l--;for(;!p.includes(r.value[d])&&d<r.value.length;)d++;if(c=r.value.substring(l,d),!c)return}}c[c.length-1]===" "&&(c=c.substring(0,c.length-1),d-=1),r.value[l-1]==="("&&r.value[d]===")"&&(l-=1,d+=1,c=r.value.substring(l,d)),(c[0]!=="("||c[c.length-1]!==")")&&(c=`(${c})`),c=n(c);const m=s.key==="ArrowUp"?a:-a,h=c.replace(/\((.*):([+-]?\d+(?:\.\d+)?)\)/,(w,p,y)=>(y=t(y,m),y==1?p:`(${p}:${y})`));r.setSelectionRange(l,d),document.execCommand("insertText",!1,h),r.setSelectionRange(l,l+h.length)}u(o,"editAttention"),window.addEventListener("keydown",o)}});var $e=ht(yt(),1);const eo={settingId:"Comfy-Desktop.UV.PythonInstallMirror",mirror:"https://github.com/astral-sh/python-build-standalone/releases/download",fallbackMirror:"https://python-standalone.org/mirror/astral-sh/python-build-standalone",validationPathSuffix:"/20250115/cpython-3.10.16+20250115-aarch64-apple-darwin-debug-full.tar.zst.sha256"},Ce=u(async e=>St(e)&&await ot().NetWork.canAccessUrl(e),"checkMirrorReachable");(async()=>{if(!vt())return;const e=ot(),t=await e.getElectronVersion(),i=Xt(),n=M(),{staticUrls:o,buildDocsUrl:s}=Tt(),r=u((a,l)=>{l!==void 0&&a!==l&&e.restartApp("Restart ComfyUI to apply changes.",1500)},"onChangeRestartApp");g.registerExtension({name:"Comfy.ElectronAdapter",settings:[{id:"Comfy-Desktop.AutoUpdate",category:["Comfy-Desktop","General","AutoUpdate"],name:"Automatically check for updates",type:"boolean",defaultValue:!0,onChange:r},{id:"Comfy-Desktop.SendStatistics",category:["Comfy-Desktop","General","Send Statistics"],name:"Send anonymous usage metrics",type:"boolean",defaultValue:!0,onChange:r},{id:"Comfy-Desktop.WindowStyle",category:["Comfy-Desktop","General","Window Style"],name:"Window Style",tooltip:"Custom: Replace the system title bar with ComfyUI's Top menu",type:"combo",experimental:!0,defaultValue:"default",options:["default","custom"],onChange:u((a,l)=>{l&&e.Config.setWindowStyle(a)},"onChange")},{id:"Comfy-Desktop.UV.PythonInstallMirror",name:"Python Install Mirror",tooltip:"Managed Python installations are downloaded from the Astral python-build-standalone project. This variable can be set to a mirror URL to use a different source for Python installations. The provided URL will replace https://github.com/astral-sh/python-build-standalone/releases/download in, e.g., https://github.com/astral-sh/python-build-standalone/releases/download/20240713/cpython-3.12.4%2B20240713-aarch64-apple-darwin-install_only.tar.gz. Distributions can be read from a local directory by using the file:// URL scheme.",type:"url",defaultValue:"",attrs:{validateUrlFn(a){return Ce(a+eo.validationPathSuffix)}}},{id:"Comfy-Desktop.UV.PypiInstallMirror",name:"Pypi Install Mirror",tooltip:"Default pip install mirror",type:"url",defaultValue:"",attrs:{validateUrlFn:Ce}},{id:"Comfy-Desktop.UV.TorchInstallMirror",name:"Torch Install Mirror",tooltip:"Pip install mirror for pytorch",type:"url",defaultValue:"",attrs:{validateUrlFn:Ce}}],commands:[{id:"Comfy-Desktop.Folders.OpenLogsFolder",label:"Open Logs Folder",icon:"pi pi-folder-open",function(){e.openLogsFolder()}},{id:"Comfy-Desktop.Folders.OpenModelsFolder",label:"Open Models Folder",icon:"pi pi-folder-open",function(){e.openModelsFolder()}},{id:"Comfy-Desktop.Folders.OpenOutputsFolder",label:"Open Outputs Folder",icon:"pi pi-folder-open",function(){e.openOutputsFolder()}},{id:"Comfy-Desktop.Folders.OpenInputsFolder",label:"Open Inputs Folder",icon:"pi pi-folder-open",function(){e.openInputsFolder()}},{id:"Comfy-Desktop.Folders.OpenCustomNodesFolder",label:"Open Custom Nodes Folder",icon:"pi pi-folder-open",function(){e.openCustomNodesFolder()}},{id:"Comfy-Desktop.Folders.OpenModelConfig",label:"Open extra_model_paths.yaml",icon:"pi pi-file",function(){e.openModelConfig()}},{id:"Comfy-Desktop.OpenDevTools",label:"Open DevTools",icon:"pi pi-code",function(){e.openDevTools()}},{id:"Comfy-Desktop.OpenUserGuide",label:"Desktop User Guide",icon:"pi pi-book",function(){window.open(s("/installation/desktop",{includeLocale:!0,platform:!0}),"_blank")}},{id:"Comfy-Desktop.CheckForUpdates",label:"Check for Updates",icon:"pi pi-sync",async function(){try{const a=await e.checkForUpdates({disableUpdateReadyAction:!0});if(!a.isUpdateAvailable){n.add({severity:"info",summary:_("desktopUpdate.noUpdateFound"),life:5e3});return}if(await re().confirm({title:_("desktopUpdate.updateFoundTitle",{version:a.version}),message:_("desktopUpdate.updateAvailableMessage"),type:"default"}))try{e.restartAndInstall()}catch(l){$e.default.error("Error installing update:",l),n.add({severity:"error",summary:_("g.error"),detail:_("desktopUpdate.errorInstallingUpdate"),life:1e4})}}catch(a){$e.default.error("Error checking for updates:",a),n.add({severity:"error",summary:_("g.error"),detail:_("desktopUpdate.errorCheckingUpdate"),life:1e4})}}},{id:"Comfy-Desktop.Reinstall",label:"Reinstall",icon:"pi pi-refresh",async function(){await re().confirm({message:_("desktopMenu.confirmReinstall"),title:_("desktopMenu.reinstall"),type:"reinstall"})&&e.reinstall()}},{id:"Comfy-Desktop.Restart",label:"Restart",icon:"pi pi-refresh",function(){e.restartApp()}},{id:"Comfy-Desktop.Quit",label:"Quit",icon:"pi pi-sign-out",async function(){i.modifiedWorkflows.length>0&&!await re().confirm({message:_("desktopMenu.confirmQuit"),title:_("desktopMenu.quit"),type:"default"})||e.quit()}}],menuCommands:[{path:["Help"],commands:["Comfy-Desktop.OpenUserGuide"]},{path:["Help"],commands:["Comfy-Desktop.OpenDevTools"]},{path:["Help","Open Folder"],commands:["Comfy-Desktop.Folders.OpenLogsFolder","Comfy-Desktop.Folders.OpenModelsFolder","Comfy-Desktop.Folders.OpenOutputsFolder","Comfy-Desktop.Folders.OpenInputsFolder","Comfy-Desktop.Folders.OpenCustomNodesFolder","Comfy-Desktop.Folders.OpenModelConfig"]},{path:["Help"],commands:["Comfy-Desktop.CheckForUpdates","Comfy-Desktop.Reinstall"]}],keybindings:[{commandId:"Workspace.CloseWorkflow",combo:{key:"w",ctrl:!0}}],aboutPageBadges:[{label:"ComfyUI_desktop v"+t,url:o.githubElectron,icon:"pi pi-github"}]})})();var to=class extends Dt{static{u(this,"ExecutableGroupNodeChildDTO")}groupNodeHandler;constructor(e,t,i,n,o){super(e,t,i,n),this.groupNodeHandler=o}resolveInput(e){if(this.id.split(":").length>2)throw new Error("Group nodes inside subgraphs are not supported. Please convert the group node to a subgraph instead.");const t=this.node.getInputNode(e);if(!t)return;const i=this.node.getInputLink(e);if(!i)throw new Error("Failed to get input link");const n=String(t.id);let o=this.nodesByExecutionId?.get(n);if(!o){const s=n.split(":").at(-1);s!==void 0&&(o=this.nodesByExecutionId?.get(s))}if(!o)throw new Error(`Failed to get input node ${n} for group node child ${this.id} with slot ${e}`);return{node:o,origin_id:n,origin_slot:i.origin_slot}}},ke=Symbol();function dt(e,t){if(typeof e=="object"&&typeof t=="object")for(const i in t){const n=t[i];if(typeof n=="object"){let o=e[i];o||(o=e[i]={}),dt(o,t[i])}else e[i]=n}return e}u(dt,"merge");var ct=class extends $t{static{u(this,"ManageGroupDialog")}tabs;selectedNodeIndex;selectedTab="Inputs";selectedGroup;modifications={};nodeItems;app;groupNodeType;groupNodeDef;groupData;innerNodesList;widgetsPage;inputsPage;outputsPage;draggable;get selectedNodeInnerIndex(){return+this.nodeItems[this.selectedNodeIndex].dataset.nodeindex}constructor(e){super(),this.app=e,this.element=N("dialog.comfy-group-manage",{parent:document.body})}changeTab(e){this.tabs[this.selectedTab].tab.classList.remove("active"),this.tabs[this.selectedTab].page.classList.remove("active"),this.tabs[e].tab.classList.add("active"),this.tabs[e].page.classList.add("active"),this.selectedTab=e}changeNode(e,t){!t&&this.selectedNodeIndex===e||(this.selectedNodeIndex!=null&&this.nodeItems[this.selectedNodeIndex].classList.remove("selected"),this.nodeItems[e].classList.add("selected"),this.selectedNodeIndex=e,!this.buildInputsPage()&&this.selectedTab==="Inputs"&&this.changeTab("Widgets"),!this.buildWidgetsPage()&&this.selectedTab==="Widgets"&&this.changeTab("Outputs"),!this.buildOutputsPage()&&this.selectedTab==="Outputs"&&this.changeTab("Inputs"),this.changeTab(this.selectedTab))}getGroupData(){this.groupNodeType=k.registered_node_types[`${G}>`+this.selectedGroup],this.groupNodeDef=this.groupNodeType.nodeData,this.groupData=R.getGroupData(this.groupNodeType)}changeGroup(e,t=!0){this.selectedGroup=e,this.getGroupData();const i=this.groupData.nodeData.nodes;if(this.nodeItems=i.map((o,s)=>N("li.draggable-item",{dataset:{nodeindex:o.index+""},onclick:u(()=>{this.changeNode(s)},"onclick")},[N("span.drag-handle"),N("div",{textContent:o.title??o.type},o.title?N("span",{textContent:o.type}):[])])),this.innerNodesList.replaceChildren(...this.nodeItems),t)this.selectedNodeIndex=null,this.changeNode(0);else{let o=this.draggable.getAllItems().findIndex(s=>s.classList.contains("selected"));o===-1&&(o=this.selectedNodeIndex),this.changeNode(o,!0)}const n=[...i];this.draggable?.dispose(),this.draggable=new Rt(this.innerNodesList,"li"),this.draggable.addEventListener("dragend",({detail:{oldPosition:o,newPosition:s}})=>{if(o!==s){n.splice(s,0,n.splice(o,1)[0]);for(let r=0;r<n.length;r++)this.storeModification({nodeIndex:n[r].index,section:ke,prop:"order",value:r})}})}storeModification(e){const{nodeIndex:t,section:i,prop:n,value:o}=e,s=this.modifications[this.selectedGroup]??={},r=s.nodes??={},a=r[t??this.selectedNodeInnerIndex]??={},l=a[i]??={};if(typeof o=="object"){const d=l[n]??={};Object.assign(d,o)}else l[n]=o}getEditElement(e,t,i,n,o,s=!0){i===n&&(i="");const r=this.modifications[this.selectedGroup]?.nodes?.[this.selectedNodeInnerIndex]?.[e]?.[t];return r&&(r.name!=null&&(i=r.name),r.visible!=null&&(o=r.visible)),N("div",[N("input",{value:i,placeholder:n,type:"text",onchange:u(a=>{this.storeModification({section:e,prop:t,value:{name:a.target.value}})},"onchange")}),N("label",{textContent:"Visible"},[N("input",{type:"checkbox",checked:o,disabled:!s,onchange:u(a=>{this.storeModification({section:e,prop:t,value:{visible:!!a.target.checked}})},"onchange")})])])}buildWidgetsPage(){const e=this.groupData.oldToNewWidgetMap[this.selectedNodeInnerIndex],t=Object.keys(e??{}),i=g.rootGraph.extra.groupNodes[this.selectedGroup].config?.[this.selectedNodeInnerIndex]?.input;return this.widgetsPage.replaceChildren(...t.map(n=>this.getEditElement("input",n,e[n],n,i?.[n]?.visible!==!1))),!!t.length}buildInputsPage(){const e=this.groupData.nodeInputs[this.selectedNodeInnerIndex],t=Object.keys(e??{}),i=g.rootGraph.extra.groupNodes[this.selectedGroup].config?.[this.selectedNodeInnerIndex]?.input;return this.inputsPage.replaceChildren(...t.map(n=>{let o=e[n];if(o)return this.getEditElement("input",n,o,n,i?.[n]?.visible!==!1)}).filter(Boolean)),!!t.length}buildOutputsPage(){const e=this.groupData.nodeData.nodes,t=this.groupData.getNodeDef(e[this.selectedNodeInnerIndex]),i=t?.output??[],n=this.groupData.oldToNewOutputMap[this.selectedNodeInnerIndex],o=g.rootGraph.extra.groupNodes[this.selectedGroup].config?.[this.selectedNodeInnerIndex]?.output,s=this.groupData.nodeData.nodes[this.selectedNodeInnerIndex].type!=="PrimitiveNode";return this.outputsPage.replaceChildren(...i.map((r,a)=>{const l=n?.[a],d=t.output_name?.[a]??r;let c=o?.[a]?.name;const m=o?.[a]?.visible||l!=null;return(!c||c===d)&&(c=""),this.getEditElement("output",a,c,d,m,s)}).filter(Boolean)),!!i.length}show(e){const t=Object.keys(g.rootGraph.extra?.groupNodes??{}).sort((o,s)=>o.localeCompare(s));this.innerNodesList=N("ul.comfy-group-manage-list-items"),this.widgetsPage=N("section.comfy-group-manage-node-page"),this.inputsPage=N("section.comfy-group-manage-node-page"),this.outputsPage=N("section.comfy-group-manage-node-page");const i=N("div",[this.widgetsPage,this.inputsPage,this.outputsPage]);this.tabs=[["Inputs",this.inputsPage],["Widgets",this.widgetsPage],["Outputs",this.outputsPage]].reduce((o,[s,r])=>(o[s]={tab:N("a",{onclick:u(()=>{this.changeTab(s)},"onclick"),textContent:s}),page:r},o),{});const n=N("div.comfy-group-manage-outer",[N("header",[N("h2","Group Nodes"),N("select",{onchange:u(o=>{this.changeGroup(o.target.value)},"onchange")},t.map(o=>N("option",{textContent:o,selected:`${G}>${o}`===e,value:o})))]),N("main",[N("section.comfy-group-manage-list",this.innerNodesList),N("section.comfy-group-manage-node",[N("header",Object.values(this.tabs).map(o=>o.tab)),i])]),N("footer",[N("button.comfy-btn",{onclick:u(()=>{if(g.rootGraph.nodes.find(o=>o.type==="workflow>"+this.selectedGroup)){M().addAlert("This group node is in use in the current workflow, please first remove these.");return}confirm(`Are you sure you want to remove the node: "${this.selectedGroup}"`)&&(delete g.rootGraph.extra.groupNodes[this.selectedGroup],k.unregisterNodeType(`${G}>`+this.selectedGroup)),this.show()},"onclick")},"Delete Group Node"),N("button.comfy-btn",{onclick:u(async()=>{let o,s=[];const r={};for(const a in this.modifications){const l=g.rootGraph.extra.groupNodes[a];let d=l.config??={},c=this.modifications[a]?.nodes;if(c){const h=Object.keys(c);if(c[h[0]][ke]){const w=[],p={},y={};for(const v of h){const f=c[v][ke].order;w[f]=l.nodes[+v],p[f]=c[v],w[f].index=f}for(const v of l.links)v[0]!=null&&(v[0]=l.nodes[v[0]].index),v[2]!=null&&(v[2]=l.nodes[v[2]].index);if(l.external)for(const v of l.external)v[0]!=null&&(v[0]=l.nodes[v[0]].index);for(const v of h)d[v]&&(y[l.nodes[v].index]=d[v]),delete d[v];l.nodes=w,c=p,l.config=d=y}dt(d,c)}r[a]=l,o||(o=g.rootGraph.nodes.reduce((h,w)=>(h[w.type]??=[],h[w.type].push(w),h),{}));const m=o[`${G}>`+a];m&&s.push(...m)}await ie.registerFromWorkflow(r,[]);for(const a of s)a.recreate();this.modifications={},this.app.canvas.setDirty(!0,!0),this.changeGroup(this.selectedGroup,!1)},"onclick")},"Save"),N("button.comfy-btn",{onclick:u(()=>this.element.close(),"onclick")},"Close")])]);this.element.replaceChildren(n),this.changeGroup(e?t.find(o=>`workflow>${o}`===e)??t[0]:t[0]),this.element.showModal(),this.element.addEventListener("close",()=>{this.draggable?.dispose(),this.element.remove()})}};window.comfyAPI=window.comfyAPI||{};window.comfyAPI.groupNodeManage=window.comfyAPI.groupNodeManage||{};window.comfyAPI.groupNodeManage.ManageGroupDialog=ct;var oo=new Set(["default","forceInput","defaultInput","control_after_generate","multiline","tooltip","dynamicPrompts"]),ze=u(e=>({min:e.min??-1/0,max:e.max??1/0}),"getRange"),no=u((e,t)=>{const i=e[0],n=e[1]??{},o=t[1]??{},s=ze(n),r=ze(o);if(s.min>r.max||s.max<r.min)return null;const a=n.step??1,l=o.step??1,d={min:Math.max(s.min,r.min),max:Math.min(s.max,r.max),step:Vt(a,l)};return Pe([i,{...n,...d}],[i,{...o,...d}])},"mergeNumericInputSpec"),io=u((e,t)=>{const i=e[1]??{},n=t[1]??{},o=Ve(e),s=Ve(t),r=q.intersection(o,s);return r.length===0?null:Pe(["COMBO",{...i,options:r}],["COMBO",{...n,options:r}])},"mergeComboInputSpec"),Pe=u((e,t)=>{const i=xe(e),n=e[1]??{},o=t[1]??{};return q.union(q.keys(n),q.keys(o)).filter(s=>!oo.has(s)).every(s=>{const r=n[s],a=o[s];return r===a||q.isNil(r)&&q.isNil(a)})?[i,{...n,...o}]:null},"mergeCommonInputSpec");const so=u((e,t)=>xe(e)!==xe(t)?null:Bt(e)||Kt(e)?no(e,t):Ut(e)?io(e,t):Pe(e,t),"mergeInputSpec"),ro=u(e=>e.type==="PrimitiveNode","isPrimitiveNode");var De="Run widget replace on values",Te=class extends he{static{u(this,"PrimitiveNode")}controlValues;lastType;static category;constructor(e){super(e),this.addOutput("connect to widget input","*"),this.serialize_widgets=!0,this.isVirtualNode=!0,(!this.properties||!(De in this.properties))&&this.addProperty(De,!1,"boolean")}applyToGraph(e=[]){if(!this.outputs[0].links?.length||!this.graph)return;const t=[...this.outputs[0].links.map(n=>this.graph.links[n]),...e];let i=this.widgets?.[0].value;i&&this.properties[De]&&(i=rt(this.graph,i));for(const n of t){const o=this.graph?.getNodeById(n.target_id),s=o?.inputs[n.target_slot];if(!s){console.warn("Unable to resolve node or input for link",n);continue}const r=s.widget?.name;if(!r){console.warn("Invalid widget or widget name",s.widget);continue}const a=o.widgets?.find(l=>l.name===r);if(!a){console.warn(`Unable to find widget "${r}" on node [${o.id}]`);continue}a.value=i,a.callback?.(a.value,g.canvas,o,g.canvas.graph_mouse,{})}}refreshComboInNode(){const e=this.widgets?.[0];e?.type==="combo"&&(e.options.values=this.outputs[0].widget[P]()[0],e.options.values.includes(e.value)||(e.value=e.options.values[0],e.callback(e.value)))}onAfterGraphConfigured(){if(this.outputs[0].links?.length&&!this.widgets?.length){if(this.#e(),this.widgets&&this.widgets_values)for(let e=0;e<this.widgets_values.length;e++){const t=this.widgets[e];t&&(t.value=this.widgets_values[e])}this.#t()}}onConnectionsChange(e,t,i){if(g.configuringGraph)return;const n=this.outputs[0].links;i?n?.length&&!this.widgets?.length&&this.#e():(this.#t(),n?.length||this.onLastDisconnect())}onConnectOutput(e,t,i,n,o){if(!i.widget&&!(i.type in $))return!1;if(this.outputs[e].links?.length){const s=this.#o(i);return s&&this.applyToGraph([{target_id:n.id,target_slot:o}]),s}return!0}#e(e){if(!this.outputs[0].links||!this.graph){this.onLastDisconnect();return}const t=this.outputs[0].links[0],i=this.graph.links[t];if(!i)return;const n=this.graph.getNodeById(i.target_id);if(!n||!n.inputs)return;const o=n.inputs[i.target_slot];if(!o)return;let s;if(o.widget)s=o.widget;else{if(!(o.type in $))return;s={name:o.name,[P]:()=>[o.type,{}]}}const r=s[P]?.();if(!r)return;const{type:a}=lo(r);this.outputs[0].type=a,this.outputs[0].name=a,this.outputs[0].widget=s,this.#i(s[ae]??r,n,s.name,e)}#i(e,t,i,n){let o=e[0];o instanceof Array&&(o="COMBO");const[s,r]=this.size;let a;if(Wt(o)?a=($[o](this,"value",e,g)||{}).widget:a=this.addWidget(o,"value",null,()=>{},{}),t?.widgets&&a){const d=t.widgets.find(c=>c.name===i);d&&(a.value=d.value)}if(!e?.[1]?.control_after_generate&&(a.type==="number"||a.type==="combo")){let d=this.widgets_values?.[1];d||(d="fixed"),At(this,a,d,void 0,e),this.widgets?.[1]&&(a.linkedWidgets=[this.widgets[1]]);let c=this.widgets_values?.[2];c&&this.widgets&&this.widgets.length===3&&(this.widgets[2].value=c)}const l=this.controlValues;if(this.widgets&&this.lastType===this.widgets[0]?.type&&l?.length===this.widgets.length-1)for(let d=0;d<l.length;d++)this.widgets[d+1].value=l[d];if(a.callback=J(a.callback,()=>{this.applyToGraph()}),this.setSize([Math.max(this.size[0],s),Math.max(this.size[1],r)]),!n){const d=this.computeSize();this.size[0]<d[0]&&(this.size[0]=d[0]),this.size[1]<d[1]&&(this.size[1]=d[1]),requestAnimationFrame(()=>{this.onResize?.(this.size)})}}recreateWidget(){const e=this.widgets?.map(t=>t.value);if(this.#n(),this.#e(!0),e?.length&&this.widgets)for(let t=0;t<this.widgets.length;t++)this.widgets[t].value=e[t];return this.widgets?.[0]}#t(){const e=this.outputs[0],t=e.links??[],i=!!e.widget?.[ae];if(i&&delete e.widget?.[ae],t?.length<2&&i){t.length&&this.recreateWidget();return}const n=e.widget?.[P]?.();if(n&&!(!(n[0]==="INT"||n[0]==="FLOAT")||!this.graph))for(const o of t){const s=this.graph.links[o];if(!s)continue;const r=this.graph.getNodeById(s.target_id);if(!r)continue;const a=r.inputs[s.target_slot];this.#o(a,i)}}#o(e,t){const i=this.outputs?.[0],n=e.widget?.[P]?.();return n?!!pe.call(this,i,n,t,this.recreateWidget):!1}#n(){if(this.widgets){for(const e of this.widgets)e.onRemove&&e.onRemove();this.controlValues=[],this.lastType=this.widgets[0]?.type;for(let e=1;e<this.widgets.length;e++)this.controlValues.push(this.widgets[e].value);setTimeout(()=>{delete this.lastType,delete this.controlValues},15),this.widgets.length=0}}onLastDisconnect(){this.outputs[0].type="*",this.outputs[0].name="connect to widget input",delete this.outputs[0].widget,this.#n()}};function Ge(e){return e.widget?.[ae]??e.widget?.[P]?.()??["*",{}]}u(Ge,"getWidgetConfig");function je(e){const{nodeData:t}=this.constructor;return t?.input?.required?.[e]??t?.input?.optional?.[e]}u(je,"getConfig");function ao(e,t){return console.warn("Please remove call to convertToInput. Widget to socket conversion is no longer necessary, as they co-exist now."),e.inputs.find(i=>i.widget?.name===t.name)}u(ao,"convertToInput");function lo(e){let t=e[0];return t instanceof Array&&(t="COMBO"),{type:t}}u(lo,"getWidgetType");function Se(e,t){if(!e.widget||(t?e.widget[P]=()=>t:delete e.widget,!(e instanceof Nt)))return;const i=e.node.graph;if(!i)return;const n=i.links[e.link??-1];if(!n)return;const o=i.getNodeById(n.origin_id);!o||!ro(o)||(t?o.recreateWidget():g.configuringGraph||(o.disconnectOutput(0),o.onLastDisconnect()))}u(Se,"setWidgetConfig");function pe(e,t,i,n,o){o||(o=Ge(e));const s=so(o,t);if(s||i){s&&(e.widget[ae]=s);const r=n?.call(this);if(r){const a=r.options.min,l=r.options.max;a!=null&&r.value<a&&(r.value=a),l!=null&&r.value>l&&(r.value=l),r.callback(r.value)}}return{customConfig:s?.[1]??{}}}u(pe,"mergeIfValid");g.registerExtension({name:"Comfy.WidgetInputs",async beforeRegisterNodeDef(e,t,i){e.prototype.convertWidgetToInput=function(){return console.warn("Please remove call to convertWidgetToInput. Widget to socket conversion is no longer necessary, as they co-exist now."),!1},e.prototype.onGraphConfigured=J(e.prototype.onGraphConfigured,function(){if(this.inputs){this.widgets??=[];for(const o of this.inputs)if(o.widget){const s=o.widget.name;o.widget[P]||(o.widget[P]=()=>je.call(this,s)),this.widgets?.find(r=>r.name===s)||this.removeInput(this.inputs.findIndex(r=>r===o))}}}),e.prototype.onConfigure=J(e.prototype.onConfigure,function(){if(!i.configuringGraph&&this.inputs){for(const o of this.inputs)if(o.widget&&!o.widget[P]){const s=o.widget.name;o.widget[P]=()=>je.call(this,s)}}});const n=e.prototype.onInputDblClick;e.prototype.onInputDblClick=function(...[o,...s]){const r=n?.apply(this,[o,...s]),a=this.inputs[o];if(!a.widget&&!(a.type in $)&&!(a.widget?.[P]?.()?.[0]instanceof Array))return r;const l=k.createNode("PrimitiveNode"),d=i.canvas.graph;if(!l||!d)return r;d?.add(l);const c=[this.pos[0]-l.size[0]-30,this.pos[1]];for(;d.getNodeOnPos(c[0],c[1],d.nodes);)c[1]+=k.NODE_TITLE_HEIGHT;return l.pos=c,l.connect(0,this,o),l.title=a.name,r}},registerCustomNodes(){k.registerNodeType("PrimitiveNode",Object.assign(Te,{title:"Primitive"})),Te.category="utils"}});window.comfyAPI=window.comfyAPI||{};window.comfyAPI.widgetInputs=window.comfyAPI.widgetInputs||{};window.comfyAPI.widgetInputs.PrimitiveNode=Te;window.comfyAPI.widgetInputs.getWidgetConfig=Ge;window.comfyAPI.widgetInputs.convertToInput=ao;window.comfyAPI.widgetInputs.setWidgetConfig=Se;window.comfyAPI.widgetInputs.mergeIfValid=pe;var Y={InUse:{Free:0,Registered:1,InWorkflow:2},isInUseGroupNode(e){const t=`${G}>${e}`;return g.rootGraph.extra?.groupNodes?.[e]?g.rootGraph.nodes.find(i=>i.type===t)?Y.InUse.InWorkflow:Y.InUse.Registered:Y.InUse.Free},storeGroupNode(e,t){let i=g.rootGraph.extra;i||(g.rootGraph.extra=i={});let n=i.groupNodes;n||(i.groupNodes=n={}),n[e]=t}},He=class{static{u(this,"GroupNodeBuilder")}nodes;nodeData;constructor(e){this.nodes=e}async build(){const e=await this.getName();if(e)return this.sortNodes(),this.nodeData=this.getNodeData(),Y.storeGroupNode(e,this.nodeData),{name:e,nodeData:this.nodeData}}async getName(){const e=await re().prompt({title:_("groupNode.create"),message:_("groupNode.enterName"),defaultValue:""});if(e){switch(Y.isInUseGroupNode(e)){case Y.InUse.InWorkflow:M().addAlert("An in use group node with this name already exists embedded in this workflow, please remove any instances or use a new name.");return;case Y.InUse.Registered:if(!confirm("A group node with this name already exists embedded in this workflow, are you sure you want to overwrite it?"))return;break}return e}}sortNodes(){const e=g.rootGraph.computeExecutionOrder(!1);this.nodes=this.nodes.map(t=>({index:e.indexOf(t),node:t})).sort((t,i)=>t.index-i.index||String(t.node.id).localeCompare(String(i.node.id))).map(({node:t})=>t)}getNodeData(){const e=u(s=>{for(const r of s.links){const a=g.rootGraph.getNodeById(r[4])?.outputs?.[Number(r[1])]?.type;a!==void 0&&r.push(a)}},"storeLinkTypes"),t=u(s=>{s.external=[];for(let r=0;r<this.nodes.length;r++){const a=this.nodes[r];if(a.outputs?.length)for(let l=0;l<a.outputs.length;l++){let d=!1;const c=a.outputs[l];let m=c.type;if(c.links?.length){for(const h of c.links){const w=g.rootGraph.links[h];if(w&&(m==="*"&&(m=w.type),!g.canvas.selected_nodes[w.target_id])){d=!0;break}}d&&s.external.push([r,l,String(m)])}}}},"storeExternalLinks"),i=g.canvas?.graph;if(!i)return{nodes:[],links:[],external:[]};const n=Et(this.nodes,i),o=JSON.parse(n);return o.external=[],e(o),t(o),o}},ie=class ut{static{u(this,"GroupNodeConfig")}name;nodeData;inputCount;oldToNewOutputMap;newToOldOutputMap;oldToNewInputMap;oldToNewWidgetMap;newToOldWidgetMap;primitiveDefs;widgetToPrimitive;primitiveToWidget;nodeInputs;outputVisibility;nodeDef;inputs;linksFrom;linksTo;externalFrom;constructor(t,i){this.name=t,this.nodeData=i,this.getLinks(),this.inputCount=0,this.oldToNewOutputMap={},this.newToOldOutputMap={},this.oldToNewInputMap={},this.oldToNewWidgetMap={},this.newToOldWidgetMap={},this.primitiveDefs={},this.widgetToPrimitive={},this.primitiveToWidget={},this.nodeInputs={},this.outputVisibility=[]}async registerType(t=G){this.nodeDef={output:[],output_name:[],output_is_list:[],output_node:!1,name:t+">"+this.name,display_name:this.name,category:"group nodes"+(">"+t),input:{required:{}},description:`Group node combining ${this.nodeData.nodes.map(o=>o.type).join(", ")}`,python_module:"custom_nodes."+this.name,[V]:this},this.inputs=[];const i={},n={};for(let o=0;o<this.nodeData.nodes.length;o++){const s=this.nodeData.nodes[o];s.index=o,this.processNode(s,i,n)}for(const o of this.#e)o();this.#e=[],this.nodeDef&&(await g.registerNodeDef(`${G}>`+this.name,this.nodeDef),Yt().addNodeDef(this.nodeDef))}getLinks(){this.linksFrom={},this.linksTo={},this.externalFrom={};for(const t of this.nodeData.links){const[i,n,o,s]=t;if(i==null||n==null||o==null||s==null)continue;const r=Number(i),a=Number(n),l=Number(o),d=Number(s);this.linksFrom[r]||(this.linksFrom[r]={}),this.linksFrom[r][a]||(this.linksFrom[r][a]=[]),this.linksFrom[r][a].push(t),this.linksTo[l]||(this.linksTo[l]={}),this.linksTo[l][d]=t}if(this.nodeData.external)for(const t of this.nodeData.external){const i=Number(t[0]),n=Number(t[1]),o=t[2];o!=null&&(this.externalFrom[i]?this.externalFrom[i][n]=o:this.externalFrom[i]={[n]:o})}}processNode(t,i,n){const o=this.getNodeDef(t);if(!o)return;const s={...o.input?.required,...o.input?.optional};this.inputs.push(this.processNodeInputs(t,i,s)),o.output?.length&&this.processNodeOutputs(t,n,o)}getNodeDef(t){if(t.type){const o=le[t.type];if(o)return o}const i=t.index;if(i==null)return;const n=this.linksFrom[i];if(t.type==="PrimitiveNode"){if(!n)return;let o=n[0]?.[0]?.[5]??null;if(o==="COMBO"){const s=t.outputs?.[0]?.widget?.name,r=n[0]?.[0]?.[2];if(s&&r!=null){const a=this.nodeData.nodes[Number(r)]?.type;if(a){const l=le[a],d=(l?.input?.required?.[s]??l?.input?.optional?.[s])?.[0];o=typeof d=="string"||typeof d=="number"?d:null}}}return this.primitiveDefs[i]={input:{required:{value:[o,{}]}},output:[o],output_name:[],output_is_list:[]}}else if(t.type==="Reroute"){const o=this.linksTo[i];if(o&&n&&!this.externalFrom[i]?.[0])return null;let s={},r="*";if(n){const a=n[0]??[];for(const l of a){const d=l[2],c=l[3];if(d==null||c==null)continue;const m=this.nodeData.nodes[Number(d)],h=m?.inputs?.[Number(c)];if(h?.type&&r==="*"&&(r=h.type),h?.widget&&m?.type){const w=le[m.type],p=w?.input?.required?.[h.widget.name]??w?.input?.optional?.[h.widget.name];if(p){const y=[p[0],s];s=pe({widget:y},p,!1,void 0,y)?.customConfig??s}}}}else if(o){const a=o[0];if(a){const l=a[0],d=a[1];if(l!=null&&d!=null){const c=this.nodeData.nodes[Number(l)]?.outputs?.[Number(d)];c&&typeof c=="object"&&"type"in c&&(r=String(c.type??"*"))}}}else{for(const a of this.nodeData.links)if(a[2]===t.index){const l=a[5];l!=null&&(r=String(l));break}if(r==="*"){const a=this.externalFrom[i]?.[0];a&&(r=String(a))}}return s.forceInput=!0,{input:{required:{[r]:[r,s]}},output:[r],output_name:[],output_is_list:[]}}console.warn("Skipping virtual node "+t.type+" when building group node "+this.name)}getInputConfig(t,i,n,o,s){const r=this.nodeData.config?.[t.index??-1]?.input?.[i];let a=r?.name??t.inputs?.find(c=>c.name===i)?.label??i,l=a,d="";if((t.type==="PrimitiveNode"&&t.title||a in n)&&(d=`${t.title??t.type} `,l=a=`${d}${i}`,a in n&&(a=`${d}${n[a]} ${i}`)),n[l]=(n[l]??1)+1,(i==="seed"||i==="noise_seed")&&(s||(s={}),s.control_after_generate=`${d}control_after_generate`),o[0]==="IMAGEUPLOAD"){s||(s={});const c=t.index??-1,m=typeof o[1]=="object"&&o[1]!==null?o[1]:{},h="widget"in m&&typeof m.widget=="string"?m.widget:"image";s.widget=this.oldToNewWidgetMap[c]?.[h]??"image"}if(s){const c=typeof o[1]=="object"&&o[1]?o[1]:{};o=[o[0],{...c,...s}]}return{name:a,config:o,customConfig:r}}processWidgetInputs(t,i,n,o){const s=[],r=new Map,a=i.index??-1,l=this.oldToNewWidgetMap[a]={};for(const d of n){const c=t[d];if(Array.isArray(c)&&c.length>=1&&typeof c[0]=="string"&&Jt().inputIsWidget(c)){const m=i.inputs?.findIndex(h=>h.name===d&&h.widget?.name===d)??-1;if(m>-1)r.set(m,d),l[d]=null;else{const{name:h,config:w}=this.getInputConfig(i,d,o,t[d]);this.nodeDef?.input?.required&&(this.nodeDef.input.required[h]=w),l[d]=h,this.newToOldWidgetMap[h]={node:i,inputName:d}}}else s.push(d)}return{converted:r,slots:s}}checkPrimitiveConnection(t,i,n){const o=t[0];if(o!=null&&this.nodeData.nodes[Number(o)]?.type==="PrimitiveNode"){const s=Number(t[0]),r=Number(t[2]),a=this.primitiveDefs[s];if(!a)return;const l=n[i],d=a.input.required.value,c=pe({widget:d},l,!1,void 0,d),m=n[i]?.[1];d[1]=c?.customConfig??m?{...typeof m=="object"?m:{}}:{};const h=this.oldToNewWidgetMap[s]?.value;if(h){const v=h.substring(0,h.length-6);d[1].control_after_generate=!0,d[1].control_prefix=v}let w=this.widgetToPrimitive[r];w||(w=this.widgetToPrimitive[r]={});const p=w[i];Array.isArray(p)?p.push(s):typeof p=="number"?w[i]=[p,s]:w[i]=s;let y=this.primitiveToWidget[s];y||(y=this.primitiveToWidget[s]=[]),y.push({nodeId:r,inputName:i})}}processInputSlots(t,i,n,o,s,r){const a=i.index??-1;this.nodeInputs[a]={};for(let l=0;l<n.length;l++){const d=n[l];if(o[l]){this.checkPrimitiveConnection(o[l],d,t);continue}const{name:c,config:m,customConfig:h}=this.getInputConfig(i,d,r,t[d]);this.nodeInputs[a][d]=c,h?.visible!==!1&&(this.nodeDef?.input?.required&&(this.nodeDef.input.required[c]=m),s[l]=this.inputCount++)}}processConvertedWidgets(t,i,n,o,s,r,a){const l=[...o.keys()].sort().map(d=>o.get(d));for(let d=0;d<l.length;d++){const c=l[d];if(!c)continue;if(s[n.length+d]){this.checkPrimitiveConnection(s[n.length+d],c,t);continue}const{name:m,config:h}=this.getInputConfig(i,c,a,t[c],{defaultInput:!0});this.nodeDef?.input?.required&&(this.nodeDef.input.required[m]=h),this.newToOldWidgetMap[m]={node:i,inputName:c};const w=i.index??-1;this.oldToNewWidgetMap[w]||(this.oldToNewWidgetMap[w]={}),this.oldToNewWidgetMap[w][c]=m,r[n.length+d]=this.inputCount++}}#e=[];processNodeInputs(t,i,n){const o=[],s=Object.keys(n);if(!s.length)return;const{converted:r,slots:a}=this.processWidgetInputs(n,t,s,i),l=t.index??-1,d=this.linksTo[l]??{},c=this.oldToNewInputMap[l]={};return this.processInputSlots(n,t,a,d,c,i),this.#e.push(()=>this.processConvertedWidgets(n,t,a,r,d,c,i)),o}processNodeOutputs(t,i,n){const o=t.index??-1,s=this.oldToNewOutputMap[o]={},r=n.output??[];for(let a=0;a<r.length;a++){const l=this.linksFrom[o]?.[a]&&!this.externalFrom[o]?.[a],d=this.nodeData.config?.[t.index??-1]?.output?.[a],c=d?.visible??!l;if(this.outputVisibility.push(c),!c)continue;this.nodeDef?.output&&(s[a]=this.nodeDef.output.length,this.newToOldOutputMap[this.nodeDef.output.length]={node:t,slot:a},this.nodeDef.output.push(r[a]),this.nodeDef.output_is_list?.push(n.output_is_list?.[a]??!1));let m=d?.name;if(!m){const w=r[a];m=n.output_name?.[a]??(typeof w=="string"?w:void 0);const p=t.outputs?.find(y=>y.name===m);p?.label&&(m=p.label)}let h=String(m??`output_${a}`);if(h in i){const w=`${t.title??t.type} `;h=`${w}${m??a}`,h in i&&(h=`${w}${t.index} ${m??a}`)}i[h]=1,this.nodeDef?.output_name?.push(h)}}static async registerFromWorkflow(t,i){for(const n in t){const o=t[n];let s=!1;for(const r of o.nodes)(!r.type||!(r.type in k.registered_node_types))&&(i.push({type:r.type??"unknown",hint:` (In group node '${G}>${n}')`}),i.push({type:`${G}>`+n,action:{text:"Remove from workflow",callback:u(a=>{delete t[n];const l=a.target;l.textContent="Removed",l.style.pointerEvents="none",l.style.opacity="0.7"},"callback")}}),s=!0);s||await new ut(n,o).registerType()}}},R=class te{static{u(this,"GroupNodeHandler")}node;groupData;innerNodes=null;constructor(t){this.node=t,this.groupData=t.constructor?.nodeData?.[V],this.node.setInnerNodes=p=>{this.innerNodes=p;for(let y=0;y<this.innerNodes.length;y++){const v=this.innerNodes[y];v.graph??=this.node.graph;for(const f of v.widgets??[])f.type==="converted-widget"&&(f.serializeValue=f.origSerializeValue);v.index=y,v.getInputNode=f=>{const b=v.index??0,I=this.groupData.oldToNewInputMap[b]?.[f];if(I!=null)return this.node.getInputNode(I);const C=this.groupData.linksTo[b]?.[f];if(!C)return null;const D=C[0];if(D==null)return null;const x=p[Number(D)];return x.type==="PrimitiveNode"?null:x},v.getInputLink=f=>{const b=v.index??0,I=this.groupData.oldToNewInputMap[b]?.[f];if(I!=null){const x=this.node.inputs[I].link;if(x==null)return null;const T=g.rootGraph.links[x];return T?{...T,target_id:v.id,target_slot:+f}:null}const C=this.groupData.linksTo[b]?.[f];if(!C)return null;const D=C[0];return D==null?null:{origin_id:p[Number(D)].id,origin_slot:C[1],target_id:v.id,target_slot:+f}}}},this.node.updateLink=p=>{p={...p};const y=this.groupData.newToOldOutputMap[p.origin_slot];if(!y||!this.innerNodes)return null;const v=y.node.index??0;let f=this.innerNodes[v],b;for(;f?.type==="Reroute";)b=f.getInputLink(0),f=f.getInputNode(0);return f?b&&te.isGroupNode(f)&&f.updateLink?f.updateLink(b):(p.origin_id=f.id,p.origin_slot=b?.origin_slot??y.slot,p):null},this.node.getInnerNodes=(p,y=[],v=[],f=new Set)=>{if(f.has(this.node))throw new Error("RecursionError: while flattening subgraph");if(f.add(this.node),!this.innerNodes){const C=this.groupData.nodeData.nodes.map((D,x)=>{if(!D.type)return null;const T=k.createNode(D.type);return T?(T.configure(D),T.id=`${this.node.id}:${x}`,T.graph=this.node.graph,T):null}).filter(D=>D!==null);this.node.setInnerNodes?.(C)}this.updateInnerWidgets();const b=[...y,this.node.id],I=this.node.graph?.getNodeById(y.at(-1))??void 0;for(const C of this.innerNodes??[]){C.graph??=this.node.graph;const D=String(C.id);C.id=D.split(":").at(-1);const x=new to(C,b,p,I);C.id=D,x.groupNodeHandler=this,v.push(x)}return v},this.node.recreate=async()=>{const p=this.node.id,y=this.node.size,v=this.node.convertToNodes?.();if(!v)return null;const f=k.createNode(this.node.type);if(!f)return null;f.id=p,f.setInnerNodes?.(v);const b=te.getHandler(f);b?.populateWidgets(),g.rootGraph.add(f),f.setSize?.([Math.max(f.size[0],y[0]),Math.max(f.size[1],y[1])]);const I=new He(v).getNodeData();return b&&(b.groupData.nodeData.links=I.links,b.replaceNodes(v)),f},this.node.convertToNodes=()=>{const p=u(()=>{const f={...this.groupData.nodeData};f.nodes=[...f.nodes];const b=this.node.getInnerNodes?.(),I=[];for(let O=0;O<f.nodes.length;O++){let H=b?.[O]?.id;H==null||typeof H=="number"&&isNaN(H)?H=void 0:I.push(H),f.nodes[O]={...f.nodes[O],id:H}}at(JSON.stringify(f),g.canvas);const[C,D]=this.node.pos;let x,T;const z=I.length?I:Object.keys(g.canvas.selected_nodes),j=[];for(let O=0;O<z.length;O++){const H=z[O],F=g.rootGraph.getNodeById(H),ve=b?.[O];if(!F||(j.push(F),(T==null||F.pos[0]<T)&&(T=F.pos[0]),(x==null||F.pos[1]<x)&&(x=F.pos[1]),!F.widgets||!ve))continue;const be=this.groupData.oldToNewWidgetMap[ve.index??0];if(be){const gt=Object.keys(be);for(const Re of gt){const Fe=be[Re];if(!Fe)continue;const Ne=this.node.widgets?.findIndex(U=>U.name===Fe)??-1;if(Ne!==-1)if(ve.type==="PrimitiveNode")for(let U=0;U<F.widgets.length;U++){const Q=this.node.widgets?.[Ne+U];Q&&(F.widgets[U].value=Q.value)}else{const U=this.node.widgets?.[Ne],Q=F.widgets.find(X=>X.name===Re);if(!Q||!U)continue;Q.value=U.value;const Ie=U.linkedWidgets??[];for(let X=0;X<Ie.length;X++){const Ue=Q.linkedWidgets?.[X];Ue&&Ie[X]&&(Ue.value=Ie[X].value)}}}}}for(const O of j)O.pos[0]-=(T??0)-C,O.pos[1]-=(x??0)-D;return{newNodes:j,selectedIds:z}},"addInnerNodes"),y=u(f=>{for(const b in this.groupData.oldToNewInputMap){const I=f[Number(b)],C=g.rootGraph.getNodeById(I);if(!C)continue;const D=this.groupData.oldToNewInputMap[Number(b)];for(const x in D){const T=D[Number(x)];if(T==null)continue;const z=t.inputs[T];if(z.link==null)continue;const j=g.rootGraph.links[z.link];j&&g.rootGraph.getNodeById(j.origin_id)?.connect(j.origin_slot,C,+x)}}},"reconnectInputs"),v=u(f=>{for(let b=0;b<t.outputs?.length;b++){const I=t.outputs[b];if(!I.links)continue;const C=[...I.links];for(const D of C){const x=this.groupData.newToOldOutputMap[b];if(!x)continue;const T=g.rootGraph.links[D];if(!T)continue;const z=g.rootGraph.getNodeById(T.target_id),j=g.rootGraph.getNodeById(f[x.node.index??0]);z&&j?.connect(x.slot,z,T.target_slot)}}},"reconnectOutputs");g.canvas.emitBeforeChange();try{const{newNodes:f,selectedIds:b}=p();return y(b),v(b),g.rootGraph.remove(this.node),f}finally{g.canvas.emitAfterChange()}};const i=this.node.getExtraMenuOptions,n=this.node;this.node.getExtraMenuOptions=function(p,y){i?.call(this,p,y);let v=y.findIndex(f=>f?.content==="Outputs");return v===-1?v=y.length:v++,y.splice(v,0,null,{content:"Convert to nodes",callback:u(async()=>{const f=n.convertToNodes;return f?.()},"callback")},{content:"Manage Group Node",callback:u(()=>Me(this.type),"callback")}),[]};const o=this.node.onDrawTitleBox;this.node.onDrawTitleBox=function(p,y,v,f){o?.call(this,p,y,v,f);const b=p.fillStyle;p.beginPath(),p.rect(11,-y+11,2,2),p.rect(14,-y+11,2,2),p.rect(17,-y+11,2,2),p.rect(11,-y+14,2,2),p.rect(14,-y+14,2,2),p.rect(17,-y+14,2,2),p.rect(11,-y+17,2,2),p.rect(14,-y+17,2,2),p.rect(17,-y+17,2,2),p.fillStyle=this.boxcolor||k.NODE_DEFAULT_BOXCOLOR,p.fill(),p.fillStyle=b};const s=t.onDrawForeground,r=this.groupData.nodeData;t.onDrawForeground=function(p,y,v){s?.call(this,p,y,v);const f=Ht().nodeProgressStates[this.id];if(f&&f.state==="running"&&this.runningInternalNodeId!==null){const b=typeof this.runningInternalNodeId=="number"?this.runningInternalNodeId:parseInt(String(this.runningInternalNodeId),10),I=r.nodes[b];if(!I)return;const C=`Running ${I.title||I.type} (${this.runningInternalNodeId}/${r.nodes.length})`;p.save(),p.font="12px sans-serif";const D=p.measureText(C);p.fillStyle=t.boxcolor||k.NODE_DEFAULT_BOXCOLOR,p.beginPath(),p.roundRect(0,-k.NODE_TITLE_HEIGHT-20,D.width+12,20,5),p.fill(),p.fillStyle="#fff",p.fillText(C,6,-k.NODE_TITLE_HEIGHT-6),p.restore()}};const a=this.node.onExecutionStart;this.node.onExecutionStart=function(){return this.resetExecution=!0,a?.call(this)};const l=this.node.onNodeCreated,d=this.groupData;this.node.onNodeCreated=function(){if(!this.widgets)return;const p=d.nodeData.config;if(p)for(const y in p){const v=p[y]?.input;if(v)for(const f in v){if(v[f]?.visible!==!1)continue;const b=d.oldToNewWidgetMap[Number(y)]?.[f],I=this.widgets.find(C=>C.name===b);I&&(I.type="hidden",I.computeSize=()=>[0,-4])}}return l?.call(this)};const c=u((p,y,v)=>{const f=u(({detail:b})=>{const I=y(b);if(!I||g.rootGraph.getNodeById(I))return;const C=this.innerNodes?.findIndex(D=>D.id==I)??-1;C>-1&&(this.node.runningInternalNodeId=C,E.dispatchCustomEvent(p,v(b,`${this.node.id}`,this.node)))},"handler");return E.addEventListener(p,f),f},"handleEvent"),m=c("executing",p=>typeof p=="string"?p:void 0,(p,y)=>y),h=c("executed",p=>typeof p=="object"?p?.display_node||p?.node:void 0,(p,y,v)=>({...typeof p=="object"?p:{},node:y,display_node:y,merge:!v.resetExecution})),w=t.onRemoved;this.node.onRemoved=function(){w?.call(this),E.removeEventListener("executing",m),E.removeEventListener("executed",h)},this.node.refreshComboInNode=p=>{for(const y in this.groupData.newToOldWidgetMap){const v=this.node.widgets?.find(f=>f.name===y);if(v?.type==="combo"){const f=this.groupData.newToOldWidgetMap[y];if(!f.node.type)continue;const b=p[f.node.type],I=b?.input?.required?.[f.inputName]??b?.input?.optional?.[f.inputName];if(!I)continue;v.options.values=I[0];const C=v.options.values;f.inputName!=="image"&&!C.includes(v.value)&&(v.value=C[0],v.callback?.(v.value))}}}}updateInnerWidgets(){if(this.innerNodes)for(const t in this.groupData.newToOldWidgetMap){const i=this.node.widgets?.find(l=>l.name===t);if(!i)continue;const n=i.value,o=this.groupData.newToOldWidgetMap[t],s=o.node.index??0,r=this.innerNodes[s];if(!r)continue;if(r.type==="PrimitiveNode"){r.primitiveValue=n;const l=this.groupData.primitiveToWidget[s];for(const d of l??[]){const c=typeof d.nodeId=="number"?d.nodeId:Number(d.nodeId),m=this.innerNodes[c]?.widgets?.find(h=>h.name===d.inputName);m&&(m.value=n)}continue}else if(r.type==="Reroute"){const l=this.groupData.linksFrom[s];if(l)for(const[,,d,c]of l[0]??[]){if(d==null||c==null)continue;const m=this.innerNodes[Number(d)];if(!m)continue;const h=m.inputs?.[Number(c)];if(h?.widget){const w=h.widget.name,p=m.widgets?.find(y=>y.name===w);p&&(p.value=n)}}}const a=r.widgets?.find(l=>l.name===o.inputName);a&&(a.value=n)}}populatePrimitive(t,i,n){const o=this.groupData.widgetToPrimitive[i]?.[n];if(o==null)return!1;const s=this.groupData.oldToNewWidgetMap[Array.isArray(o)?o[0]:o]?.value;if(!s)return!1;const r=this.node.widgets?.findIndex(a=>a.name===s)??-1;if(r>-1&&this.innerNodes){const a=Array.isArray(o)?o[0]:o,l=this.innerNodes[a];if(!l?.widgets)return!0;let d=l.widgets.length;d-1!==(this.node.widgets?.[r]?.linkedWidgets?.length??0)&&(d=1);for(let c=0;c<d;c++){const m=this.node.widgets?.[r+c],h=l.widgets[c];m&&h&&(m.value=h.value)}}return!0}populateReroute(t,i,n){if(t.type!=="Reroute")return;const o=this.groupData.linksFrom[i]?.[0]?.[0];if(!o)return;const s=o[2],r=o[3];if(s==null||r==null)return;const a=this.groupData.nodeData.nodes[Number(s)],l=a?.inputs;if(!l?.[Number(r)]?.widget)return;const d=(l?.length??0)-(a?.widgets_values?.length??0),c=a?.widgets_values?.[Number(r)-d];if(c==null)return;const m=Object.values(n)[0],h=this.node.widgets?.find(w=>w.name===m);h&&(h.value=c)}populateWidgets(){if(this.node.widgets)for(let t=0;t<this.groupData.nodeData.nodes.length;t++){const i=this.groupData.nodeData.nodes[t],n=this.groupData.oldToNewWidgetMap[t]??{},o=Object.keys(n);if(!i.widgets_values?.length){this.populateReroute(i,t,n);continue}let s=0;for(let r=0;r<o.length;r++){const a=o[r],l=n[a],d=this.node.widgets.findIndex(h=>h.name===l),c=this.node.widgets[d];if(this.populatePrimitive(i,t,a)||d===-1){const h=this.innerNodes?.[t]?.widgets?.find(w=>w.name===a);s+=h?.linkedWidgets?.length??0}if(d===-1)continue;c.value=i.widgets_values?.[r+s];const m=c.linkedWidgets??[];for(let h=0;h<m.length;h++)this.node.widgets[d+h+1].value=i.widgets_values?.[r+ ++s]}}}replaceNodes(t){let i,n;for(let o=0;o<t.length;o++){const s=t[o];(n==null||s.pos[0]<n)&&(n=s.pos[0]),(i==null||s.pos[1]<i)&&(i=s.pos[1]),this.linkOutputs(s,o),g.rootGraph.remove(s),s.id=`${this.node.id}:${o}`}this.linkInputs(),this.node.pos=[n??0,i??0]}linkOutputs(t,i){if(t.outputs)for(const n of t.outputs){if(!n.links)continue;const o=[...n.links];for(const s of o){const r=g.rootGraph.links[s];if(!r)continue;const a=g.rootGraph.getNodeById(r.target_id),l=this.groupData.oldToNewOutputMap[i]?.[r.origin_slot];l!=null&&a&&this.node.connect(l,a,r.target_slot)}}}linkInputs(){for(const t of this.groupData.nodeData.links??[]){const[,i,n,o,s]=t;if(s==null||typeof s=="object")continue;const r=g.rootGraph.getNodeById(s);if(!r||n==null||o==null)continue;const a=this.groupData.oldToNewInputMap[Number(n)]?.[Number(o)];a!=null&&(typeof i=="number"||typeof i=="string")&&r.connect(i,this.node.id,a)}}static getGroupData(t){if(typeof t=="function")return t.nodeData?.[V];const i=t.nodeData;return i?.[V]?i[V]:t.constructor?.nodeData?.[V]}static getHandler(t){let i=t[V];return!i&&te.isGroupNode(t)&&(i=new te(t),t[V]=i),i}static isGroupNode(t){return!!t.constructor?.nodeData?.[V]}static async fromNodes(t){const i=new He(t),n=await i.build();if(!n)return;const{name:o,nodeData:s}=n;await new ie(o,s).registerType();const r=k.createNode(`${G}>${o}`);if(!r)return;r.setInnerNodes?.(i.nodes);const a=te.getHandler(r);return a?.populateWidgets(),g.rootGraph.add(r),a?.replaceNodes(i.nodes),r}},co=u(e=>{for(const t of e)typeof t.type=="string"&&t.type.startsWith("workflow/")&&(t.type=t.type.replace(/^workflow\//,`${G}>`))},"replaceLegacySeparators");async function _e(){const e=Object.values(g.canvas.selected_nodes??{});if(e.length===0)throw new Error("No nodes selected");if(e.length===1)throw new Error("Please select multiple nodes to convert to group node");for(const t of e){if(t instanceof kt)throw new Error("Selected nodes contain a subgraph node");if(R.isGroupNode(t))throw new Error("Selected nodes contain a group node")}return await R.fromNodes(e)}u(_e,"convertSelectedNodesToGroupNode");var qe=u(e=>e.length<2||!!e.find(t=>R.isGroupNode(t)),"convertDisabled");function uo(){const e=Object.values(g.canvas.selected_nodes??{});for(const t of e)R.isGroupNode(t)&&t.convertToNodes?.()}u(uo,"ungroupSelectedGroupNodes");function Me(e){new ct(g).show(e)}u(Me,"manageGroupNodes");var po="Comfy.GroupNode",le,go={name:po,commands:[{id:"Comfy.GroupNode.ConvertSelectedNodesToGroupNode",label:"Convert selected nodes to group node",icon:"pi pi-sitemap",versionAdded:"1.3.17",function:u(()=>_e(),"function")},{id:"Comfy.GroupNode.UngroupSelectedGroupNodes",label:"Ungroup selected group nodes",icon:"pi pi-sitemap",versionAdded:"1.3.17",function:u(()=>uo(),"function")},{id:"Comfy.GroupNode.ManageGroupNodes",label:"Manage group nodes",icon:"pi pi-cog",versionAdded:"1.3.17",function:u((...e)=>Me(e[0]),"function")}],keybindings:[{commandId:"Comfy.GroupNode.ConvertSelectedNodesToGroupNode",combo:{alt:!0,key:"g"}},{commandId:"Comfy.GroupNode.UngroupSelectedGroupNodes",combo:{alt:!0,shift:!0,key:"G"}}],getCanvasMenuItems(e){const t=[],i=!qe(Object.values(e.selected_nodes??{}));t.push({content:"Convert to Group Node (Deprecated)",disabled:!i,callback:u(async()=>_e(),"callback")});const n=e.graph?.extra?.groupNodes,o=!n||!Object.keys(n).length;return t.push({content:"Manage Group Nodes",disabled:o,callback:u(()=>Me(),"callback")}),t},getNodeMenuItems(e){return R.isGroupNode(e)?[]:[{content:"Convert to Group Node (Deprecated)",disabled:!!qe(Object.values(g.canvas.selected_nodes??{})),callback:u(async()=>_e(),"callback")}]},async beforeConfigureGraph(e,t){const i=e?.extra?.groupNodes;i&&(co(e.nodes),await ie.registerFromWorkflow(i,t))},addCustomNodeDefs(e){le=e},nodeCreated(e){if(R.isGroupNode(e)){e[V]=new R(e);const t=R.getHandler(e);e.title&&t?.groupData?.nodeData&&Y.storeGroupNode(e.title,t.groupData.nodeData)}},async refreshComboInNodes(e){Object.assign(le,e);const t=g.rootGraph.extra?.groupNodes;t&&await ie.registerFromWorkflow(t,[])}};g.registerExtension(go);window.comfyAPI=window.comfyAPI||{};window.comfyAPI.groupNode=window.comfyAPI.groupNode||{};window.comfyAPI.groupNode.GroupNodeConfig=ie;window.comfyAPI.groupNode.GroupNodeHandler=R;function A(e,t){e.mode=t,e.graph?.change()}u(A,"setNodeMode");function Ye(e,t){const i=ne().get("Comfy.GroupSelectedNodes.Padding");e.resizeTo([...e.children,...t],i)}u(Ye,"addNodesToGroup");g.registerExtension({name:"Comfy.GroupOptions",getCanvasMenuItems(e){const t=[],i=e.graph.getGroupOnPos(e.graph_mouse[0],e.graph_mouse[1]);if(!i)return e.selectedItems.size>0&&t.push({content:"Add Group For Selected Nodes",callback:u(()=>{const s=new xt;Ye(s,e.selectedItems),e.graph.add(s),e.graph.change(),s.recomputeInsideNodes()},"callback")}),t;i.recomputeInsideNodes();const n=i.nodes;if(t.push({content:"Add Selected Nodes To Group",disabled:!e.selectedItems?.size,callback:u(()=>{Ye(i,e.selectedItems),e.graph.change()},"callback")}),n.length===0)return t;t.push(null);let o=!0;for(let s=1;s<n.length;s++)if(n[s].mode!==n[0].mode){o=!1;break}if(t.push({content:"Fit Group To Nodes",callback:u(()=>{i.recomputeInsideNodes();const s=ne().get("Comfy.GroupSelectedNodes.Padding");i.resizeTo(i.children,s),e.graph.change()},"callback")}),t.push({content:"Select Nodes",callback:u(()=>{e.selectNodes(n),e.graph.change(),e.canvas.focus()},"callback")}),o)switch(n[0].mode){case 0:t.push({content:"Set Group Nodes to Never",callback:u(()=>{for(const s of n)A(s,2)},"callback")}),t.push({content:"Bypass Group Nodes",callback:u(()=>{for(const s of n)A(s,4)},"callback")});break;case 2:t.push({content:"Set Group Nodes to Always",callback:u(()=>{for(const s of n)A(s,0)},"callback")}),t.push({content:"Bypass Group Nodes",callback:u(()=>{for(const s of n)A(s,4)},"callback")});break;case 4:t.push({content:"Set Group Nodes to Always",callback:u(()=>{for(const s of n)A(s,0)},"callback")}),t.push({content:"Set Group Nodes to Never",callback:u(()=>{for(const s of n)A(s,2)},"callback")});break;default:t.push({content:"Set Group Nodes to Always",callback:u(()=>{for(const s of n)A(s,0)},"callback")}),t.push({content:"Set Group Nodes to Never",callback:u(()=>{for(const s of n)A(s,2)},"callback")}),t.push({content:"Bypass Group Nodes",callback:u(()=>{for(const s of n)A(s,4)},"callback")});break}else t.push({content:"Set Group Nodes to Always",callback:u(()=>{for(const s of n)A(s,0)},"callback")}),t.push({content:"Set Group Nodes to Never",callback:u(()=>{for(const s of n)A(s,2)},"callback")}),t.push({content:"Bypass Group Nodes",callback:u(()=>{for(const s of n)A(s,4)},"callback")});return t}});K().registerExtension({name:"Comfy.ImageCompare",async nodeCreated(e){if(e.constructor.comfyClass!=="ImageCompare")return;const[t,i]=e.size;e.setSize([Math.max(t,400),Math.max(i,350)]);const n=e.onExecuted;e.onExecuted=function(o){n?.call(this,o);const{a_images:s,b_images:r}=o,a=g.getRandParam(),l=s&&s.length>0?E.apiURL(`/view?${new URLSearchParams(s[0])}${a}`):"",d=r&&r.length>0?E.apiURL(`/view?${new URLSearchParams(r[0])}${a}`):"",c=e.widgets?.find(m=>m.type==="imagecompare");c&&(c.value={before:l,after:d},c.callback?.(c.value))}}});K().registerExtension({name:"Comfy.ImageCrop",async nodeCreated(e){if(e.constructor.comfyClass!=="ImageCrop")return;const[t,i]=e.size;e.setSize([Math.max(t,300),Math.max(i,450)])}});var fo=[{label:"GLB",value:"glb"},{label:"OBJ",value:"obj"},{label:"STL",value:"stl"}];function we(e){return[null,{content:"Save",has_submenu:!0,callback:u((t,i,n,o)=>{const s=fo.map(r=>({content:r.label,callback:u(()=>{(async()=>{try{await e.exportModel(r.value),M().add({severity:"success",summary:_("toastMessages.exportSuccess",{format:r.label})})}catch(a){console.error("Export failed:",a),M().addAlert(_("toastMessages.failedToExportModel",{format:r.label}))}})()},"callback")}));new k.ContextMenu(s,{event:n,parentMenu:o})},"callback")}]}u(we,"createExportMenuItems");window.comfyAPI=window.comfyAPI||{};window.comfyAPI.exportMenuHelper=window.comfyAPI.exportMenuHelper||{};window.comfyAPI.exportMenuHelper.createExportMenuItems=we;var ho=class{static{u(this,"Load3DConfiguration")}constructor(e,t){this.load3d=e,this.properties=t}configureForSaveMesh(e,t){this.setupModelHandlingForSaveMesh(t,e),this.setupDefaultProperties()}configure(e){this.setupModelHandling(e.modelWidget,e.loadFolder,e.cameraState),this.setupTargetSize(e.width,e.height),this.setupDefaultProperties(e.bgImagePath)}setupTargetSize(e,t){e&&t&&(this.load3d.setTargetSize(e.value,t.value),e.callback=i=>{this.load3d.setTargetSize(i,t.value)},t.callback=i=>{this.load3d.setTargetSize(e.value,i)})}setupModelHandlingForSaveMesh(e,t){const i=this.createModelUpdateHandler(t);e&&i(e)}setupModelHandling(e,t,i){const n=this.createModelUpdateHandler(t,i);e.value&&n(e.value);const o=e.callback;let s=e.value;Object.defineProperty(e,"value",{get(){return s},set(r){s=r,e.callback&&r!==void 0&&r!==""&&e.callback(r)},enumerable:!0,configurable:!0}),e.callback=r=>{n(r),o&&o(r)}}setupDefaultProperties(e){const t=this.loadSceneConfig();this.applySceneConfig(t,e);const i=this.loadCameraConfig();this.applyCameraConfig(i);const n=this.loadLightConfig();this.applyLightConfig(n)}loadSceneConfig(){return this.properties&&"Scene Config"in this.properties?this.properties["Scene Config"]:{showGrid:ne().get("Comfy.Load3D.ShowGrid"),backgroundColor:"#"+ne().get("Comfy.Load3D.BackgroundColor"),backgroundImage:""}}loadCameraConfig(){return this.properties&&"Camera Config"in this.properties?this.properties["Camera Config"]:{cameraType:ne().get("Comfy.Load3D.CameraType"),fov:35}}loadLightConfig(){return this.properties&&"Light Config"in this.properties?this.properties["Light Config"]:{intensity:ne().get("Comfy.Load3D.LightIntensity")}}loadModelConfig(){return this.properties&&"Model Config"in this.properties?this.properties["Model Config"]:{upDirection:"original",materialMode:"original",showSkeleton:!1}}applySceneConfig(e,t){if(this.load3d.toggleGrid(e.showGrid),this.load3d.setBackgroundColor(e.backgroundColor),e.backgroundImage){if(t&&t!=e.backgroundImage)return;this.load3d.setBackgroundImage(e.backgroundImage),e.backgroundRenderMode&&this.load3d.setBackgroundRenderMode(e.backgroundRenderMode)}}applyCameraConfig(e){this.load3d.toggleCamera(e.cameraType),this.load3d.setFOV(e.fov),e.state&&this.load3d.setCameraState(e.state)}applyLightConfig(e){this.load3d.setLightIntensity(e.intensity)}applyModelConfig(e){this.load3d.setUpDirection(e.upDirection),this.load3d.setMaterialMode(e.materialMode)}createModelUpdateHandler(e,t){let i=!0;return async n=>{if(!n)return;const o=n;this.setResourceFolder(o);const s=E.apiURL(W.getResourceURL(...W.splitFilePath(o),e));await this.load3d.loadModel(s,o);const r=this.loadModelConfig();if(this.applyModelConfig(r),i&&t){try{this.load3d.setCameraState(t)}catch(a){console.warn("Failed to restore camera state:",a)}i=!1}}}setResourceFolder(e){const t=e.split("/").filter(n=>n.trim());if(t.length<=2)return;const i=t.slice(1,-1).join("/");i&&this.properties&&(this.properties["Resource Folder"]=i)}},We=ho,mo={name:"image",type:"Load3D",isPreview:!1},Xe={name:"image",type:"Preview3D",isPreview:!0};async function yo(e,t){if(!e?.length)return;const i=t.widgets?.find(n=>n.name==="model_file");try{const n=t.properties["Resource Folder"]||"",o=n.trim()?`3d/${n.trim()}`:"3d",s=await W.uploadFile(e[0],o);if(!s){M().addAlert(_("toastMessages.fileUploadFailed"));return}const r=E.apiURL(W.getResourceURL(...W.splitFilePath(s),"input"));ue(t).waitForLoad3d(a=>{try{a.loadModel(r)}catch{M().addAlert(_("toastMessages.failedToLoadModel"))}}),s&&i&&(i.options?.values?.includes(s)||i.options?.values?.push(s),i.value=s)}catch(n){console.error("Model upload failed:",n),M().addAlert(_("toastMessages.fileUploadFailed"))}}u(yo,"handleModelUpload");async function wo(e,t){if(e?.length)try{const i=t.properties["Resource Folder"]||"",n=i.trim()?`3d/${i.trim()}`:"3d";await W.uploadMultipleFiles(e,n)}catch(i){console.error("Extra resources upload failed:",i),M().addAlert(_("toastMessages.extraResourcesUploadFailed"))}}u(wo,"handleResourcesUpload");function Je(e,t=!1){const i=document.createElement("input");return i.type="file",i.accept=e,i.multiple=t,i.style.display="none",i}u(Je,"createFileInput");K().registerExtension({name:"Comfy.Load3D",settings:[{id:"Comfy.Load3D.ShowGrid",category:["3D","Scene","Initial Grid Visibility"],name:"Initial Grid Visibility",tooltip:"Controls whether the grid is visible by default when a new 3D widget is created. This default can still be toggled individually for each widget after creation.",type:"boolean",defaultValue:!0,experimental:!0},{id:"Comfy.Load3D.BackgroundColor",category:["3D","Scene","Initial Background Color"],name:"Initial Background Color",tooltip:"Controls the default background color of the 3D scene. This setting determines the background appearance when a new 3D widget is created, but can be adjusted individually for each widget after creation.",type:"color",defaultValue:"282828",experimental:!0},{id:"Comfy.Load3D.CameraType",category:["3D","Camera","Initial Camera Type"],name:"Initial Camera Type",tooltip:"Controls whether the camera is perspective or orthographic by default when a new 3D widget is created. This default can still be toggled individually for each widget after creation.",type:"combo",options:["perspective","orthographic"],defaultValue:"perspective",experimental:!0},{id:"Comfy.Load3D.LightIntensity",category:["3D","Light","Initial Light Intensity"],name:"Initial Light Intensity",tooltip:"Sets the default brightness level of lighting in the 3D scene. This value determines how intensely lights illuminate objects when a new 3D widget is created, but can be adjusted individually for each widget after creation.",type:"number",defaultValue:3,experimental:!0},{id:"Comfy.Load3D.LightIntensityMaximum",category:["3D","Light","Light Intensity Maximum"],name:"Light Intensity Maximum",tooltip:"Sets the maximum allowable light intensity value for 3D scenes. This defines the upper brightness limit that can be set when adjusting lighting in any 3D widget.",type:"number",defaultValue:10,experimental:!0},{id:"Comfy.Load3D.LightIntensityMinimum",category:["3D","Light","Light Intensity Minimum"],name:"Light Intensity Minimum",tooltip:"Sets the minimum allowable light intensity value for 3D scenes. This defines the lower brightness limit that can be set when adjusting lighting in any 3D widget.",type:"number",defaultValue:1,experimental:!0},{id:"Comfy.Load3D.LightAdjustmentIncrement",category:["3D","Light","Light Adjustment Increment"],name:"Light Adjustment Increment",tooltip:"Controls the increment size when adjusting light intensity in 3D scenes. A smaller step value allows for finer control over lighting adjustments, while a larger value results in more noticeable changes per adjustment.",type:"slider",attrs:{min:.1,max:1,step:.1},defaultValue:.5,experimental:!0},{id:"Comfy.Load3D.3DViewerEnable",category:["3D","3DViewer","Enable"],name:"Enable 3D Viewer (Beta)",tooltip:"Enables the 3D Viewer (Beta) for selected nodes. This feature allows you to visualize and interact with 3D models directly within the full size 3d viewer.",type:"boolean",defaultValue:!1,experimental:!0},{id:"Comfy.Load3D.PLYEngine",category:["3D","PLY","PLY Engine"],name:"PLY Engine",tooltip:'Select the engine for loading PLY files. "threejs" uses the native Three.js PLYLoader (best for mesh PLY files). "fastply" uses an optimized loader for ASCII point cloud PLY files. "sparkjs" uses Spark.js for 3D Gaussian Splatting PLY files.',type:"combo",options:["threejs","fastply","sparkjs"],defaultValue:"threejs",experimental:!0}],commands:[{id:"Comfy.3DViewer.Open3DViewer",icon:"pi pi-pencil",label:"Open 3D Viewer (Beta) for Selected Node",function:u(()=>{const e=g.canvas.selected_nodes;if(!e||Object.keys(e).length!==1)return;const t=e[Object.keys(e)[0]];if(!Lt(t))return;S.copyToClipspace(t),S.clipspace_return_node=t;const i={node:t};nt().showDialog({key:"global-load3d-viewer",title:_("load3d.viewer.title"),component:zt,props:i,dialogComponentProps:{style:"width: 80vw; height: 80vh;",maximizable:!0,onClose:u(async()=>{await me().handleViewerClose(i.node)},"onClose")}})},"function")}],getCustomWidgets(){return{LOAD_3D(e){const t=Je(".gltf,.glb,.obj,.fbx,.stl,.ply,.spz,.splat,.ksplat",!1);e.properties["Resource Folder"]="",t.onchange=async()=>{await yo(t.files,e)},e.addWidget("button","upload 3d model","upload3dmodel",()=>{t.click()});const i=Je("*",!0);i.onchange=async()=>{await wo(i.files,e),i.value=""},e.addWidget("button","upload extra resources","uploadExtraResources",()=>{i.click()}),e.addWidget("button","clear","clear",()=>{ue(e).waitForLoad3d(s=>{s.clearModel()});const o=e.widgets?.find(s=>s.name==="model_file");o&&(o.value="")});const n=new Ae({node:e,name:"image",component:Le,inputSpec:mo,options:{}});return n.type="load3D",Oe(e,n),{widget:n}}}},getNodeMenuItems(e){if(e.constructor.comfyClass!=="Load3D")return[];const t=me().getLoad3d(e);return t?t.isSplatModel()?[]:we(t):[]},async nodeCreated(e){if(e.constructor.comfyClass!=="Load3D")return;const[t,i]=e.size;e.setSize([Math.max(t,300),Math.max(i,600)]),await Ee(),ue(e).waitForLoad3d(n=>{const o=e.properties["Camera Config"]?.state,s=new We(n,e.properties),r=e.widgets?.find(c=>c.name==="model_file"),a=e.widgets?.find(c=>c.name==="width"),l=e.widgets?.find(c=>c.name==="height"),d=e.widgets?.find(c=>c.name==="image");if(r&&a&&l&&d){const c={loadFolder:"input",modelWidget:r,cameraState:o,width:a,height:l};s.configure(c),d.serializeValue=async()=>{const m=jt.get(e);if(!m)return console.error("No load3d instance found for node"),null;const h=e.properties["Camera Config"]||{cameraType:m.getCurrentCameraType(),fov:m.cameraManager.perspectiveCamera.fov};h.state=m.getCameraState(),e.properties["Camera Config"]=h,m.stopRecording();const{scene:w,mask:p,normal:y}=await m.captureScene(a.value,l.value),[v,f,b]=await Promise.all([W.uploadTempImage(w,"scene"),W.uploadTempImage(p,"scene_mask"),W.uploadTempImage(y,"scene_normal")]);m.handleResize();const I={image:`threed/${v.name} [temp]`,mask:`threed/${f.name} [temp]`,normal:`threed/${b.name} [temp]`,camera_info:e.properties["Camera Config"]?.state||null,recording:""},C=m.getRecordingData();if(C){const[D]=await Promise.all([W.uploadTempImage(C,"recording","mp4")]);I.recording=`threed/${D.name} [temp]`}return I}}})}});K().registerExtension({name:"Comfy.Preview3D",async beforeRegisterNodeDef(e,t){t.name==="Preview3D"&&(t.input.required.image=["PREVIEW_3D"])},getNodeMenuItems(e){if(e.constructor.comfyClass!=="Preview3D")return[];const t=me().getLoad3d(e);return t?t.isSplatModel()?[]:we(t):[]},getCustomWidgets(){return{PREVIEW_3D(e){const t=new Ae({node:e,name:Xe.name,component:Le,inputSpec:Xe,options:{}});return t.type="load3D",Oe(e,t),{widget:t}}}},async nodeCreated(e){if(e.constructor.comfyClass!=="Preview3D")return;const[t,i]=e.size;e.setSize([Math.max(t,400),Math.max(i,550)]),await Ee();const n=e.onExecuted;ue(e).waitForLoad3d(o=>{const s=new We(o,e.properties),r=e.widgets?.find(a=>a.name==="model_file");if(r){const a=e.properties["Last Time Model File"];if(a){r.value=a;const l={loadFolder:"output",modelWidget:r,cameraState:e.properties["Camera Config"]?.state};s.configure(l)}e.onExecuted=function(l){n?.call(this,l);const d=l.result,c=d?.[0];if(!c){const p=_("toastMessages.unableToGetModelFilePath");console.error(p),M().addAlert(p)}const m=d?.[1],h=d?.[2];r.value=c?.replaceAll("\\","/"),e.properties["Last Time Model File"]=r.value;const w={loadFolder:"output",modelWidget:r,cameraState:m,bgImagePath:h};s.configure(w),h&&o.setBackgroundImage(h)}}})}});function pt(e){if(!e){console.error("[MaskEditor] No node provided");return}if(!e.imgs?.length&&e.previewMediaType!=="image"){console.error("[MaskEditor] Node has no images");return}qt().openMaskEditor(e)}u(pt,"openMaskEditor");function vo(){const e=S.clipspace_return_node;if(!e){console.error("[MaskEditor] No clipspace_return_node found");return}pt(e)}u(vo,"openMaskEditorFromClipspace");function oe(){return nt().isDialogOpen("global-mask-editor")}u(oe,"isOpened");var Ke=u(async e=>{if(!oe())return;const t=st(),i=t.brushSettings.size,n=e(i);t.setBrushSize(n)},"changeBrushSize");g.registerExtension({name:"Comfy.MaskEditor",settings:[{id:"Comfy.MaskEditor.BrushAdjustmentSpeed",category:["Mask Editor","BrushAdjustment","Sensitivity"],name:"Brush adjustment speed multiplier",tooltip:"Controls how quickly the brush size and hardness change when adjusting. Higher values mean faster changes.",type:"slider",attrs:{min:.1,max:2,step:.1},defaultValue:1,versionAdded:"1.0.0"},{id:"Comfy.MaskEditor.UseDominantAxis",category:["Mask Editor","BrushAdjustment","UseDominantAxis"],name:"Lock brush adjustment to dominant axis",tooltip:"When enabled, brush adjustments will only affect size OR hardness based on which direction you move more",type:"boolean",defaultValue:!0}],commands:[{id:"Comfy.MaskEditor.OpenMaskEditor",icon:"pi pi-pencil",label:"Open Mask Editor for Selected Node",function:u(()=>{const e=g.canvas.selected_nodes;if(!e||Object.keys(e).length!==1)return;const t=e[Object.keys(e)[0]];pt(t)},"function")},{id:"Comfy.MaskEditor.BrushSize.Increase",icon:"pi pi-plus-circle",label:"Increase Brush Size in MaskEditor",function:u(()=>Ke(e=>q.clamp(e+2,1,250)),"function")},{id:"Comfy.MaskEditor.BrushSize.Decrease",icon:"pi pi-minus-circle",label:"Decrease Brush Size in MaskEditor",function:u(()=>Ke(e=>q.clamp(e-2,1,250)),"function")},{id:"Comfy.MaskEditor.ColorPicker",icon:"pi pi-palette",label:"Open Color Picker in MaskEditor",function:u(()=>{oe()&&st().colorInput?.click()},"function")},{id:"Comfy.MaskEditor.Rotate.Right",icon:"pi pi-refresh",label:"Rotate Right in MaskEditor",function:u(async()=>{oe()&&await ge().rotateClockwise()},"function")},{id:"Comfy.MaskEditor.Rotate.Left",icon:"pi pi-undo",label:"Rotate Left in MaskEditor",function:u(async()=>{oe()&&await ge().rotateCounterclockwise()},"function")},{id:"Comfy.MaskEditor.Mirror.Horizontal",icon:"pi pi-arrows-h",label:"Mirror Horizontal in MaskEditor",function:u(async()=>{oe()&&await ge().mirrorHorizontal()},"function")},{id:"Comfy.MaskEditor.Mirror.Vertical",icon:"pi pi-arrows-v",label:"Mirror Vertical in MaskEditor",function:u(async()=>{oe()&&await ge().mirrorVertical()},"function")}],init(){S.open_maskeditor=vo,console.warn("[MaskEditor] ComfyApp.open_maskeditor is deprecated. Plugins should migrate to using the command system or direct node context menu integration.")}});var bo="Comfy.NodeTemplates",Qe="comfy.templates.json",No=class extends it{static{u(this,"ManageTemplates")}templates;draggedEl;saveVisualCue;emptyImg;importInput;constructor(){super(),this.load().then(e=>{this.templates=e}),this.element.classList.add("comfy-manage-templates"),this.draggedEl=null,this.saveVisualCue=null,this.emptyImg=new Image,this.emptyImg.src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=",this.importInput=N("input",{type:"file",accept:".json",multiple:!0,style:{display:"none"},parent:document.body,onchange:u(()=>this.importAll(),"onchange")})}createButtons(){const e=super.createButtons();return e[0].textContent="Close",e[0].onclick=()=>{clearTimeout(this.saveVisualCue),this.close()},e.unshift(N("button",{type:"button",textContent:"Export",onclick:u(()=>this.exportAll(),"onclick")})),e.unshift(N("button",{type:"button",textContent:"Import",onclick:u(()=>{this.importInput.click()},"onclick")})),e}async load(){let e=[];const t=await E.getUserData(Qe);if(t.status===200)try{e=await t.json()}catch{}else t.status!==404&&console.error(t.status+" "+t.statusText);return e??[]}async store(){const e=JSON.stringify(this.templates,void 0,4);try{await E.storeUserData(Qe,e,{stringify:!1})}catch(t){console.error(t),M().addAlert(t.message)}}async importAll(){for(const e of this.importInput.files)if(e.type==="application/json"||e.name.endsWith(".json")){const t=new FileReader;t.onload=async()=>{const i=JSON.parse(t.result);if(i?.templates){for(const n of i.templates)n?.name&&n?.data&&this.templates.push(n);await this.store()}},await t.readAsText(e)}this.importInput.value=null,this.close()}exportAll(){if(this.templates.length==0){M().addAlert(_("toastMessages.noTemplatesToExport"));return}const e=JSON.stringify({templates:this.templates},null,2);Be("node_templates.json",new Blob([e],{type:"application/json"}))}show(){super.show(N("div",{},this.templates.flatMap((e,t)=>{let i;return[N("div",{dataset:{id:t.toString()},className:"templateManagerRow",style:{display:"grid",gridTemplateColumns:"1fr auto",border:"1px dashed transparent",gap:"5px",backgroundColor:"var(--comfy-menu-bg)"},ondragstart:u(n=>{this.draggedEl=n.currentTarget,n.currentTarget.style.opacity="0.6",n.currentTarget.style.border="1px dashed yellow",n.dataTransfer.effectAllowed="move",n.dataTransfer.setDragImage(this.emptyImg,0,0)},"ondragstart"),ondragend:u(n=>{n.target.style.opacity="1",n.currentTarget.style.border="1px dashed transparent",n.currentTarget.removeAttribute("draggable"),this.element.querySelectorAll(".templateManagerRow").forEach((o,s)=>{var r=Number.parseInt(o.dataset.id);o==this.draggedEl&&r!=s&&this.templates.splice(s,0,this.templates.splice(r,1)[0]),o.dataset.id=s.toString()}),this.store()},"ondragend"),ondragover:u(n=>{if(n.preventDefault(),n.currentTarget==this.draggedEl)return;let o=n.currentTarget.getBoundingClientRect();n.clientY>o.top+o.height/2?n.currentTarget.parentNode.insertBefore(this.draggedEl,n.currentTarget.nextSibling):n.currentTarget.parentNode.insertBefore(this.draggedEl,n.currentTarget)},"ondragover")},[N("label",{textContent:"Name: ",style:{cursor:"grab"},onmousedown:u(n=>{n.target.localName=="label"&&(n.currentTarget.parentNode.draggable="true")},"onmousedown")},[N("input",{value:e.name,dataset:{name:e.name},style:{transitionProperty:"background-color",transitionDuration:"0s"},onchange:u(n=>{clearTimeout(this.saveVisualCue);var o=n.target,s=o.parentNode.parentNode;this.templates[s.dataset.id].name=o.value.trim()||"untitled",this.store(),o.style.backgroundColor="rgb(40, 95, 40)",o.style.transitionDuration="0s",this.saveVisualCue=setTimeout(function(){o.style.transitionDuration=".7s",o.style.backgroundColor="var(--comfy-input-bg)"},15)},"onchange"),onkeypress:u(n=>{var o=n.target;clearTimeout(this.saveVisualCue),o.style.transitionDuration="0s",o.style.backgroundColor="var(--comfy-input-bg)"},"onkeypress"),$:u(n=>i=n,"$")})]),N("div",{},[N("button",{textContent:"Export",style:{fontSize:"12px",fontWeight:"normal"},onclick:u(()=>{const n=JSON.stringify({templates:[e]},null,2),o=new Blob([n],{type:"application/json"});Be((i.value||e.name)+".json",o)},"onclick")}),N("button",{textContent:"Delete",style:{fontSize:"12px",color:"red",fontWeight:"normal"},onclick:u(n=>{const o=n.target.parentNode.parentNode;o.parentNode.removeChild(o),this.templates.splice(o.dataset.id*1,1),this.store();var s=this;setTimeout(function(){s.element.querySelectorAll(".templateManagerRow").forEach((r,a)=>{r.dataset.id=a.toString()})},0)},"onclick")})])])]})))}},fe=new No,Ze=u(async e=>{const t=localStorage.getItem("litegrapheditor_clipboard");await e(),localStorage.setItem("litegrapheditor_clipboard",t)},"clipboardAction"),Io={name:bo,getCanvasMenuItems(e){const t=[];t.push(null),t.push({content:"Save Selected as Template",disabled:!Object.keys(g.canvas.selected_nodes||{}).length,callback:u(async()=>{const n=await re().prompt({title:_("nodeTemplates.saveAsTemplate"),message:_("nodeTemplates.enterName"),defaultValue:""});n?.trim()&&Ze(()=>{g.canvas.copyToClipboard();let o=localStorage.getItem("litegrapheditor_clipboard");o=JSON.parse(o||"{}");const s=Object.keys(g.canvas.selected_nodes);for(let r=0;r<s.length;r++){const a=g.canvas.graph?.getNodeById(s[r]),l=a?.constructor.nodeData;if(!a)continue;const d=R.getGroupData(a);if(d){const c=d.nodeData;if(o.groupNodes||(o.groupNodes={}),l==null)throw new TypeError("nodeData is not set");o.groupNodes[l.name]=c,o.nodes[r].type=l.name}}fe.templates.push({name:n,data:JSON.stringify(o)}),fe.store()})},"callback")});const i=fe.templates.map(n=>({content:n.name,callback:u(()=>{Ze(async()=>{const o=JSON.parse(n.data);await ie.registerFromWorkflow(o.groupNodes??{},[]),o.reroutes?(localStorage.setItem("litegrapheditor_clipboard",n.data),g.canvas.pasteFromClipboard()):at(n.data,g.canvas)})},"callback")}));return i.push(null,{content:"Manage",callback:u(()=>fe.show(),"callback")}),t.push({content:"Node Templates",submenu:{options:i}}),t}};g.registerExtension(Io);g.registerExtension({name:"Comfy.NoteNode",registerCustomNodes(){class e extends he{static{u(this,"NoteNode")}static category;static collapsable;static title_mode;groupcolor=L.node_colors.yellow.groupcolor;isVirtualNode;constructor(n){super(n),this.color=L.node_colors.yellow.color,this.bgcolor=L.node_colors.yellow.bgcolor,this.properties||(this.properties={text:""}),$.STRING(this,"text",["STRING",{default:this.properties.text,multiline:!0}],g),this.serialize_widgets=!0,this.isVirtualNode=!0}}k.registerNodeType("Note",Object.assign(e,{title_mode:k.NORMAL_TITLE,title:"Note",collapsable:!0})),e.category="utils";class t extends he{static{u(this,"MarkdownNoteNode")}static title="Markdown Note";groupcolor=L.node_colors.yellow.groupcolor;constructor(n){super(n),this.color=L.node_colors.yellow.color,this.bgcolor=L.node_colors.yellow.bgcolor,this.properties||(this.properties={text:""}),$.MARKDOWN(this,"text",["STRING",{default:this.properties.text}],g),this.serialize_widgets=!0,this.isVirtualNode=!0}}k.registerNodeType("MarkdownNote",t),t.category="utils"}});K().registerExtension({name:"Comfy.PreviewAny",async beforeRegisterNodeDef(e,t){if(t.name==="PreviewAny"){const i=e.prototype.onNodeCreated;e.prototype.onNodeCreated=function(){i&&i.apply(this,[]);const o=$.MARKDOWN(this,"preview",["MARKDOWN",{}],g).widget,s=$.STRING(this,"preview",["STRING",{multiline:!0}],g).widget,r=$.BOOLEAN(this,"previewMode",["BOOLEAN",{label_on:"Markdown",label_off:"Plaintext",default:!1}],g);r.widget.callback=a=>{o.hidden=!a,o.options.hidden=!a,s.hidden=a,s.options.hidden=a},o.hidden=!0,o.options.hidden=!0,o.options.read_only=!0,o.element.readOnly=!0,o.element.disabled=!0,o.serialize=!1,s.hidden=!1,s.options.hidden=!1,s.options.read_only=!0,s.element.readOnly=!0,s.element.disabled=!0,s.serialize=!1};const n=e.prototype.onExecuted;e.prototype.onExecuted=function(o){n?.apply(this,[o]);const s=this.widgets?.filter(r=>r.name==="preview")??[];for(const r of s){const a=o.text??"";r.value=Array.isArray(a)?a[0]??"":a}}}}});g.registerExtension({name:"Comfy.RerouteNode",registerCustomNodes(e){class t extends he{static{u(this,"RerouteNode")}static category;static defaultVisibility=!1;constructor(n){super(n??""),this.properties||(this.properties={}),this.properties.showOutputText=t.defaultVisibility,this.properties.horizontal=!1,this.addInput("","*"),this.addOutput(this.properties.showOutputText?"*":"","*"),this.isVirtualNode=!0}onAfterGraphConfigured(){requestAnimationFrame(()=>{this.onConnectionsChange(k.INPUT,void 0,!0)})}clone(){const n=super.clone();return n&&(n.removeOutput(0),n.addOutput(this.properties.showOutputText?"*":"","*"),n.setSize(n.computeSize()),n)}onConnectionsChange(n,o,s){const{graph:r}=this;if(!r||e.configuringGraph)return;if(s&&n===k.OUTPUT&&new Set(this.outputs[0].links?.map(f=>r.links[f]?.type)?.filter(f=>f&&f!=="*")??[]).size>1){const f=[];for(const b of this.outputs[0].links??[]){const I=r.links[b];f.push(I)}f.pop();for(const b of f)r.getNodeById(b.target_id)?.disconnectInput(b.target_slot)}let a=this,l=[],d=null,c=null;for(;a;){l.unshift(a);const f=a.inputs[0].link;if(f!==null){const b=r.links[f];if(!b)return;const I=r.getNodeById(b.origin_id);if(!I)return;if(I instanceof t)I===this?(a.disconnectInput(b.target_slot),a=null):a=I;else{c=a,d=I.outputs[b.origin_slot]?.type??null;break}}else{a=null;break}}const m=[this];let h=null;for(;m.length;){a=m.pop();const f=a.outputs?.[0]?.links??[];for(const b of f){const I=r.links[b];if(!I)continue;const C=r.getNodeById(I.target_id);if(C)if(C instanceof t)m.push(C),l.push(C);else{const D=C.inputs[I.target_slot],x=D.type,T=!d||!x||k.isValidConnection(d,x);if(!T){C.disconnectInput(I.target_slot);continue}C.onConnectionsChange?.(k.INPUT,I.target_slot,T,I,D),h=C.inputs[I.target_slot].type}}}const w=d||h||"*",p=L.link_type_colors[w];let y,v;for(const f of l){f.outputs[0].type=d||"*",f.__outputType=w,f.outputs[0].name=f.properties.showOutputText?`${w}`:"",f.setSize(f.computeSize());for(const b of f.outputs[0].links||[]){const I=r.links[b];if(!I||(I.color=p,e.configuringGraph))continue;const C=r.getNodeById(I.target_id);if(!C)continue;const D=C.inputs?.[I.target_slot];if(D?.widget){const x=Ge(D);y||(y=x[1]??{},v=x[0]);const T=pe(D,[x[0],y]);T.customConfig&&(y=T.customConfig)}}}for(const f of l)y&&h?(f.inputs[0].widget={name:"value"},Se(f.inputs[0],[v??`${w}`,y])):Se(f.inputs[0],void 0);if(c?.inputs?.[0]?.link){const f=r.links[c.inputs[0].link];f&&(f.color=p)}}getExtraMenuOptions(n,o){return o.unshift({content:(this.properties.showOutputText?"Hide":"Show")+" Type",callback:u(()=>{this.properties.showOutputText=!this.properties.showOutputText,this.properties.showOutputText?this.outputs[0].name=`${this.__outputType||this.outputs[0].type}`:this.outputs[0].name="",this.setSize(this.computeSize()),e.canvas.setDirty(!0,!0)},"callback")},{content:(t.defaultVisibility?"Hide":"Show")+" Type By Default",callback:u(()=>{t.setDefaultTextVisibility(!t.defaultVisibility)},"callback")}),[]}computeSize(){return[this.properties.showOutputText&&this.outputs&&this.outputs.length?Math.max(75,k.NODE_TEXT_SIZE*this.outputs[0].name.length*.6+40):75,26]}static setDefaultTextVisibility(n){t.defaultVisibility=n,n?localStorage["Comfy.RerouteNode.DefaultVisibility"]="true":delete localStorage["Comfy.RerouteNode.DefaultVisibility"]}}t.setDefaultTextVisibility(!!localStorage["Comfy.RerouteNode.DefaultVisibility"]),k.registerNodeType("Reroute",Object.assign(t,{title_mode:k.NO_TITLE,title:"Reroute",collapsable:!1})),t.category="utils"}});var Co=new Set(["SaveImage","SaveVideo","SaveAnimatedWEBP","SaveWEBM","SaveAudio","SaveGLB","SaveAnimatedPNG","CLIPSave","VAESave","ModelSave","LoraSave","SaveLatent"]);g.registerExtension({name:"Comfy.SaveImageExtraOutput",async beforeRegisterNodeDef(e,t,i){if(Co.has(t.name)){const n=e.prototype.onNodeCreated;e.prototype.onNodeCreated=function(){const o=n?n.apply(this,arguments):void 0,s=this.widgets.find(r=>r.name==="filename_prefix");return s.serializeValue=()=>rt(i.graph,s.value),o}}else{const n=e.prototype.onNodeCreated;e.prototype.onNodeCreated=function(){const o=n?n.apply(this,arguments):void 0;return(!this.properties||!("Node name for S&R"in this.properties))&&this.addProperty("Node name for S&R",this.constructor.type,"string"),o}}}});var et={name:"image",type:"Preview3D",isPreview:!0};K().registerExtension({name:"Comfy.SaveGLB",async beforeRegisterNodeDef(e,t){t.name==="SaveGLB"&&(t.input.required.image=["PREVIEW_3D"])},getCustomWidgets(){return{PREVIEW_3D(e){const t=new Ae({node:e,name:et.name,component:Le,inputSpec:et,options:{}});return t.type="load3D",Oe(e,t),{widget:t}}}},getNodeMenuItems(e){if(e.constructor.comfyClass!=="SaveGLB")return[];const t=me().getLoad3d(e);return t?t.isSplatModel()?[]:we(t):[]},async nodeCreated(e){if(e.constructor.comfyClass!=="SaveGLB")return;const[t,i]=e.size;e.setSize([Math.max(t,400),Math.max(i,550)]),await Ee();const n=e.onExecuted;e.onExecuted=function(o){n?.call(this,o);const s=o["3d"]?.[0];s&&ue(e).waitForLoad3d(r=>{const a=e.widgets?.find(l=>l.name==="image");if(r&&a){const l=(s.subfolder??"")+"/"+(s.filename??"");a.value=l;const d=new We(r,e.properties),c=s.type,m=u(()=>{r.removeEventListener("modelLoadingEnd",m),W.generateThumbnailIfNeeded(r,l,c)},"onModelLoaded");r.addEventListener("modelLoadingEnd",m),d.configureForSaveMesh(c,l)}})}}});function ko(e,t){const i=t.selectedItems;if(i.size<=1)return;const n=_t(i,10);if(!n)return;const[o,s,r,a]=n;e.save(),e.lineWidth=2/t.ds.scale,e.strokeStyle=getComputedStyle(document.documentElement).getPropertyValue("--border-color").trim()||"#ffffff66";const l=5/t.ds.scale;e.setLineDash([l,l]),e.beginPath(),e.roundRect(o,s,r,a,8/t.ds.scale),e.stroke(),e.restore()}u(ko,"drawSelectionBorder");g.registerExtension({name:"Comfy.SelectionBorder",async init(){const e=g.canvas.onDrawForeground;g.canvas.onDrawForeground=function(t,i){e?.call(this,t,i),ko(t,g.canvas)}}});var de=!1,ce=0;g.registerExtension({name:"Comfy.SimpleTouchSupport",setup(){let e=null,t=null,i=null,n=null;function o(a){return Math.hypot(a.touches[0].clientX-a.touches[1].clientX,a.touches[0].clientY-a.touches[1].clientY)}u(o,"getMultiTouchPos");function s(a){return{clientX:(a.touches[0].clientX+a.touches[1].clientX)/2,clientY:(a.touches[0].clientY+a.touches[1].clientY)/2}}u(s,"getMultiTouchCenter"),g.canvasEl.parentElement?.addEventListener("touchstart",a=>{ce+=a.changedTouches.length,i=null,n=null,a.touches?.length===1?(t=new Date,i=a.touches[0]):(t=null,a.touches?.length===2&&(n=g.canvas.ds.scale,i=s(a),e=o(a),g.canvas.pointer.isDown=!1))},!0),g.canvasEl.parentElement?.addEventListener("touchend",a=>{if(ce-=a.changedTouches.length,a.touches?.length!==1&&(de=!1),t&&!a.touches?.length){if(new Date().getTime()-t.getTime()>600&&a.target===g.canvasEl){const l={button:2,clientX:a.changedTouches[0].clientX,clientY:a.changedTouches[0].clientY,pointerId:1,isPrimary:!0};g.canvasEl.dispatchEvent(new PointerEvent("pointerdown",l)),setTimeout(()=>{g.canvasEl.dispatchEvent(new PointerEvent("pointerup",l))}),a.preventDefault()}t=null}});const r=u(()=>{ce=0,de=!1,t=null,i=null,n=null,e=null},"resetTouchState");document.addEventListener("visibilitychange",()=>{document.hidden&&r()}),g.canvasEl.parentElement?.addEventListener("touchcancel",r),g.canvasEl.parentElement?.addEventListener("touchmove",a=>{if(t&&i&&a.touches?.length===1){const c=a.touches[0],m=c.clientX-i.clientX,h=c.clientY-i.clientY;m*m+h*h>30&&(t=null)}if(a.touches?.length===2&&i&&!a.ctrlKey&&!a.shiftKey){a.preventDefault(),g.canvas.pointer.isDown=!1,de=!0,k.closeAllContextMenus(window),g.canvas.search_box?.close();const c=o(a),m=s(a);if(n===null||e===null)return;let h=n*c/e;const w=(m.clientX-i.clientX)/h,p=(m.clientY-i.clientY)/h;h<g.canvas.ds.min_scale?h=g.canvas.ds.min_scale:h>g.canvas.ds.max_scale&&(h=g.canvas.ds.max_scale);const y=g.canvas.ds.scale;g.canvas.ds.scale=h,Math.abs(g.canvas.ds.scale-1)<.01&&(g.canvas.ds.scale=1);const v=g.canvas.ds.scale,f=u(b=>[m.clientX/b-g.canvas.ds.offset[0],m.clientY/b-g.canvas.ds.offset[1]],"convertScaleToOffset");var l=f(y),d=f(v);g.canvas.ds.offset[0]+=w+d[0]-l[0],g.canvas.ds.offset[1]+=p+d[1]-l[1],i.clientX=m.clientX,i.clientY=m.clientY,g.canvas.setDirty(!0,!0)}},!0)}});var Do=L.prototype.processMouseDown;L.prototype.processMouseDown=function(e){if(!(de||ce))return g.canvas.pointer.isDown=!1,Do.apply(this,[e])};var _o=L.prototype.processMouseMove;L.prototype.processMouseMove=function(e){if(!(de||ce>1))return _o.apply(this,[e])};g.registerExtension({name:"Comfy.SlotDefaults",suggestionsNumber:null,init(){k.search_filter_enabled=!0,k.middle_click_slot_add_default_node=!0,this.suggestionsNumber=g.ui.settings.addSetting({id:"Comfy.NodeSuggestions.number",category:["Comfy","Node Search Box","NodeSuggestions"],name:"Number of nodes suggestions",tooltip:"Only for litegraph searchbox/context menu",type:"slider",attrs:{min:1,max:100,step:1},defaultValue:5,onChange:u(e=>{this.setDefaults(e)},"onChange")})},slot_types_default_out:{},slot_types_default_in:{},async beforeRegisterNodeDef(e,t){var i=t.name;const n=t.input?.required;for(const l in n){var o=n[l];if(typeof o[0]!="string")continue;var s=o[0];if(s in $&&!o[1]?.forceInput||(s in this.slot_types_default_out||(this.slot_types_default_out[s]=["Reroute"]),this.slot_types_default_out[s].includes(i)))continue;this.slot_types_default_out[s].push(i);const d=s.toLocaleLowerCase();d in k.registered_slot_in_types||(k.registered_slot_in_types[d]={nodes:[]}),k.registered_slot_in_types[d].nodes.push(e.comfyClass)}var r=t.output??[];for(const l of r){const d=l;d in this.slot_types_default_in||(this.slot_types_default_in[d]=["Reroute"]),!this.slot_types_default_in[d].includes(i)&&(this.slot_types_default_in[d].push(i),d in k.registered_slot_out_types||(k.registered_slot_out_types[d]={nodes:[]}),k.registered_slot_out_types[d].nodes.push(e.comfyClass),k.slot_types_out.includes(d)||k.slot_types_out.push(d))}var a=this.suggestionsNumber.value;this.setDefaults(a)},setDefaults(e){k.slot_types_default_out={},k.slot_types_default_in={};for(const t in this.slot_types_default_out)k.slot_types_default_out[t]=this.slot_types_default_out[t].slice(0,e);for(const t in this.slot_types_default_in)k.slot_types_default_in[t]=this.slot_types_default_in[t].slice(0,e)}});async function xo(e,t,i,n,o=!1){try{const s=new FormData;s.append("image",i),o&&s.append("subfolder","pasted");const r=await E.fetchApi("/upload/image",{method:"POST",body:s});if(r.status===200){const a=await r.json();let l=a.name;a.subfolder&&(l=a.subfolder+"/"+l),e.options.values.includes(l)||e.options.values.push(l),n&&(t.element.src=E.apiURL(ye(...lt(l))),e.value=l,e.callback?.(l))}else M().addAlert(r.status+" - "+r.statusText)}catch(s){M().addAlert(s)}}u(xo,"uploadFile");g.registerExtension({name:"Comfy.AudioWidget",async beforeRegisterNodeDef(e,t){["LoadAudio","SaveAudio","PreviewAudio","SaveAudioMP3","SaveAudioOpus"].includes(e.prototype.comfyClass)&&(t.input.required.audioUI=["AUDIO_UI",{}])},getCustomWidgets(){return{AUDIO_UI(e,t){const i=document.createElement("audio");i.controls=!0,i.classList.add("comfy-audio"),i.setAttribute("name","media");const n=e.addDOMWidget(t,"audioUI",i);n.serialize=!1;const{nodeData:o}=e.constructor;if(o==null)throw new TypeError("nodeData is null");if(o.output_node){n.element.classList.add("empty-audio-widget");const s=e.onExecuted;e.onExecuted=function(r){s?.call(this,r);const a=r.audio;if(!a?.length)return;const l=a[0];n.element.src=E.apiURL(ye(l.subfolder??"",l.filename??"",l.type)),n.element.classList.remove("empty-audio-widget")}}return n.onRemove=J(n.onRemove,()=>{n.element&&(n.element.pause(),n.element.src="",n.element.remove())}),{widget:n}}}},onNodeOutputsUpdated(e){for(const[t,i]of Object.entries(e)){if(!i.audio?.length)continue;const n=Ct(g.rootGraph,t);if(!n)continue;const o=n.widgets?.find(r=>r.name==="audioUI"),s=i.audio[0];o.element.src=E.apiURL(ye(s.subfolder??"",s.filename??"",s.type)),o.element.classList.remove("empty-audio-widget")}}});g.registerExtension({name:"Comfy.UploadAudio",async beforeRegisterNodeDef(e,t){t?.input?.required?.audio?.[1]?.audio_upload===!0&&(t.input.required.upload=["AUDIOUPLOAD",{}])},getCustomWidgets(){return{AUDIOUPLOAD(e,t){const i=e.widgets.find(c=>c.name==="audio"),n=e.widgets.find(c=>c.name==="audioUI");n.options.canvasOnly=!0;const o=u(()=>{typeof i.value=="string"&&(n.element.src=E.apiURL(ye(...lt(i.value))))},"onAudioWidgetUpdate");i.value&&o(),i.callback=o;const s=e.onGraphConfigured;e.onGraphConfigured=function(){s?.apply(this,arguments),i.value&&o()};const r=u(async c=>(c?.length&&xo(i,n,c[0],!0),c),"handleUpload"),a=u(c=>c.type.startsWith("audio/"),"isAudioFile"),{openFileSelection:l}=Gt(e,{accept:"audio/*",onSelect:r}),d=e.addWidget("button",t,"",l,{serialize:!1,canvasOnly:!0});return d.label=_("g.choose_file_to_upload"),Ft(e,{fileFilter:a,onDrop:r}),Pt(e,{fileFilter:a,onPaste:r}),e.previewMediaType="audio",{widget:d}}}}});g.registerExtension({name:"Comfy.RecordAudio",getCustomWidgets(){return{AUDIO_RECORD(e,t){const i=document.createElement("audio");i.controls=!0,i.classList.add("comfy-audio"),i.setAttribute("name","media");const n=e.addDOMWidget(t,"audioUI",i);n.options.canvasOnly=!1;let o=null,s=!1,r=[],a=null,l=null,d=null,c=null;n.serializeValue=async()=>{s&&o&&(d=new Promise(p=>{c=p}),o.stop(),await d);const h=n.element.src;if(!h)return M().addAlert(_("g.noAudioRecorded")),"";const w=await fetch(h).then(p=>p.blob());return await Z().convertBlobToFileAndSubmit(w)},l=e.addWidget("button",t,"",async()=>{if(s)o&&s&&o.stop();else try{a=await navigator.mediaDevices.getUserMedia({audio:!0}),o=new wt(a,{mimeType:"audio/wav"}),r=[],o.ondataavailable=h=>{r.push(h.data)},o.onstop=async()=>{const h=new Blob(r,{type:"audio/wav"});Z().stopAllTracks(a),n.element.src&&n.element.src.startsWith("blob:")&&URL.revokeObjectURL(n.element.src),n.element.src=URL.createObjectURL(h),s=!1,l&&(l.label=_("g.startRecording")),c&&(c(),c=null,d=null)},o.onerror=h=>{console.error("MediaRecorder error:",h),Z().stopAllTracks(a),s=!1,l&&(l.label=_("g.startRecording")),c&&(c(),c=null,d=null)},o.start(),s=!0,l&&(l.label=_("g.stopRecording"))}catch(h){if(console.error("Error accessing microphone:",h),M().addAlert(_("g.micPermissionDenied")),o)try{o.stop()}catch{}Z().stopAllTracks(a),a=null,s=!1,l&&(l.label=_("g.startRecording"))}},{serialize:!1,canvasOnly:!1}),l.label=_("g.startRecording"),l.type="audiorecord";const m=e.onRemoved;return e.onRemoved=function(){s&&o&&o.stop(),Z().stopAllTracks(a),n.element.src?.startsWith("blob:")&&URL.revokeObjectURL(n.element.src),m?.call(this)},{widget:l}}}},async nodeCreated(e){e.constructor.comfyClass==="RecordAudio"&&await Z().registerWavEncoder()}});var To=u(e=>{const[t,i]=e;return i?(i.image_upload===!0||i.video_upload===!0||i.animated_image_upload===!0)&&(Ot(e)||t==="COMBO"):!1},"isMediaUploadComboInput"),So=u((e,t)=>["IMAGEUPLOAD",{...t[1],imageInputName:e}],"createUploadInput");g.registerExtension({name:"Comfy.UploadImage",beforeRegisterNodeDef(e,t){const{input:i}=t??{},{required:n}=i??{};if(!n)return;const o=Object.entries(n).find(([s,r])=>To(r));if(o){const[s,r]=o;n.upload=So(s,r)}}});var tt=Symbol();g.registerExtension({name:"Comfy.WebcamCapture",getCustomWidgets(){return{WEBCAM(e,t){let i;e[tt]=new Promise(r=>i=r);const n=document.createElement("div");n.style.background="rgba(0,0,0,0.25)",n.style.textAlign="center";const o=document.createElement("video");return o.style.height=o.style.width="100%",u(async()=>{try{const r=await navigator.mediaDevices.getUserMedia({video:!0,audio:!1});n.replaceChildren(o),setTimeout(()=>i(o),500),o.addEventListener("loadedmetadata",()=>i(o),!1),o.srcObject=r,o.play()}catch(r){const a=document.createElement("div");a.style.color="red",a.style.overflow="auto",a.style.maxHeight="100%",a.style.whiteSpace="pre-wrap",window.isSecureContext?a.textContent=`Unable to load webcam, please ensure access is granted:
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./cloudRemoteConfig-F9J0iGyF.js","./vendor-primevue-DcMRXJN3.js","./vendor-other-DlQF6V2E.js","./rolldown-runtime-BN4meiq5.js","./vendor-other-CaaUC6Qe.css","./dialogService-YG0RH337.js","./_plugin-vue_export-helper-PHE0iSCb.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","./cloudBadges-D5mGJbRy.js","./cloudSessionCookie-MEORlqtg.js","./cloudFeedbackTopbarButton-RZUssOmb.js","./cloudSubscription-CuWNXKVx.js"])))=>i.map(i=>d[i]);
2
+ var ft=Object.defineProperty;var u=(e,t)=>ft(e,"name",{value:t,configurable:!0});import{r as ht}from"./rolldown-runtime-BN4meiq5.js";import{dt as se}from"./vendor-primevue-DcMRXJN3.js";import{Bo as mt,Pr as q,io as Ee,kr as yt,n as wt}from"./vendor-other-DlQF6V2E.js";import{A as _,Bt as vt,It as M,Lt as bt,N as Nt,S as It,Z as Ct,_ as kt,b as he,f as k,ft as G,m as L,r as E,v as Dt,wt as _t,y as xt,zt as ot}from"./api-Dwq2LQIW.js";import"./remoteConfig-CZcEXsZS.js";import"./colorUtil-CzxntCbX.js";import"./useErrorHandling-Cfa5N_7c.js";import"./Button-Do2I1OAA.js";import{k as Tt,v as St,w as Mt}from"./PanelTemplate-BJda9e5J.js";import{B as Et,Cr as Ot,Dn as At,Fn as Lt,Gr as Oe,In as Pt,Ln as Gt,N as S,On as Wt,P as g,R as Rt,Rn as Ft,Sn as K,Sr as Ut,Tn as $,Tr as Bt,U as Vt,W as V,Wr as Ae,Xn as nt,Yr as J,Zr as Be,_r as $t,at as ge,br as Ve,cn as zt,dn as jt,dt as Ht,fn as ue,gr as it,hr as N,it as qt,mt as Yt,nt as P,ot as st,pn as W,t as re,tt as ae,un as me,vr as rt,w as Xt,wn as Jt,wr as Kt,xr as xe,yr as ne,z as at}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";import{t as Le}from"./Load3D-vYr8M3jJ.js";import{i as lt,r as ye}from"./audioUtils-DD4rUYVZ.js";import{t as Z}from"./audioService-DvVaKhuU.js";var ee=class B extends it{static{u(this,"ClipspaceDialog")}static items=[];static instance=null;static registerButton(t,i,n){const o=N("button",{type:"button",textContent:t,contextPredicate:i,onclick:n});B.items.push(o)}static invalidatePreview(){if(S.clipspace&&S.clipspace.imgs&&S.clipspace.imgs.length>0){const t=document.getElementById("clipspace_preview");t&&(t.src=S.clipspace.imgs[S.clipspace.selectedIndex].src,t.style.maxHeight="100%",t.style.maxWidth="100%")}}static invalidate(){if(B.instance){const t=B.instance,i=N("div.comfy-modal-content",[t.createImgSettings(),...t.createButtons()]);t.element?(t.element.firstChild&&t.element.removeChild(t.element.firstChild),t.element.appendChild(i)):t.element=N("div.comfy-modal",{parent:document.body},[i]),t.element.children[0].children.length<=1&&t.element.children[0].appendChild(N("p",{},["Unable to find the features to edit content of a format stored in the current Clipspace."])),B.invalidatePreview()}}constructor(){super()}createButtons(){const t=[];for(let i in B.items){const n=B.items[i];(!n.contextPredicate||n.contextPredicate())&&t.push(B.items[i])}return t.push(N("button",{type:"button",textContent:"Close",onclick:u(()=>{this.close()},"onclick")})),t}createImgSettings(){if(S.clipspace?.imgs){const t=[],i=S.clipspace.imgs;for(let r=0;r<i.length;r++)t.push(N("option",{value:r},[`${r}`]));const n=N("select",{id:"clipspace_img_selector",onchange:u(r=>{r.target&&S.clipspace&&(S.clipspace.selectedIndex=r.target.selectedIndex,B.invalidatePreview())},"onchange")},t),o=N("tr",{},[N("td",{},[N("font",{color:"white"},["Select Image"])]),N("td",{},[n])]),s=N("select",{id:"clipspace_img_paste_mode",onchange:u(r=>{r.target&&S.clipspace&&(S.clipspace.img_paste_mode=r.target.value)},"onchange")},[N("option",{value:"selected"},"selected"),N("option",{value:"all"},"all")]);return s.value=S.clipspace.img_paste_mode,N("table",{},[o,N("tr",{},[N("td",{},[N("font",{color:"white"},["Paste Mode"])]),N("td",{},[s])]),N("tr",{},[N("td",{align:"center",width:"100px",height:"100px",colSpan:"2"},[N("img",{id:"clipspace_preview",ondragstart:u(()=>!1,"ondragstart")},[])])])])}else return[]}createImgPreview(){return S.clipspace?.imgs?N("img",{id:"clipspace_preview",ondragstart:u(()=>!1,"ondragstart")}):[]}show(){B.invalidate(),this.element.style.display="block"}};g.registerExtension({name:"Comfy.Clipspace",init(e){e.openClipspace=function(){ee.instance||(ee.instance=new ee,S.clipspace_invalidate_handler=ee.invalidate),S.clipspace?ee.instance.show():e.ui.dialog.show("Clipspace is Empty!")}}});window.comfyAPI=window.comfyAPI||{};window.comfyAPI.clipspace=window.comfyAPI.clipspace||{};window.comfyAPI.clipspace.ClipspaceDialog=ee;g.registerExtension({name:"Comfy.ContextMenuFilter",init(){const e=k.ContextMenu;k.ContextMenu=function(t,i){const n=new e(t,i);if(i?.className==="dark"&&t?.length>4){const o=document.createElement("input");o.classList.add("comfy-context-menu-filter"),o.placeholder="Filter list",n.root.prepend(o);const s=Array.from(n.root.querySelectorAll(".litemenu-entry"));let r=[...s],a=r.length;requestAnimationFrame(()=>{const l=L.active_canvas.current_node?.widgets?.filter(w=>It(w)&&w.options.values?.length===t.length).find(w=>w.options.values?.every((p,y)=>p===t[y]))?.value;let d=l?t.findIndex(w=>w===l):0;d<0&&(d=0);let c=r[d];m();function m(){c?.style.setProperty("background-color",""),c?.style.setProperty("color",""),c=r[d],c?.style.setProperty("background-color","#ccc","important"),c?.style.setProperty("color","#000","important")}u(m,"updateSelected");const h=u(()=>{if(n.root.getBoundingClientRect().top<0){const w=1-n.root.getBoundingClientRect().height/n.root.clientHeight,p=n.root.clientHeight*w/2;n.root.style.top=-p+"px"}},"positionList");o.addEventListener("keydown",w=>{switch(w.key){case"ArrowUp":w.preventDefault(),d===0?d=a-1:d--,m();break;case"ArrowRight":w.preventDefault(),d=a-1,m();break;case"ArrowDown":w.preventDefault(),d===a-1?d=0:d++,m();break;case"ArrowLeft":w.preventDefault(),d=0,m();break;case"Enter":c?.click();break;case"Escape":n.close();break}}),o.addEventListener("input",()=>{const w=o.value.toLocaleLowerCase();if(r=s.filter(p=>{const y=!w||p.textContent?.toLocaleLowerCase().includes(w);return p.style.display=y?"block":"none",y}),d=0,r.includes(c)&&(d=r.findIndex(p=>p===c)),a=r.length,m(),i.event){let p=i.event.clientY-10;const y=document.body.getBoundingClientRect(),v=n.root.getBoundingClientRect();y.height&&p>y.height-v.height-10&&(p=Math.max(0,y.height-v.height-10)),n.root.style.top=p+"px",h()}}),requestAnimationFrame(()=>{o.focus(),h()})})}return n},k.ContextMenu.prototype=e.prototype}});function Qt(e=[]){if(!this.outputs[0].links?.length||!this.graph)return;const t=[...this.outputs[0].links.map(n=>this.graph.links[n]),...e];let i=this.widgets?.[0].value;for(const n of t){const o=this.graph?.getNodeById(n.target_id),s=o?.inputs[n.target_slot];if(!s){console.warn("Unable to resolve node or input for link",n);continue}const r=s.widget?.name;if(!r){console.warn("Invalid widget or widget name",s.widget);continue}const a=o.widgets?.find(l=>l.name===r);if(!a){console.warn(`Unable to find widget "${r}" on node [${o.id}]`);continue}a.value=i,a.callback?.(a.value,g.canvas,o,g.canvas.graph_mouse,{})}}u(Qt,"applyToGraph");function Zt(){this.applyToGraph=J(this.applyToGraph,Qt);const e=this.widgets[0],t=mt([]);e.options.values=t;const i=u(()=>{t.splice(0,t.length,...this.widgets.filter(o=>o.name.startsWith("option")&&o.value).map(o=>`${o.value}`)),!g.configuringGraph&&(t.includes(`${e.value}`)||(e.value=t[0]??"",e.callback?.(e.value)))},"updateCombo");e.callback=J(e.callback,()=>this.applyToGraph());function n(o){if(!o.widgets)return;const s=o.widgets.length-1;o.addWidget("string",`option${s}`,"",()=>{});const r=o.widgets.at(-1);if(!r)return;let a="";Object.defineProperty(r,"value",{get(){return a},set(l){if(a=l,i(),!o.widgets)return;const d=o.widgets.at(-1);if(d===this){l&&n(o);return}l||o.widgets.at(-2)!==this||d?.value||(o.widgets.pop(),o.computeSize(o.size),this.callback(l))}})}u(n,"addOption"),n(this)}u(Zt,"onNodeCreated");g.registerExtension({name:"Comfy.CustomCombo",beforeRegisterNodeDef(e,t){t?.name==="CustomCombo"&&(e.prototype.onNodeCreated=J(e.prototype.onNodeCreated,Zt))}});K().registerExtension({name:"Comfy.DynamicPrompts",nodeCreated(e){if(e.widgets){const t=e.widgets.filter(i=>i.dynamicPrompts);for(const i of t)i.serializeValue=(n,o)=>{if(typeof i.value!="string")return i.value;const s=Mt(i.value);return n?.widgets_values&&(n.widgets_values[o]=s),s}}}});g.registerExtension({name:"Comfy.EditAttention",init(){const e=g.ui.settings.addSetting({id:"Comfy.EditAttention.Delta",category:["Comfy","EditTokenWeight","Delta"],name:"Ctrl+up/down precision",type:"slider",attrs:{min:.01,max:.5,step:.01},defaultValue:.05});function t(s,r){const a=parseFloat(s);if(isNaN(a))return s;const l=a+r;return String(Number(l.toFixed(10)))}u(t,"incrementWeight");function i(s,r){let a=r,l=r,d=0,c=0;for(;a>=0&&(a--,!(s[a]==="("&&d===c));)s[a]==="("&&d++,s[a]===")"&&c++;if(a<0)return null;for(d=0,c=0;l<s.length&&!(s[l]===")"&&d===c);)s[l]==="("&&d++,s[l]===")"&&c++,l++;return l===s.length?null:{start:a+1,end:l}}u(i,"findNearestEnclosure");function n(s){const r=s.match(/^\((.*)\)$/),a=s.match(/:([+-]?(\d*\.)?\d+([eE][+-]?\d+)?)/);return r&&!a?`(${r[1]}:1.0)`:s}u(n,"addWeightToParentheses");function o(s){const r=s.composedPath()[0],a=parseFloat(e.value);if(r.tagName!=="TEXTAREA"||!(s.key==="ArrowUp"||s.key==="ArrowDown")||!s.ctrlKey&&!s.metaKey)return;s.preventDefault();let l=r.selectionStart,d=r.selectionEnd,c=r.value.substring(l,d);if(!c){const w=i(r.value,l);if(w)l=w.start,d=w.end,c=r.value.substring(l,d);else{const p=" .,\\/!?%^*;:{}=-_`~()\r\n ";for(;!p.includes(r.value[l-1])&&l>0;)l--;for(;!p.includes(r.value[d])&&d<r.value.length;)d++;if(c=r.value.substring(l,d),!c)return}}c[c.length-1]===" "&&(c=c.substring(0,c.length-1),d-=1),r.value[l-1]==="("&&r.value[d]===")"&&(l-=1,d+=1,c=r.value.substring(l,d)),(c[0]!=="("||c[c.length-1]!==")")&&(c=`(${c})`),c=n(c);const m=s.key==="ArrowUp"?a:-a,h=c.replace(/\((.*):([+-]?\d+(?:\.\d+)?)\)/,(w,p,y)=>(y=t(y,m),y==1?p:`(${p}:${y})`));r.setSelectionRange(l,d),document.execCommand("insertText",!1,h),r.setSelectionRange(l,l+h.length)}u(o,"editAttention"),window.addEventListener("keydown",o)}});var $e=ht(yt(),1);const eo={settingId:"Comfy-Desktop.UV.PythonInstallMirror",mirror:"https://github.com/astral-sh/python-build-standalone/releases/download",fallbackMirror:"https://python-standalone.org/mirror/astral-sh/python-build-standalone",validationPathSuffix:"/20250115/cpython-3.10.16+20250115-aarch64-apple-darwin-debug-full.tar.zst.sha256"},Ce=u(async e=>St(e)&&await ot().NetWork.canAccessUrl(e),"checkMirrorReachable");(async()=>{if(!vt())return;const e=ot(),t=await e.getElectronVersion(),i=Xt(),n=M(),{staticUrls:o,buildDocsUrl:s}=Tt(),r=u((a,l)=>{l!==void 0&&a!==l&&e.restartApp("Restart ComfyUI to apply changes.",1500)},"onChangeRestartApp");g.registerExtension({name:"Comfy.ElectronAdapter",settings:[{id:"Comfy-Desktop.AutoUpdate",category:["Comfy-Desktop","General","AutoUpdate"],name:"Automatically check for updates",type:"boolean",defaultValue:!0,onChange:r},{id:"Comfy-Desktop.SendStatistics",category:["Comfy-Desktop","General","Send Statistics"],name:"Send anonymous usage metrics",type:"boolean",defaultValue:!0,onChange:r},{id:"Comfy-Desktop.WindowStyle",category:["Comfy-Desktop","General","Window Style"],name:"Window Style",tooltip:"Custom: Replace the system title bar with ComfyUI's Top menu",type:"combo",experimental:!0,defaultValue:"default",options:["default","custom"],onChange:u((a,l)=>{l&&e.Config.setWindowStyle(a)},"onChange")},{id:"Comfy-Desktop.UV.PythonInstallMirror",name:"Python Install Mirror",tooltip:"Managed Python installations are downloaded from the Astral python-build-standalone project. This variable can be set to a mirror URL to use a different source for Python installations. The provided URL will replace https://github.com/astral-sh/python-build-standalone/releases/download in, e.g., https://github.com/astral-sh/python-build-standalone/releases/download/20240713/cpython-3.12.4%2B20240713-aarch64-apple-darwin-install_only.tar.gz. Distributions can be read from a local directory by using the file:// URL scheme.",type:"url",defaultValue:"",attrs:{validateUrlFn(a){return Ce(a+eo.validationPathSuffix)}}},{id:"Comfy-Desktop.UV.PypiInstallMirror",name:"Pypi Install Mirror",tooltip:"Default pip install mirror",type:"url",defaultValue:"",attrs:{validateUrlFn:Ce}},{id:"Comfy-Desktop.UV.TorchInstallMirror",name:"Torch Install Mirror",tooltip:"Pip install mirror for pytorch",type:"url",defaultValue:"",attrs:{validateUrlFn:Ce}}],commands:[{id:"Comfy-Desktop.Folders.OpenLogsFolder",label:"Open Logs Folder",icon:"pi pi-folder-open",function(){e.openLogsFolder()}},{id:"Comfy-Desktop.Folders.OpenModelsFolder",label:"Open Models Folder",icon:"pi pi-folder-open",function(){e.openModelsFolder()}},{id:"Comfy-Desktop.Folders.OpenOutputsFolder",label:"Open Outputs Folder",icon:"pi pi-folder-open",function(){e.openOutputsFolder()}},{id:"Comfy-Desktop.Folders.OpenInputsFolder",label:"Open Inputs Folder",icon:"pi pi-folder-open",function(){e.openInputsFolder()}},{id:"Comfy-Desktop.Folders.OpenCustomNodesFolder",label:"Open Custom Nodes Folder",icon:"pi pi-folder-open",function(){e.openCustomNodesFolder()}},{id:"Comfy-Desktop.Folders.OpenModelConfig",label:"Open extra_model_paths.yaml",icon:"pi pi-file",function(){e.openModelConfig()}},{id:"Comfy-Desktop.OpenDevTools",label:"Open DevTools",icon:"pi pi-code",function(){e.openDevTools()}},{id:"Comfy-Desktop.OpenUserGuide",label:"Desktop User Guide",icon:"pi pi-book",function(){window.open(s("/installation/desktop",{includeLocale:!0,platform:!0}),"_blank")}},{id:"Comfy-Desktop.CheckForUpdates",label:"Check for Updates",icon:"pi pi-sync",async function(){try{const a=await e.checkForUpdates({disableUpdateReadyAction:!0});if(!a.isUpdateAvailable){n.add({severity:"info",summary:_("desktopUpdate.noUpdateFound"),life:5e3});return}if(await re().confirm({title:_("desktopUpdate.updateFoundTitle",{version:a.version}),message:_("desktopUpdate.updateAvailableMessage"),type:"default"}))try{e.restartAndInstall()}catch(l){$e.default.error("Error installing update:",l),n.add({severity:"error",summary:_("g.error"),detail:_("desktopUpdate.errorInstallingUpdate"),life:1e4})}}catch(a){$e.default.error("Error checking for updates:",a),n.add({severity:"error",summary:_("g.error"),detail:_("desktopUpdate.errorCheckingUpdate"),life:1e4})}}},{id:"Comfy-Desktop.Reinstall",label:"Reinstall",icon:"pi pi-refresh",async function(){await re().confirm({message:_("desktopMenu.confirmReinstall"),title:_("desktopMenu.reinstall"),type:"reinstall"})&&e.reinstall()}},{id:"Comfy-Desktop.Restart",label:"Restart",icon:"pi pi-refresh",function(){e.restartApp()}},{id:"Comfy-Desktop.Quit",label:"Quit",icon:"pi pi-sign-out",async function(){i.modifiedWorkflows.length>0&&!await re().confirm({message:_("desktopMenu.confirmQuit"),title:_("desktopMenu.quit"),type:"default"})||e.quit()}}],menuCommands:[{path:["Help"],commands:["Comfy-Desktop.OpenUserGuide"]},{path:["Help"],commands:["Comfy-Desktop.OpenDevTools"]},{path:["Help","Open Folder"],commands:["Comfy-Desktop.Folders.OpenLogsFolder","Comfy-Desktop.Folders.OpenModelsFolder","Comfy-Desktop.Folders.OpenOutputsFolder","Comfy-Desktop.Folders.OpenInputsFolder","Comfy-Desktop.Folders.OpenCustomNodesFolder","Comfy-Desktop.Folders.OpenModelConfig"]},{path:["Help"],commands:["Comfy-Desktop.CheckForUpdates","Comfy-Desktop.Reinstall"]}],keybindings:[{commandId:"Workspace.CloseWorkflow",combo:{key:"w",ctrl:!0}}],aboutPageBadges:[{label:"ComfyUI_desktop v"+t,url:o.githubElectron,icon:"pi pi-github"}]})})();var to=class extends Dt{static{u(this,"ExecutableGroupNodeChildDTO")}groupNodeHandler;constructor(e,t,i,n,o){super(e,t,i,n),this.groupNodeHandler=o}resolveInput(e){if(this.id.split(":").length>2)throw new Error("Group nodes inside subgraphs are not supported. Please convert the group node to a subgraph instead.");const t=this.node.getInputNode(e);if(!t)return;const i=this.node.getInputLink(e);if(!i)throw new Error("Failed to get input link");const n=String(t.id);let o=this.nodesByExecutionId?.get(n);if(!o){const s=n.split(":").at(-1);s!==void 0&&(o=this.nodesByExecutionId?.get(s))}if(!o)throw new Error(`Failed to get input node ${n} for group node child ${this.id} with slot ${e}`);return{node:o,origin_id:n,origin_slot:i.origin_slot}}},ke=Symbol();function dt(e,t){if(typeof e=="object"&&typeof t=="object")for(const i in t){const n=t[i];if(typeof n=="object"){let o=e[i];o||(o=e[i]={}),dt(o,t[i])}else e[i]=n}return e}u(dt,"merge");var ct=class extends $t{static{u(this,"ManageGroupDialog")}tabs;selectedNodeIndex;selectedTab="Inputs";selectedGroup;modifications={};nodeItems;app;groupNodeType;groupNodeDef;groupData;innerNodesList;widgetsPage;inputsPage;outputsPage;draggable;get selectedNodeInnerIndex(){return+this.nodeItems[this.selectedNodeIndex].dataset.nodeindex}constructor(e){super(),this.app=e,this.element=N("dialog.comfy-group-manage",{parent:document.body})}changeTab(e){this.tabs[this.selectedTab].tab.classList.remove("active"),this.tabs[this.selectedTab].page.classList.remove("active"),this.tabs[e].tab.classList.add("active"),this.tabs[e].page.classList.add("active"),this.selectedTab=e}changeNode(e,t){!t&&this.selectedNodeIndex===e||(this.selectedNodeIndex!=null&&this.nodeItems[this.selectedNodeIndex].classList.remove("selected"),this.nodeItems[e].classList.add("selected"),this.selectedNodeIndex=e,!this.buildInputsPage()&&this.selectedTab==="Inputs"&&this.changeTab("Widgets"),!this.buildWidgetsPage()&&this.selectedTab==="Widgets"&&this.changeTab("Outputs"),!this.buildOutputsPage()&&this.selectedTab==="Outputs"&&this.changeTab("Inputs"),this.changeTab(this.selectedTab))}getGroupData(){this.groupNodeType=k.registered_node_types[`${G}>`+this.selectedGroup],this.groupNodeDef=this.groupNodeType.nodeData,this.groupData=R.getGroupData(this.groupNodeType)}changeGroup(e,t=!0){this.selectedGroup=e,this.getGroupData();const i=this.groupData.nodeData.nodes;if(this.nodeItems=i.map((o,s)=>N("li.draggable-item",{dataset:{nodeindex:o.index+""},onclick:u(()=>{this.changeNode(s)},"onclick")},[N("span.drag-handle"),N("div",{textContent:o.title??o.type},o.title?N("span",{textContent:o.type}):[])])),this.innerNodesList.replaceChildren(...this.nodeItems),t)this.selectedNodeIndex=null,this.changeNode(0);else{let o=this.draggable.getAllItems().findIndex(s=>s.classList.contains("selected"));o===-1&&(o=this.selectedNodeIndex),this.changeNode(o,!0)}const n=[...i];this.draggable?.dispose(),this.draggable=new Rt(this.innerNodesList,"li"),this.draggable.addEventListener("dragend",({detail:{oldPosition:o,newPosition:s}})=>{if(o!==s){n.splice(s,0,n.splice(o,1)[0]);for(let r=0;r<n.length;r++)this.storeModification({nodeIndex:n[r].index,section:ke,prop:"order",value:r})}})}storeModification(e){const{nodeIndex:t,section:i,prop:n,value:o}=e,s=this.modifications[this.selectedGroup]??={},r=s.nodes??={},a=r[t??this.selectedNodeInnerIndex]??={},l=a[i]??={};if(typeof o=="object"){const d=l[n]??={};Object.assign(d,o)}else l[n]=o}getEditElement(e,t,i,n,o,s=!0){i===n&&(i="");const r=this.modifications[this.selectedGroup]?.nodes?.[this.selectedNodeInnerIndex]?.[e]?.[t];return r&&(r.name!=null&&(i=r.name),r.visible!=null&&(o=r.visible)),N("div",[N("input",{value:i,placeholder:n,type:"text",onchange:u(a=>{this.storeModification({section:e,prop:t,value:{name:a.target.value}})},"onchange")}),N("label",{textContent:"Visible"},[N("input",{type:"checkbox",checked:o,disabled:!s,onchange:u(a=>{this.storeModification({section:e,prop:t,value:{visible:!!a.target.checked}})},"onchange")})])])}buildWidgetsPage(){const e=this.groupData.oldToNewWidgetMap[this.selectedNodeInnerIndex],t=Object.keys(e??{}),i=g.rootGraph.extra.groupNodes[this.selectedGroup].config?.[this.selectedNodeInnerIndex]?.input;return this.widgetsPage.replaceChildren(...t.map(n=>this.getEditElement("input",n,e[n],n,i?.[n]?.visible!==!1))),!!t.length}buildInputsPage(){const e=this.groupData.nodeInputs[this.selectedNodeInnerIndex],t=Object.keys(e??{}),i=g.rootGraph.extra.groupNodes[this.selectedGroup].config?.[this.selectedNodeInnerIndex]?.input;return this.inputsPage.replaceChildren(...t.map(n=>{let o=e[n];if(o)return this.getEditElement("input",n,o,n,i?.[n]?.visible!==!1)}).filter(Boolean)),!!t.length}buildOutputsPage(){const e=this.groupData.nodeData.nodes,t=this.groupData.getNodeDef(e[this.selectedNodeInnerIndex]),i=t?.output??[],n=this.groupData.oldToNewOutputMap[this.selectedNodeInnerIndex],o=g.rootGraph.extra.groupNodes[this.selectedGroup].config?.[this.selectedNodeInnerIndex]?.output,s=this.groupData.nodeData.nodes[this.selectedNodeInnerIndex].type!=="PrimitiveNode";return this.outputsPage.replaceChildren(...i.map((r,a)=>{const l=n?.[a],d=t.output_name?.[a]??r;let c=o?.[a]?.name;const m=o?.[a]?.visible||l!=null;return(!c||c===d)&&(c=""),this.getEditElement("output",a,c,d,m,s)}).filter(Boolean)),!!i.length}show(e){const t=Object.keys(g.rootGraph.extra?.groupNodes??{}).sort((o,s)=>o.localeCompare(s));this.innerNodesList=N("ul.comfy-group-manage-list-items"),this.widgetsPage=N("section.comfy-group-manage-node-page"),this.inputsPage=N("section.comfy-group-manage-node-page"),this.outputsPage=N("section.comfy-group-manage-node-page");const i=N("div",[this.widgetsPage,this.inputsPage,this.outputsPage]);this.tabs=[["Inputs",this.inputsPage],["Widgets",this.widgetsPage],["Outputs",this.outputsPage]].reduce((o,[s,r])=>(o[s]={tab:N("a",{onclick:u(()=>{this.changeTab(s)},"onclick"),textContent:s}),page:r},o),{});const n=N("div.comfy-group-manage-outer",[N("header",[N("h2","Group Nodes"),N("select",{onchange:u(o=>{this.changeGroup(o.target.value)},"onchange")},t.map(o=>N("option",{textContent:o,selected:`${G}>${o}`===e,value:o})))]),N("main",[N("section.comfy-group-manage-list",this.innerNodesList),N("section.comfy-group-manage-node",[N("header",Object.values(this.tabs).map(o=>o.tab)),i])]),N("footer",[N("button.comfy-btn",{onclick:u(()=>{if(g.rootGraph.nodes.find(o=>o.type==="workflow>"+this.selectedGroup)){M().addAlert("This group node is in use in the current workflow, please first remove these.");return}confirm(`Are you sure you want to remove the node: "${this.selectedGroup}"`)&&(delete g.rootGraph.extra.groupNodes[this.selectedGroup],k.unregisterNodeType(`${G}>`+this.selectedGroup)),this.show()},"onclick")},"Delete Group Node"),N("button.comfy-btn",{onclick:u(async()=>{let o,s=[];const r={};for(const a in this.modifications){const l=g.rootGraph.extra.groupNodes[a];let d=l.config??={},c=this.modifications[a]?.nodes;if(c){const h=Object.keys(c);if(c[h[0]][ke]){const w=[],p={},y={};for(const v of h){const f=c[v][ke].order;w[f]=l.nodes[+v],p[f]=c[v],w[f].index=f}for(const v of l.links)v[0]!=null&&(v[0]=l.nodes[v[0]].index),v[2]!=null&&(v[2]=l.nodes[v[2]].index);if(l.external)for(const v of l.external)v[0]!=null&&(v[0]=l.nodes[v[0]].index);for(const v of h)d[v]&&(y[l.nodes[v].index]=d[v]),delete d[v];l.nodes=w,c=p,l.config=d=y}dt(d,c)}r[a]=l,o||(o=g.rootGraph.nodes.reduce((h,w)=>(h[w.type]??=[],h[w.type].push(w),h),{}));const m=o[`${G}>`+a];m&&s.push(...m)}await ie.registerFromWorkflow(r,[]);for(const a of s)a.recreate();this.modifications={},this.app.canvas.setDirty(!0,!0),this.changeGroup(this.selectedGroup,!1)},"onclick")},"Save"),N("button.comfy-btn",{onclick:u(()=>this.element.close(),"onclick")},"Close")])]);this.element.replaceChildren(n),this.changeGroup(e?t.find(o=>`workflow>${o}`===e)??t[0]:t[0]),this.element.showModal(),this.element.addEventListener("close",()=>{this.draggable?.dispose(),this.element.remove()})}};window.comfyAPI=window.comfyAPI||{};window.comfyAPI.groupNodeManage=window.comfyAPI.groupNodeManage||{};window.comfyAPI.groupNodeManage.ManageGroupDialog=ct;var oo=new Set(["default","forceInput","defaultInput","control_after_generate","multiline","tooltip","dynamicPrompts"]),ze=u(e=>({min:e.min??-1/0,max:e.max??1/0}),"getRange"),no=u((e,t)=>{const i=e[0],n=e[1]??{},o=t[1]??{},s=ze(n),r=ze(o);if(s.min>r.max||s.max<r.min)return null;const a=n.step??1,l=o.step??1,d={min:Math.max(s.min,r.min),max:Math.min(s.max,r.max),step:Vt(a,l)};return Pe([i,{...n,...d}],[i,{...o,...d}])},"mergeNumericInputSpec"),io=u((e,t)=>{const i=e[1]??{},n=t[1]??{},o=Ve(e),s=Ve(t),r=q.intersection(o,s);return r.length===0?null:Pe(["COMBO",{...i,options:r}],["COMBO",{...n,options:r}])},"mergeComboInputSpec"),Pe=u((e,t)=>{const i=xe(e),n=e[1]??{},o=t[1]??{};return q.union(q.keys(n),q.keys(o)).filter(s=>!oo.has(s)).every(s=>{const r=n[s],a=o[s];return r===a||q.isNil(r)&&q.isNil(a)})?[i,{...n,...o}]:null},"mergeCommonInputSpec");const so=u((e,t)=>xe(e)!==xe(t)?null:Bt(e)||Kt(e)?no(e,t):Ut(e)?io(e,t):Pe(e,t),"mergeInputSpec"),ro=u(e=>e.type==="PrimitiveNode","isPrimitiveNode");var De="Run widget replace on values",Te=class extends he{static{u(this,"PrimitiveNode")}controlValues;lastType;static category;constructor(e){super(e),this.addOutput("connect to widget input","*"),this.serialize_widgets=!0,this.isVirtualNode=!0,(!this.properties||!(De in this.properties))&&this.addProperty(De,!1,"boolean")}applyToGraph(e=[]){if(!this.outputs[0].links?.length||!this.graph)return;const t=[...this.outputs[0].links.map(n=>this.graph.links[n]),...e];let i=this.widgets?.[0].value;i&&this.properties[De]&&(i=rt(this.graph,i));for(const n of t){const o=this.graph?.getNodeById(n.target_id),s=o?.inputs[n.target_slot];if(!s){console.warn("Unable to resolve node or input for link",n);continue}const r=s.widget?.name;if(!r){console.warn("Invalid widget or widget name",s.widget);continue}const a=o.widgets?.find(l=>l.name===r);if(!a){console.warn(`Unable to find widget "${r}" on node [${o.id}]`);continue}a.value=i,a.callback?.(a.value,g.canvas,o,g.canvas.graph_mouse,{})}}refreshComboInNode(){const e=this.widgets?.[0];e?.type==="combo"&&(e.options.values=this.outputs[0].widget[P]()[0],e.options.values.includes(e.value)||(e.value=e.options.values[0],e.callback(e.value)))}onAfterGraphConfigured(){if(this.outputs[0].links?.length&&!this.widgets?.length){if(this.#e(),this.widgets&&this.widgets_values)for(let e=0;e<this.widgets_values.length;e++){const t=this.widgets[e];t&&(t.value=this.widgets_values[e])}this.#t()}}onConnectionsChange(e,t,i){if(g.configuringGraph)return;const n=this.outputs[0].links;i?n?.length&&!this.widgets?.length&&this.#e():(this.#t(),n?.length||this.onLastDisconnect())}onConnectOutput(e,t,i,n,o){if(!i.widget&&!(i.type in $))return!1;if(this.outputs[e].links?.length){const s=this.#o(i);return s&&this.applyToGraph([{target_id:n.id,target_slot:o}]),s}return!0}#e(e){if(!this.outputs[0].links||!this.graph){this.onLastDisconnect();return}const t=this.outputs[0].links[0],i=this.graph.links[t];if(!i)return;const n=this.graph.getNodeById(i.target_id);if(!n||!n.inputs)return;const o=n.inputs[i.target_slot];if(!o)return;let s;if(o.widget)s=o.widget;else{if(!(o.type in $))return;s={name:o.name,[P]:()=>[o.type,{}]}}const r=s[P]?.();if(!r)return;const{type:a}=lo(r);this.outputs[0].type=a,this.outputs[0].name=a,this.outputs[0].widget=s,this.#i(s[ae]??r,n,s.name,e)}#i(e,t,i,n){let o=e[0];o instanceof Array&&(o="COMBO");const[s,r]=this.size;let a;if(Wt(o)?a=($[o](this,"value",e,g)||{}).widget:a=this.addWidget(o,"value",null,()=>{},{}),t?.widgets&&a){const d=t.widgets.find(c=>c.name===i);d&&(a.value=d.value)}if(!e?.[1]?.control_after_generate&&(a.type==="number"||a.type==="combo")){let d=this.widgets_values?.[1];d||(d="fixed"),At(this,a,d,void 0,e),this.widgets?.[1]&&(a.linkedWidgets=[this.widgets[1]]);let c=this.widgets_values?.[2];c&&this.widgets&&this.widgets.length===3&&(this.widgets[2].value=c)}const l=this.controlValues;if(this.widgets&&this.lastType===this.widgets[0]?.type&&l?.length===this.widgets.length-1)for(let d=0;d<l.length;d++)this.widgets[d+1].value=l[d];if(a.callback=J(a.callback,()=>{this.applyToGraph()}),this.setSize([Math.max(this.size[0],s),Math.max(this.size[1],r)]),!n){const d=this.computeSize();this.size[0]<d[0]&&(this.size[0]=d[0]),this.size[1]<d[1]&&(this.size[1]=d[1]),requestAnimationFrame(()=>{this.onResize?.(this.size)})}}recreateWidget(){const e=this.widgets?.map(t=>t.value);if(this.#n(),this.#e(!0),e?.length&&this.widgets)for(let t=0;t<this.widgets.length;t++)this.widgets[t].value=e[t];return this.widgets?.[0]}#t(){const e=this.outputs[0],t=e.links??[],i=!!e.widget?.[ae];if(i&&delete e.widget?.[ae],t?.length<2&&i){t.length&&this.recreateWidget();return}const n=e.widget?.[P]?.();if(n&&!(!(n[0]==="INT"||n[0]==="FLOAT")||!this.graph))for(const o of t){const s=this.graph.links[o];if(!s)continue;const r=this.graph.getNodeById(s.target_id);if(!r)continue;const a=r.inputs[s.target_slot];this.#o(a,i)}}#o(e,t){const i=this.outputs?.[0],n=e.widget?.[P]?.();return n?!!pe.call(this,i,n,t,this.recreateWidget):!1}#n(){if(this.widgets){for(const e of this.widgets)e.onRemove&&e.onRemove();this.controlValues=[],this.lastType=this.widgets[0]?.type;for(let e=1;e<this.widgets.length;e++)this.controlValues.push(this.widgets[e].value);setTimeout(()=>{delete this.lastType,delete this.controlValues},15),this.widgets.length=0}}onLastDisconnect(){this.outputs[0].type="*",this.outputs[0].name="connect to widget input",delete this.outputs[0].widget,this.#n()}};function Ge(e){return e.widget?.[ae]??e.widget?.[P]?.()??["*",{}]}u(Ge,"getWidgetConfig");function je(e){const{nodeData:t}=this.constructor;return t?.input?.required?.[e]??t?.input?.optional?.[e]}u(je,"getConfig");function ao(e,t){return console.warn("Please remove call to convertToInput. Widget to socket conversion is no longer necessary, as they co-exist now."),e.inputs.find(i=>i.widget?.name===t.name)}u(ao,"convertToInput");function lo(e){let t=e[0];return t instanceof Array&&(t="COMBO"),{type:t}}u(lo,"getWidgetType");function Se(e,t){if(!e.widget||(t?e.widget[P]=()=>t:delete e.widget,!(e instanceof Nt)))return;const i=e.node.graph;if(!i)return;const n=i.links[e.link??-1];if(!n)return;const o=i.getNodeById(n.origin_id);!o||!ro(o)||(t?o.recreateWidget():g.configuringGraph||(o.disconnectOutput(0),o.onLastDisconnect()))}u(Se,"setWidgetConfig");function pe(e,t,i,n,o){o||(o=Ge(e));const s=so(o,t);if(s||i){s&&(e.widget[ae]=s);const r=n?.call(this);if(r){const a=r.options.min,l=r.options.max;a!=null&&r.value<a&&(r.value=a),l!=null&&r.value>l&&(r.value=l),r.callback(r.value)}}return{customConfig:s?.[1]??{}}}u(pe,"mergeIfValid");g.registerExtension({name:"Comfy.WidgetInputs",async beforeRegisterNodeDef(e,t,i){e.prototype.convertWidgetToInput=function(){return console.warn("Please remove call to convertWidgetToInput. Widget to socket conversion is no longer necessary, as they co-exist now."),!1},e.prototype.onGraphConfigured=J(e.prototype.onGraphConfigured,function(){if(this.inputs){this.widgets??=[];for(const o of this.inputs)if(o.widget){const s=o.widget.name;o.widget[P]||(o.widget[P]=()=>je.call(this,s)),this.widgets?.find(r=>r.name===s)||this.removeInput(this.inputs.findIndex(r=>r===o))}}}),e.prototype.onConfigure=J(e.prototype.onConfigure,function(){if(!i.configuringGraph&&this.inputs){for(const o of this.inputs)if(o.widget&&!o.widget[P]){const s=o.widget.name;o.widget[P]=()=>je.call(this,s)}}});const n=e.prototype.onInputDblClick;e.prototype.onInputDblClick=function(...[o,...s]){const r=n?.apply(this,[o,...s]),a=this.inputs[o];if(!a.widget&&!(a.type in $)&&!(a.widget?.[P]?.()?.[0]instanceof Array))return r;const l=k.createNode("PrimitiveNode"),d=i.canvas.graph;if(!l||!d)return r;d?.add(l);const c=[this.pos[0]-l.size[0]-30,this.pos[1]];for(;d.getNodeOnPos(c[0],c[1],d.nodes);)c[1]+=k.NODE_TITLE_HEIGHT;return l.pos=c,l.connect(0,this,o),l.title=a.name,r}},registerCustomNodes(){k.registerNodeType("PrimitiveNode",Object.assign(Te,{title:"Primitive"})),Te.category="utils"}});window.comfyAPI=window.comfyAPI||{};window.comfyAPI.widgetInputs=window.comfyAPI.widgetInputs||{};window.comfyAPI.widgetInputs.PrimitiveNode=Te;window.comfyAPI.widgetInputs.getWidgetConfig=Ge;window.comfyAPI.widgetInputs.convertToInput=ao;window.comfyAPI.widgetInputs.setWidgetConfig=Se;window.comfyAPI.widgetInputs.mergeIfValid=pe;var Y={InUse:{Free:0,Registered:1,InWorkflow:2},isInUseGroupNode(e){const t=`${G}>${e}`;return g.rootGraph.extra?.groupNodes?.[e]?g.rootGraph.nodes.find(i=>i.type===t)?Y.InUse.InWorkflow:Y.InUse.Registered:Y.InUse.Free},storeGroupNode(e,t){let i=g.rootGraph.extra;i||(g.rootGraph.extra=i={});let n=i.groupNodes;n||(i.groupNodes=n={}),n[e]=t}},He=class{static{u(this,"GroupNodeBuilder")}nodes;nodeData;constructor(e){this.nodes=e}async build(){const e=await this.getName();if(e)return this.sortNodes(),this.nodeData=this.getNodeData(),Y.storeGroupNode(e,this.nodeData),{name:e,nodeData:this.nodeData}}async getName(){const e=await re().prompt({title:_("groupNode.create"),message:_("groupNode.enterName"),defaultValue:""});if(e){switch(Y.isInUseGroupNode(e)){case Y.InUse.InWorkflow:M().addAlert("An in use group node with this name already exists embedded in this workflow, please remove any instances or use a new name.");return;case Y.InUse.Registered:if(!confirm("A group node with this name already exists embedded in this workflow, are you sure you want to overwrite it?"))return;break}return e}}sortNodes(){const e=g.rootGraph.computeExecutionOrder(!1);this.nodes=this.nodes.map(t=>({index:e.indexOf(t),node:t})).sort((t,i)=>t.index-i.index||String(t.node.id).localeCompare(String(i.node.id))).map(({node:t})=>t)}getNodeData(){const e=u(s=>{for(const r of s.links){const a=g.rootGraph.getNodeById(r[4])?.outputs?.[Number(r[1])]?.type;a!==void 0&&r.push(a)}},"storeLinkTypes"),t=u(s=>{s.external=[];for(let r=0;r<this.nodes.length;r++){const a=this.nodes[r];if(a.outputs?.length)for(let l=0;l<a.outputs.length;l++){let d=!1;const c=a.outputs[l];let m=c.type;if(c.links?.length){for(const h of c.links){const w=g.rootGraph.links[h];if(w&&(m==="*"&&(m=w.type),!g.canvas.selected_nodes[w.target_id])){d=!0;break}}d&&s.external.push([r,l,String(m)])}}}},"storeExternalLinks"),i=g.canvas?.graph;if(!i)return{nodes:[],links:[],external:[]};const n=Et(this.nodes,i),o=JSON.parse(n);return o.external=[],e(o),t(o),o}},ie=class ut{static{u(this,"GroupNodeConfig")}name;nodeData;inputCount;oldToNewOutputMap;newToOldOutputMap;oldToNewInputMap;oldToNewWidgetMap;newToOldWidgetMap;primitiveDefs;widgetToPrimitive;primitiveToWidget;nodeInputs;outputVisibility;nodeDef;inputs;linksFrom;linksTo;externalFrom;constructor(t,i){this.name=t,this.nodeData=i,this.getLinks(),this.inputCount=0,this.oldToNewOutputMap={},this.newToOldOutputMap={},this.oldToNewInputMap={},this.oldToNewWidgetMap={},this.newToOldWidgetMap={},this.primitiveDefs={},this.widgetToPrimitive={},this.primitiveToWidget={},this.nodeInputs={},this.outputVisibility=[]}async registerType(t=G){this.nodeDef={output:[],output_name:[],output_is_list:[],output_node:!1,name:t+">"+this.name,display_name:this.name,category:"group nodes"+(">"+t),input:{required:{}},description:`Group node combining ${this.nodeData.nodes.map(o=>o.type).join(", ")}`,python_module:"custom_nodes."+this.name,[V]:this},this.inputs=[];const i={},n={};for(let o=0;o<this.nodeData.nodes.length;o++){const s=this.nodeData.nodes[o];s.index=o,this.processNode(s,i,n)}for(const o of this.#e)o();this.#e=[],this.nodeDef&&(await g.registerNodeDef(`${G}>`+this.name,this.nodeDef),Yt().addNodeDef(this.nodeDef))}getLinks(){this.linksFrom={},this.linksTo={},this.externalFrom={};for(const t of this.nodeData.links){const[i,n,o,s]=t;if(i==null||n==null||o==null||s==null)continue;const r=Number(i),a=Number(n),l=Number(o),d=Number(s);this.linksFrom[r]||(this.linksFrom[r]={}),this.linksFrom[r][a]||(this.linksFrom[r][a]=[]),this.linksFrom[r][a].push(t),this.linksTo[l]||(this.linksTo[l]={}),this.linksTo[l][d]=t}if(this.nodeData.external)for(const t of this.nodeData.external){const i=Number(t[0]),n=Number(t[1]),o=t[2];o!=null&&(this.externalFrom[i]?this.externalFrom[i][n]=o:this.externalFrom[i]={[n]:o})}}processNode(t,i,n){const o=this.getNodeDef(t);if(!o)return;const s={...o.input?.required,...o.input?.optional};this.inputs.push(this.processNodeInputs(t,i,s)),o.output?.length&&this.processNodeOutputs(t,n,o)}getNodeDef(t){if(t.type){const o=le[t.type];if(o)return o}const i=t.index;if(i==null)return;const n=this.linksFrom[i];if(t.type==="PrimitiveNode"){if(!n)return;let o=n[0]?.[0]?.[5]??null;if(o==="COMBO"){const s=t.outputs?.[0]?.widget?.name,r=n[0]?.[0]?.[2];if(s&&r!=null){const a=this.nodeData.nodes[Number(r)]?.type;if(a){const l=le[a],d=(l?.input?.required?.[s]??l?.input?.optional?.[s])?.[0];o=typeof d=="string"||typeof d=="number"?d:null}}}return this.primitiveDefs[i]={input:{required:{value:[o,{}]}},output:[o],output_name:[],output_is_list:[]}}else if(t.type==="Reroute"){const o=this.linksTo[i];if(o&&n&&!this.externalFrom[i]?.[0])return null;let s={},r="*";if(n){const a=n[0]??[];for(const l of a){const d=l[2],c=l[3];if(d==null||c==null)continue;const m=this.nodeData.nodes[Number(d)],h=m?.inputs?.[Number(c)];if(h?.type&&r==="*"&&(r=h.type),h?.widget&&m?.type){const w=le[m.type],p=w?.input?.required?.[h.widget.name]??w?.input?.optional?.[h.widget.name];if(p){const y=[p[0],s];s=pe({widget:y},p,!1,void 0,y)?.customConfig??s}}}}else if(o){const a=o[0];if(a){const l=a[0],d=a[1];if(l!=null&&d!=null){const c=this.nodeData.nodes[Number(l)]?.outputs?.[Number(d)];c&&typeof c=="object"&&"type"in c&&(r=String(c.type??"*"))}}}else{for(const a of this.nodeData.links)if(a[2]===t.index){const l=a[5];l!=null&&(r=String(l));break}if(r==="*"){const a=this.externalFrom[i]?.[0];a&&(r=String(a))}}return s.forceInput=!0,{input:{required:{[r]:[r,s]}},output:[r],output_name:[],output_is_list:[]}}console.warn("Skipping virtual node "+t.type+" when building group node "+this.name)}getInputConfig(t,i,n,o,s){const r=this.nodeData.config?.[t.index??-1]?.input?.[i];let a=r?.name??t.inputs?.find(c=>c.name===i)?.label??i,l=a,d="";if((t.type==="PrimitiveNode"&&t.title||a in n)&&(d=`${t.title??t.type} `,l=a=`${d}${i}`,a in n&&(a=`${d}${n[a]} ${i}`)),n[l]=(n[l]??1)+1,(i==="seed"||i==="noise_seed")&&(s||(s={}),s.control_after_generate=`${d}control_after_generate`),o[0]==="IMAGEUPLOAD"){s||(s={});const c=t.index??-1,m=typeof o[1]=="object"&&o[1]!==null?o[1]:{},h="widget"in m&&typeof m.widget=="string"?m.widget:"image";s.widget=this.oldToNewWidgetMap[c]?.[h]??"image"}if(s){const c=typeof o[1]=="object"&&o[1]?o[1]:{};o=[o[0],{...c,...s}]}return{name:a,config:o,customConfig:r}}processWidgetInputs(t,i,n,o){const s=[],r=new Map,a=i.index??-1,l=this.oldToNewWidgetMap[a]={};for(const d of n){const c=t[d];if(Array.isArray(c)&&c.length>=1&&typeof c[0]=="string"&&Jt().inputIsWidget(c)){const m=i.inputs?.findIndex(h=>h.name===d&&h.widget?.name===d)??-1;if(m>-1)r.set(m,d),l[d]=null;else{const{name:h,config:w}=this.getInputConfig(i,d,o,t[d]);this.nodeDef?.input?.required&&(this.nodeDef.input.required[h]=w),l[d]=h,this.newToOldWidgetMap[h]={node:i,inputName:d}}}else s.push(d)}return{converted:r,slots:s}}checkPrimitiveConnection(t,i,n){const o=t[0];if(o!=null&&this.nodeData.nodes[Number(o)]?.type==="PrimitiveNode"){const s=Number(t[0]),r=Number(t[2]),a=this.primitiveDefs[s];if(!a)return;const l=n[i],d=a.input.required.value,c=pe({widget:d},l,!1,void 0,d),m=n[i]?.[1];d[1]=c?.customConfig??m?{...typeof m=="object"?m:{}}:{};const h=this.oldToNewWidgetMap[s]?.value;if(h){const v=h.substring(0,h.length-6);d[1].control_after_generate=!0,d[1].control_prefix=v}let w=this.widgetToPrimitive[r];w||(w=this.widgetToPrimitive[r]={});const p=w[i];Array.isArray(p)?p.push(s):typeof p=="number"?w[i]=[p,s]:w[i]=s;let y=this.primitiveToWidget[s];y||(y=this.primitiveToWidget[s]=[]),y.push({nodeId:r,inputName:i})}}processInputSlots(t,i,n,o,s,r){const a=i.index??-1;this.nodeInputs[a]={};for(let l=0;l<n.length;l++){const d=n[l];if(o[l]){this.checkPrimitiveConnection(o[l],d,t);continue}const{name:c,config:m,customConfig:h}=this.getInputConfig(i,d,r,t[d]);this.nodeInputs[a][d]=c,h?.visible!==!1&&(this.nodeDef?.input?.required&&(this.nodeDef.input.required[c]=m),s[l]=this.inputCount++)}}processConvertedWidgets(t,i,n,o,s,r,a){const l=[...o.keys()].sort().map(d=>o.get(d));for(let d=0;d<l.length;d++){const c=l[d];if(!c)continue;if(s[n.length+d]){this.checkPrimitiveConnection(s[n.length+d],c,t);continue}const{name:m,config:h}=this.getInputConfig(i,c,a,t[c],{defaultInput:!0});this.nodeDef?.input?.required&&(this.nodeDef.input.required[m]=h),this.newToOldWidgetMap[m]={node:i,inputName:c};const w=i.index??-1;this.oldToNewWidgetMap[w]||(this.oldToNewWidgetMap[w]={}),this.oldToNewWidgetMap[w][c]=m,r[n.length+d]=this.inputCount++}}#e=[];processNodeInputs(t,i,n){const o=[],s=Object.keys(n);if(!s.length)return;const{converted:r,slots:a}=this.processWidgetInputs(n,t,s,i),l=t.index??-1,d=this.linksTo[l]??{},c=this.oldToNewInputMap[l]={};return this.processInputSlots(n,t,a,d,c,i),this.#e.push(()=>this.processConvertedWidgets(n,t,a,r,d,c,i)),o}processNodeOutputs(t,i,n){const o=t.index??-1,s=this.oldToNewOutputMap[o]={},r=n.output??[];for(let a=0;a<r.length;a++){const l=this.linksFrom[o]?.[a]&&!this.externalFrom[o]?.[a],d=this.nodeData.config?.[t.index??-1]?.output?.[a],c=d?.visible??!l;if(this.outputVisibility.push(c),!c)continue;this.nodeDef?.output&&(s[a]=this.nodeDef.output.length,this.newToOldOutputMap[this.nodeDef.output.length]={node:t,slot:a},this.nodeDef.output.push(r[a]),this.nodeDef.output_is_list?.push(n.output_is_list?.[a]??!1));let m=d?.name;if(!m){const w=r[a];m=n.output_name?.[a]??(typeof w=="string"?w:void 0);const p=t.outputs?.find(y=>y.name===m);p?.label&&(m=p.label)}let h=String(m??`output_${a}`);if(h in i){const w=`${t.title??t.type} `;h=`${w}${m??a}`,h in i&&(h=`${w}${t.index} ${m??a}`)}i[h]=1,this.nodeDef?.output_name?.push(h)}}static async registerFromWorkflow(t,i){for(const n in t){const o=t[n];let s=!1;for(const r of o.nodes)(!r.type||!(r.type in k.registered_node_types))&&(i.push({type:r.type??"unknown",hint:` (In group node '${G}>${n}')`}),i.push({type:`${G}>`+n,action:{text:"Remove from workflow",callback:u(a=>{delete t[n];const l=a.target;l.textContent="Removed",l.style.pointerEvents="none",l.style.opacity="0.7"},"callback")}}),s=!0);s||await new ut(n,o).registerType()}}},R=class te{static{u(this,"GroupNodeHandler")}node;groupData;innerNodes=null;constructor(t){this.node=t,this.groupData=t.constructor?.nodeData?.[V],this.node.setInnerNodes=p=>{this.innerNodes=p;for(let y=0;y<this.innerNodes.length;y++){const v=this.innerNodes[y];v.graph??=this.node.graph;for(const f of v.widgets??[])f.type==="converted-widget"&&(f.serializeValue=f.origSerializeValue);v.index=y,v.getInputNode=f=>{const b=v.index??0,I=this.groupData.oldToNewInputMap[b]?.[f];if(I!=null)return this.node.getInputNode(I);const C=this.groupData.linksTo[b]?.[f];if(!C)return null;const D=C[0];if(D==null)return null;const x=p[Number(D)];return x.type==="PrimitiveNode"?null:x},v.getInputLink=f=>{const b=v.index??0,I=this.groupData.oldToNewInputMap[b]?.[f];if(I!=null){const x=this.node.inputs[I].link;if(x==null)return null;const T=g.rootGraph.links[x];return T?{...T,target_id:v.id,target_slot:+f}:null}const C=this.groupData.linksTo[b]?.[f];if(!C)return null;const D=C[0];return D==null?null:{origin_id:p[Number(D)].id,origin_slot:C[1],target_id:v.id,target_slot:+f}}}},this.node.updateLink=p=>{p={...p};const y=this.groupData.newToOldOutputMap[p.origin_slot];if(!y||!this.innerNodes)return null;const v=y.node.index??0;let f=this.innerNodes[v],b;for(;f?.type==="Reroute";)b=f.getInputLink(0),f=f.getInputNode(0);return f?b&&te.isGroupNode(f)&&f.updateLink?f.updateLink(b):(p.origin_id=f.id,p.origin_slot=b?.origin_slot??y.slot,p):null},this.node.getInnerNodes=(p,y=[],v=[],f=new Set)=>{if(f.has(this.node))throw new Error("RecursionError: while flattening subgraph");if(f.add(this.node),!this.innerNodes){const C=this.groupData.nodeData.nodes.map((D,x)=>{if(!D.type)return null;const T=k.createNode(D.type);return T?(T.configure(D),T.id=`${this.node.id}:${x}`,T.graph=this.node.graph,T):null}).filter(D=>D!==null);this.node.setInnerNodes?.(C)}this.updateInnerWidgets();const b=[...y,this.node.id],I=this.node.graph?.getNodeById(y.at(-1))??void 0;for(const C of this.innerNodes??[]){C.graph??=this.node.graph;const D=String(C.id);C.id=D.split(":").at(-1);const x=new to(C,b,p,I);C.id=D,x.groupNodeHandler=this,v.push(x)}return v},this.node.recreate=async()=>{const p=this.node.id,y=this.node.size,v=this.node.convertToNodes?.();if(!v)return null;const f=k.createNode(this.node.type);if(!f)return null;f.id=p,f.setInnerNodes?.(v);const b=te.getHandler(f);b?.populateWidgets(),g.rootGraph.add(f),f.setSize?.([Math.max(f.size[0],y[0]),Math.max(f.size[1],y[1])]);const I=new He(v).getNodeData();return b&&(b.groupData.nodeData.links=I.links,b.replaceNodes(v)),f},this.node.convertToNodes=()=>{const p=u(()=>{const f={...this.groupData.nodeData};f.nodes=[...f.nodes];const b=this.node.getInnerNodes?.(),I=[];for(let O=0;O<f.nodes.length;O++){let H=b?.[O]?.id;H==null||typeof H=="number"&&isNaN(H)?H=void 0:I.push(H),f.nodes[O]={...f.nodes[O],id:H}}at(JSON.stringify(f),g.canvas);const[C,D]=this.node.pos;let x,T;const z=I.length?I:Object.keys(g.canvas.selected_nodes),j=[];for(let O=0;O<z.length;O++){const H=z[O],F=g.rootGraph.getNodeById(H),ve=b?.[O];if(!F||(j.push(F),(T==null||F.pos[0]<T)&&(T=F.pos[0]),(x==null||F.pos[1]<x)&&(x=F.pos[1]),!F.widgets||!ve))continue;const be=this.groupData.oldToNewWidgetMap[ve.index??0];if(be){const gt=Object.keys(be);for(const Re of gt){const Fe=be[Re];if(!Fe)continue;const Ne=this.node.widgets?.findIndex(U=>U.name===Fe)??-1;if(Ne!==-1)if(ve.type==="PrimitiveNode")for(let U=0;U<F.widgets.length;U++){const Q=this.node.widgets?.[Ne+U];Q&&(F.widgets[U].value=Q.value)}else{const U=this.node.widgets?.[Ne],Q=F.widgets.find(X=>X.name===Re);if(!Q||!U)continue;Q.value=U.value;const Ie=U.linkedWidgets??[];for(let X=0;X<Ie.length;X++){const Ue=Q.linkedWidgets?.[X];Ue&&Ie[X]&&(Ue.value=Ie[X].value)}}}}}for(const O of j)O.pos[0]-=(T??0)-C,O.pos[1]-=(x??0)-D;return{newNodes:j,selectedIds:z}},"addInnerNodes"),y=u(f=>{for(const b in this.groupData.oldToNewInputMap){const I=f[Number(b)],C=g.rootGraph.getNodeById(I);if(!C)continue;const D=this.groupData.oldToNewInputMap[Number(b)];for(const x in D){const T=D[Number(x)];if(T==null)continue;const z=t.inputs[T];if(z.link==null)continue;const j=g.rootGraph.links[z.link];j&&g.rootGraph.getNodeById(j.origin_id)?.connect(j.origin_slot,C,+x)}}},"reconnectInputs"),v=u(f=>{for(let b=0;b<t.outputs?.length;b++){const I=t.outputs[b];if(!I.links)continue;const C=[...I.links];for(const D of C){const x=this.groupData.newToOldOutputMap[b];if(!x)continue;const T=g.rootGraph.links[D];if(!T)continue;const z=g.rootGraph.getNodeById(T.target_id),j=g.rootGraph.getNodeById(f[x.node.index??0]);z&&j?.connect(x.slot,z,T.target_slot)}}},"reconnectOutputs");g.canvas.emitBeforeChange();try{const{newNodes:f,selectedIds:b}=p();return y(b),v(b),g.rootGraph.remove(this.node),f}finally{g.canvas.emitAfterChange()}};const i=this.node.getExtraMenuOptions,n=this.node;this.node.getExtraMenuOptions=function(p,y){i?.call(this,p,y);let v=y.findIndex(f=>f?.content==="Outputs");return v===-1?v=y.length:v++,y.splice(v,0,null,{content:"Convert to nodes",callback:u(async()=>{const f=n.convertToNodes;return f?.()},"callback")},{content:"Manage Group Node",callback:u(()=>Me(this.type),"callback")}),[]};const o=this.node.onDrawTitleBox;this.node.onDrawTitleBox=function(p,y,v,f){o?.call(this,p,y,v,f);const b=p.fillStyle;p.beginPath(),p.rect(11,-y+11,2,2),p.rect(14,-y+11,2,2),p.rect(17,-y+11,2,2),p.rect(11,-y+14,2,2),p.rect(14,-y+14,2,2),p.rect(17,-y+14,2,2),p.rect(11,-y+17,2,2),p.rect(14,-y+17,2,2),p.rect(17,-y+17,2,2),p.fillStyle=this.boxcolor||k.NODE_DEFAULT_BOXCOLOR,p.fill(),p.fillStyle=b};const s=t.onDrawForeground,r=this.groupData.nodeData;t.onDrawForeground=function(p,y,v){s?.call(this,p,y,v);const f=Ht().nodeProgressStates[this.id];if(f&&f.state==="running"&&this.runningInternalNodeId!==null){const b=typeof this.runningInternalNodeId=="number"?this.runningInternalNodeId:parseInt(String(this.runningInternalNodeId),10),I=r.nodes[b];if(!I)return;const C=`Running ${I.title||I.type} (${this.runningInternalNodeId}/${r.nodes.length})`;p.save(),p.font="12px sans-serif";const D=p.measureText(C);p.fillStyle=t.boxcolor||k.NODE_DEFAULT_BOXCOLOR,p.beginPath(),p.roundRect(0,-k.NODE_TITLE_HEIGHT-20,D.width+12,20,5),p.fill(),p.fillStyle="#fff",p.fillText(C,6,-k.NODE_TITLE_HEIGHT-6),p.restore()}};const a=this.node.onExecutionStart;this.node.onExecutionStart=function(){return this.resetExecution=!0,a?.call(this)};const l=this.node.onNodeCreated,d=this.groupData;this.node.onNodeCreated=function(){if(!this.widgets)return;const p=d.nodeData.config;if(p)for(const y in p){const v=p[y]?.input;if(v)for(const f in v){if(v[f]?.visible!==!1)continue;const b=d.oldToNewWidgetMap[Number(y)]?.[f],I=this.widgets.find(C=>C.name===b);I&&(I.type="hidden",I.computeSize=()=>[0,-4])}}return l?.call(this)};const c=u((p,y,v)=>{const f=u(({detail:b})=>{const I=y(b);if(!I||g.rootGraph.getNodeById(I))return;const C=this.innerNodes?.findIndex(D=>D.id==I)??-1;C>-1&&(this.node.runningInternalNodeId=C,E.dispatchCustomEvent(p,v(b,`${this.node.id}`,this.node)))},"handler");return E.addEventListener(p,f),f},"handleEvent"),m=c("executing",p=>typeof p=="string"?p:void 0,(p,y)=>y),h=c("executed",p=>typeof p=="object"?p?.display_node||p?.node:void 0,(p,y,v)=>({...typeof p=="object"?p:{},node:y,display_node:y,merge:!v.resetExecution})),w=t.onRemoved;this.node.onRemoved=function(){w?.call(this),E.removeEventListener("executing",m),E.removeEventListener("executed",h)},this.node.refreshComboInNode=p=>{for(const y in this.groupData.newToOldWidgetMap){const v=this.node.widgets?.find(f=>f.name===y);if(v?.type==="combo"){const f=this.groupData.newToOldWidgetMap[y];if(!f.node.type)continue;const b=p[f.node.type],I=b?.input?.required?.[f.inputName]??b?.input?.optional?.[f.inputName];if(!I)continue;v.options.values=I[0];const C=v.options.values;f.inputName!=="image"&&!C.includes(v.value)&&(v.value=C[0],v.callback?.(v.value))}}}}updateInnerWidgets(){if(this.innerNodes)for(const t in this.groupData.newToOldWidgetMap){const i=this.node.widgets?.find(l=>l.name===t);if(!i)continue;const n=i.value,o=this.groupData.newToOldWidgetMap[t],s=o.node.index??0,r=this.innerNodes[s];if(!r)continue;if(r.type==="PrimitiveNode"){r.primitiveValue=n;const l=this.groupData.primitiveToWidget[s];for(const d of l??[]){const c=typeof d.nodeId=="number"?d.nodeId:Number(d.nodeId),m=this.innerNodes[c]?.widgets?.find(h=>h.name===d.inputName);m&&(m.value=n)}continue}else if(r.type==="Reroute"){const l=this.groupData.linksFrom[s];if(l)for(const[,,d,c]of l[0]??[]){if(d==null||c==null)continue;const m=this.innerNodes[Number(d)];if(!m)continue;const h=m.inputs?.[Number(c)];if(h?.widget){const w=h.widget.name,p=m.widgets?.find(y=>y.name===w);p&&(p.value=n)}}}const a=r.widgets?.find(l=>l.name===o.inputName);a&&(a.value=n)}}populatePrimitive(t,i,n){const o=this.groupData.widgetToPrimitive[i]?.[n];if(o==null)return!1;const s=this.groupData.oldToNewWidgetMap[Array.isArray(o)?o[0]:o]?.value;if(!s)return!1;const r=this.node.widgets?.findIndex(a=>a.name===s)??-1;if(r>-1&&this.innerNodes){const a=Array.isArray(o)?o[0]:o,l=this.innerNodes[a];if(!l?.widgets)return!0;let d=l.widgets.length;d-1!==(this.node.widgets?.[r]?.linkedWidgets?.length??0)&&(d=1);for(let c=0;c<d;c++){const m=this.node.widgets?.[r+c],h=l.widgets[c];m&&h&&(m.value=h.value)}}return!0}populateReroute(t,i,n){if(t.type!=="Reroute")return;const o=this.groupData.linksFrom[i]?.[0]?.[0];if(!o)return;const s=o[2],r=o[3];if(s==null||r==null)return;const a=this.groupData.nodeData.nodes[Number(s)],l=a?.inputs;if(!l?.[Number(r)]?.widget)return;const d=(l?.length??0)-(a?.widgets_values?.length??0),c=a?.widgets_values?.[Number(r)-d];if(c==null)return;const m=Object.values(n)[0],h=this.node.widgets?.find(w=>w.name===m);h&&(h.value=c)}populateWidgets(){if(this.node.widgets)for(let t=0;t<this.groupData.nodeData.nodes.length;t++){const i=this.groupData.nodeData.nodes[t],n=this.groupData.oldToNewWidgetMap[t]??{},o=Object.keys(n);if(!i.widgets_values?.length){this.populateReroute(i,t,n);continue}let s=0;for(let r=0;r<o.length;r++){const a=o[r],l=n[a],d=this.node.widgets.findIndex(h=>h.name===l),c=this.node.widgets[d];if(this.populatePrimitive(i,t,a)||d===-1){const h=this.innerNodes?.[t]?.widgets?.find(w=>w.name===a);s+=h?.linkedWidgets?.length??0}if(d===-1)continue;c.value=i.widgets_values?.[r+s];const m=c.linkedWidgets??[];for(let h=0;h<m.length;h++)this.node.widgets[d+h+1].value=i.widgets_values?.[r+ ++s]}}}replaceNodes(t){let i,n;for(let o=0;o<t.length;o++){const s=t[o];(n==null||s.pos[0]<n)&&(n=s.pos[0]),(i==null||s.pos[1]<i)&&(i=s.pos[1]),this.linkOutputs(s,o),g.rootGraph.remove(s),s.id=`${this.node.id}:${o}`}this.linkInputs(),this.node.pos=[n??0,i??0]}linkOutputs(t,i){if(t.outputs)for(const n of t.outputs){if(!n.links)continue;const o=[...n.links];for(const s of o){const r=g.rootGraph.links[s];if(!r)continue;const a=g.rootGraph.getNodeById(r.target_id),l=this.groupData.oldToNewOutputMap[i]?.[r.origin_slot];l!=null&&a&&this.node.connect(l,a,r.target_slot)}}}linkInputs(){for(const t of this.groupData.nodeData.links??[]){const[,i,n,o,s]=t;if(s==null||typeof s=="object")continue;const r=g.rootGraph.getNodeById(s);if(!r||n==null||o==null)continue;const a=this.groupData.oldToNewInputMap[Number(n)]?.[Number(o)];a!=null&&(typeof i=="number"||typeof i=="string")&&r.connect(i,this.node.id,a)}}static getGroupData(t){if(typeof t=="function")return t.nodeData?.[V];const i=t.nodeData;return i?.[V]?i[V]:t.constructor?.nodeData?.[V]}static getHandler(t){let i=t[V];return!i&&te.isGroupNode(t)&&(i=new te(t),t[V]=i),i}static isGroupNode(t){return!!t.constructor?.nodeData?.[V]}static async fromNodes(t){const i=new He(t),n=await i.build();if(!n)return;const{name:o,nodeData:s}=n;await new ie(o,s).registerType();const r=k.createNode(`${G}>${o}`);if(!r)return;r.setInnerNodes?.(i.nodes);const a=te.getHandler(r);return a?.populateWidgets(),g.rootGraph.add(r),a?.replaceNodes(i.nodes),r}},co=u(e=>{for(const t of e)typeof t.type=="string"&&t.type.startsWith("workflow/")&&(t.type=t.type.replace(/^workflow\//,`${G}>`))},"replaceLegacySeparators");async function _e(){const e=Object.values(g.canvas.selected_nodes??{});if(e.length===0)throw new Error("No nodes selected");if(e.length===1)throw new Error("Please select multiple nodes to convert to group node");for(const t of e){if(t instanceof kt)throw new Error("Selected nodes contain a subgraph node");if(R.isGroupNode(t))throw new Error("Selected nodes contain a group node")}return await R.fromNodes(e)}u(_e,"convertSelectedNodesToGroupNode");var qe=u(e=>e.length<2||!!e.find(t=>R.isGroupNode(t)),"convertDisabled");function uo(){const e=Object.values(g.canvas.selected_nodes??{});for(const t of e)R.isGroupNode(t)&&t.convertToNodes?.()}u(uo,"ungroupSelectedGroupNodes");function Me(e){new ct(g).show(e)}u(Me,"manageGroupNodes");var po="Comfy.GroupNode",le,go={name:po,commands:[{id:"Comfy.GroupNode.ConvertSelectedNodesToGroupNode",label:"Convert selected nodes to group node",icon:"pi pi-sitemap",versionAdded:"1.3.17",function:u(()=>_e(),"function")},{id:"Comfy.GroupNode.UngroupSelectedGroupNodes",label:"Ungroup selected group nodes",icon:"pi pi-sitemap",versionAdded:"1.3.17",function:u(()=>uo(),"function")},{id:"Comfy.GroupNode.ManageGroupNodes",label:"Manage group nodes",icon:"pi pi-cog",versionAdded:"1.3.17",function:u((...e)=>Me(e[0]),"function")}],keybindings:[{commandId:"Comfy.GroupNode.ConvertSelectedNodesToGroupNode",combo:{alt:!0,key:"g"}},{commandId:"Comfy.GroupNode.UngroupSelectedGroupNodes",combo:{alt:!0,shift:!0,key:"G"}}],getCanvasMenuItems(e){const t=[],i=!qe(Object.values(e.selected_nodes??{}));t.push({content:"Convert to Group Node (Deprecated)",disabled:!i,callback:u(async()=>_e(),"callback")});const n=e.graph?.extra?.groupNodes,o=!n||!Object.keys(n).length;return t.push({content:"Manage Group Nodes",disabled:o,callback:u(()=>Me(),"callback")}),t},getNodeMenuItems(e){return R.isGroupNode(e)?[]:[{content:"Convert to Group Node (Deprecated)",disabled:!!qe(Object.values(g.canvas.selected_nodes??{})),callback:u(async()=>_e(),"callback")}]},async beforeConfigureGraph(e,t){const i=e?.extra?.groupNodes;i&&(co(e.nodes),await ie.registerFromWorkflow(i,t))},addCustomNodeDefs(e){le=e},nodeCreated(e){if(R.isGroupNode(e)){e[V]=new R(e);const t=R.getHandler(e);e.title&&t?.groupData?.nodeData&&Y.storeGroupNode(e.title,t.groupData.nodeData)}},async refreshComboInNodes(e){Object.assign(le,e);const t=g.rootGraph.extra?.groupNodes;t&&await ie.registerFromWorkflow(t,[])}};g.registerExtension(go);window.comfyAPI=window.comfyAPI||{};window.comfyAPI.groupNode=window.comfyAPI.groupNode||{};window.comfyAPI.groupNode.GroupNodeConfig=ie;window.comfyAPI.groupNode.GroupNodeHandler=R;function A(e,t){e.mode=t,e.graph?.change()}u(A,"setNodeMode");function Ye(e,t){const i=ne().get("Comfy.GroupSelectedNodes.Padding");e.resizeTo([...e.children,...t],i)}u(Ye,"addNodesToGroup");g.registerExtension({name:"Comfy.GroupOptions",getCanvasMenuItems(e){const t=[],i=e.graph.getGroupOnPos(e.graph_mouse[0],e.graph_mouse[1]);if(!i)return e.selectedItems.size>0&&t.push({content:"Add Group For Selected Nodes",callback:u(()=>{const s=new xt;Ye(s,e.selectedItems),e.graph.add(s),e.graph.change(),s.recomputeInsideNodes()},"callback")}),t;i.recomputeInsideNodes();const n=i.nodes;if(t.push({content:"Add Selected Nodes To Group",disabled:!e.selectedItems?.size,callback:u(()=>{Ye(i,e.selectedItems),e.graph.change()},"callback")}),n.length===0)return t;t.push(null);let o=!0;for(let s=1;s<n.length;s++)if(n[s].mode!==n[0].mode){o=!1;break}if(t.push({content:"Fit Group To Nodes",callback:u(()=>{i.recomputeInsideNodes();const s=ne().get("Comfy.GroupSelectedNodes.Padding");i.resizeTo(i.children,s),e.graph.change()},"callback")}),t.push({content:"Select Nodes",callback:u(()=>{e.selectNodes(n),e.graph.change(),e.canvas.focus()},"callback")}),o)switch(n[0].mode){case 0:t.push({content:"Set Group Nodes to Never",callback:u(()=>{for(const s of n)A(s,2)},"callback")}),t.push({content:"Bypass Group Nodes",callback:u(()=>{for(const s of n)A(s,4)},"callback")});break;case 2:t.push({content:"Set Group Nodes to Always",callback:u(()=>{for(const s of n)A(s,0)},"callback")}),t.push({content:"Bypass Group Nodes",callback:u(()=>{for(const s of n)A(s,4)},"callback")});break;case 4:t.push({content:"Set Group Nodes to Always",callback:u(()=>{for(const s of n)A(s,0)},"callback")}),t.push({content:"Set Group Nodes to Never",callback:u(()=>{for(const s of n)A(s,2)},"callback")});break;default:t.push({content:"Set Group Nodes to Always",callback:u(()=>{for(const s of n)A(s,0)},"callback")}),t.push({content:"Set Group Nodes to Never",callback:u(()=>{for(const s of n)A(s,2)},"callback")}),t.push({content:"Bypass Group Nodes",callback:u(()=>{for(const s of n)A(s,4)},"callback")});break}else t.push({content:"Set Group Nodes to Always",callback:u(()=>{for(const s of n)A(s,0)},"callback")}),t.push({content:"Set Group Nodes to Never",callback:u(()=>{for(const s of n)A(s,2)},"callback")}),t.push({content:"Bypass Group Nodes",callback:u(()=>{for(const s of n)A(s,4)},"callback")});return t}});K().registerExtension({name:"Comfy.ImageCompare",async nodeCreated(e){if(e.constructor.comfyClass!=="ImageCompare")return;const[t,i]=e.size;e.setSize([Math.max(t,400),Math.max(i,350)]);const n=e.onExecuted;e.onExecuted=function(o){n?.call(this,o);const{a_images:s,b_images:r}=o,a=g.getRandParam(),l=s&&s.length>0?E.apiURL(`/view?${new URLSearchParams(s[0])}${a}`):"",d=r&&r.length>0?E.apiURL(`/view?${new URLSearchParams(r[0])}${a}`):"",c=e.widgets?.find(m=>m.type==="imagecompare");c&&(c.value={before:l,after:d},c.callback?.(c.value))}}});K().registerExtension({name:"Comfy.ImageCrop",async nodeCreated(e){if(e.constructor.comfyClass!=="ImageCrop")return;const[t,i]=e.size;e.setSize([Math.max(t,300),Math.max(i,450)])}});var fo=[{label:"GLB",value:"glb"},{label:"OBJ",value:"obj"},{label:"STL",value:"stl"}];function we(e){return[null,{content:"Save",has_submenu:!0,callback:u((t,i,n,o)=>{const s=fo.map(r=>({content:r.label,callback:u(()=>{(async()=>{try{await e.exportModel(r.value),M().add({severity:"success",summary:_("toastMessages.exportSuccess",{format:r.label})})}catch(a){console.error("Export failed:",a),M().addAlert(_("toastMessages.failedToExportModel",{format:r.label}))}})()},"callback")}));new k.ContextMenu(s,{event:n,parentMenu:o})},"callback")}]}u(we,"createExportMenuItems");window.comfyAPI=window.comfyAPI||{};window.comfyAPI.exportMenuHelper=window.comfyAPI.exportMenuHelper||{};window.comfyAPI.exportMenuHelper.createExportMenuItems=we;var ho=class{static{u(this,"Load3DConfiguration")}constructor(e,t){this.load3d=e,this.properties=t}configureForSaveMesh(e,t){this.setupModelHandlingForSaveMesh(t,e),this.setupDefaultProperties()}configure(e){this.setupModelHandling(e.modelWidget,e.loadFolder,e.cameraState),this.setupTargetSize(e.width,e.height),this.setupDefaultProperties(e.bgImagePath)}setupTargetSize(e,t){e&&t&&(this.load3d.setTargetSize(e.value,t.value),e.callback=i=>{this.load3d.setTargetSize(i,t.value)},t.callback=i=>{this.load3d.setTargetSize(e.value,i)})}setupModelHandlingForSaveMesh(e,t){const i=this.createModelUpdateHandler(t);e&&i(e)}setupModelHandling(e,t,i){const n=this.createModelUpdateHandler(t,i);e.value&&n(e.value);const o=e.callback;let s=e.value;Object.defineProperty(e,"value",{get(){return s},set(r){s=r,e.callback&&r!==void 0&&r!==""&&e.callback(r)},enumerable:!0,configurable:!0}),e.callback=r=>{n(r),o&&o(r)}}setupDefaultProperties(e){const t=this.loadSceneConfig();this.applySceneConfig(t,e);const i=this.loadCameraConfig();this.applyCameraConfig(i);const n=this.loadLightConfig();this.applyLightConfig(n)}loadSceneConfig(){return this.properties&&"Scene Config"in this.properties?this.properties["Scene Config"]:{showGrid:ne().get("Comfy.Load3D.ShowGrid"),backgroundColor:"#"+ne().get("Comfy.Load3D.BackgroundColor"),backgroundImage:""}}loadCameraConfig(){return this.properties&&"Camera Config"in this.properties?this.properties["Camera Config"]:{cameraType:ne().get("Comfy.Load3D.CameraType"),fov:35}}loadLightConfig(){return this.properties&&"Light Config"in this.properties?this.properties["Light Config"]:{intensity:ne().get("Comfy.Load3D.LightIntensity")}}loadModelConfig(){return this.properties&&"Model Config"in this.properties?this.properties["Model Config"]:{upDirection:"original",materialMode:"original",showSkeleton:!1}}applySceneConfig(e,t){if(this.load3d.toggleGrid(e.showGrid),this.load3d.setBackgroundColor(e.backgroundColor),e.backgroundImage){if(t&&t!=e.backgroundImage)return;this.load3d.setBackgroundImage(e.backgroundImage),e.backgroundRenderMode&&this.load3d.setBackgroundRenderMode(e.backgroundRenderMode)}}applyCameraConfig(e){this.load3d.toggleCamera(e.cameraType),this.load3d.setFOV(e.fov),e.state&&this.load3d.setCameraState(e.state)}applyLightConfig(e){this.load3d.setLightIntensity(e.intensity)}applyModelConfig(e){this.load3d.setUpDirection(e.upDirection),this.load3d.setMaterialMode(e.materialMode)}createModelUpdateHandler(e,t){let i=!0;return async n=>{if(!n)return;const o=n;this.setResourceFolder(o);const s=E.apiURL(W.getResourceURL(...W.splitFilePath(o),e));await this.load3d.loadModel(s,o);const r=this.loadModelConfig();if(this.applyModelConfig(r),i&&t){try{this.load3d.setCameraState(t)}catch(a){console.warn("Failed to restore camera state:",a)}i=!1}}}setResourceFolder(e){const t=e.split("/").filter(n=>n.trim());if(t.length<=2)return;const i=t.slice(1,-1).join("/");i&&this.properties&&(this.properties["Resource Folder"]=i)}},We=ho,mo={name:"image",type:"Load3D",isPreview:!1},Xe={name:"image",type:"Preview3D",isPreview:!0};async function yo(e,t){if(!e?.length)return;const i=t.widgets?.find(n=>n.name==="model_file");try{const n=t.properties["Resource Folder"]||"",o=n.trim()?`3d/${n.trim()}`:"3d",s=await W.uploadFile(e[0],o);if(!s){M().addAlert(_("toastMessages.fileUploadFailed"));return}const r=E.apiURL(W.getResourceURL(...W.splitFilePath(s),"input"));ue(t).waitForLoad3d(a=>{try{a.loadModel(r)}catch{M().addAlert(_("toastMessages.failedToLoadModel"))}}),s&&i&&(i.options?.values?.includes(s)||i.options?.values?.push(s),i.value=s)}catch(n){console.error("Model upload failed:",n),M().addAlert(_("toastMessages.fileUploadFailed"))}}u(yo,"handleModelUpload");async function wo(e,t){if(e?.length)try{const i=t.properties["Resource Folder"]||"",n=i.trim()?`3d/${i.trim()}`:"3d";await W.uploadMultipleFiles(e,n)}catch(i){console.error("Extra resources upload failed:",i),M().addAlert(_("toastMessages.extraResourcesUploadFailed"))}}u(wo,"handleResourcesUpload");function Je(e,t=!1){const i=document.createElement("input");return i.type="file",i.accept=e,i.multiple=t,i.style.display="none",i}u(Je,"createFileInput");K().registerExtension({name:"Comfy.Load3D",settings:[{id:"Comfy.Load3D.ShowGrid",category:["3D","Scene","Initial Grid Visibility"],name:"Initial Grid Visibility",tooltip:"Controls whether the grid is visible by default when a new 3D widget is created. This default can still be toggled individually for each widget after creation.",type:"boolean",defaultValue:!0,experimental:!0},{id:"Comfy.Load3D.BackgroundColor",category:["3D","Scene","Initial Background Color"],name:"Initial Background Color",tooltip:"Controls the default background color of the 3D scene. This setting determines the background appearance when a new 3D widget is created, but can be adjusted individually for each widget after creation.",type:"color",defaultValue:"282828",experimental:!0},{id:"Comfy.Load3D.CameraType",category:["3D","Camera","Initial Camera Type"],name:"Initial Camera Type",tooltip:"Controls whether the camera is perspective or orthographic by default when a new 3D widget is created. This default can still be toggled individually for each widget after creation.",type:"combo",options:["perspective","orthographic"],defaultValue:"perspective",experimental:!0},{id:"Comfy.Load3D.LightIntensity",category:["3D","Light","Initial Light Intensity"],name:"Initial Light Intensity",tooltip:"Sets the default brightness level of lighting in the 3D scene. This value determines how intensely lights illuminate objects when a new 3D widget is created, but can be adjusted individually for each widget after creation.",type:"number",defaultValue:3,experimental:!0},{id:"Comfy.Load3D.LightIntensityMaximum",category:["3D","Light","Light Intensity Maximum"],name:"Light Intensity Maximum",tooltip:"Sets the maximum allowable light intensity value for 3D scenes. This defines the upper brightness limit that can be set when adjusting lighting in any 3D widget.",type:"number",defaultValue:10,experimental:!0},{id:"Comfy.Load3D.LightIntensityMinimum",category:["3D","Light","Light Intensity Minimum"],name:"Light Intensity Minimum",tooltip:"Sets the minimum allowable light intensity value for 3D scenes. This defines the lower brightness limit that can be set when adjusting lighting in any 3D widget.",type:"number",defaultValue:1,experimental:!0},{id:"Comfy.Load3D.LightAdjustmentIncrement",category:["3D","Light","Light Adjustment Increment"],name:"Light Adjustment Increment",tooltip:"Controls the increment size when adjusting light intensity in 3D scenes. A smaller step value allows for finer control over lighting adjustments, while a larger value results in more noticeable changes per adjustment.",type:"slider",attrs:{min:.1,max:1,step:.1},defaultValue:.5,experimental:!0},{id:"Comfy.Load3D.3DViewerEnable",category:["3D","3DViewer","Enable"],name:"Enable 3D Viewer (Beta)",tooltip:"Enables the 3D Viewer (Beta) for selected nodes. This feature allows you to visualize and interact with 3D models directly within the full size 3d viewer.",type:"boolean",defaultValue:!1,experimental:!0},{id:"Comfy.Load3D.PLYEngine",category:["3D","PLY","PLY Engine"],name:"PLY Engine",tooltip:'Select the engine for loading PLY files. "threejs" uses the native Three.js PLYLoader (best for mesh PLY files). "fastply" uses an optimized loader for ASCII point cloud PLY files. "sparkjs" uses Spark.js for 3D Gaussian Splatting PLY files.',type:"combo",options:["threejs","fastply","sparkjs"],defaultValue:"threejs",experimental:!0}],commands:[{id:"Comfy.3DViewer.Open3DViewer",icon:"pi pi-pencil",label:"Open 3D Viewer (Beta) for Selected Node",function:u(()=>{const e=g.canvas.selected_nodes;if(!e||Object.keys(e).length!==1)return;const t=e[Object.keys(e)[0]];if(!Lt(t))return;S.copyToClipspace(t),S.clipspace_return_node=t;const i={node:t};nt().showDialog({key:"global-load3d-viewer",title:_("load3d.viewer.title"),component:zt,props:i,dialogComponentProps:{style:"width: 80vw; height: 80vh;",maximizable:!0,onClose:u(async()=>{await me().handleViewerClose(i.node)},"onClose")}})},"function")}],getCustomWidgets(){return{LOAD_3D(e){const t=Je(".gltf,.glb,.obj,.fbx,.stl,.ply,.spz,.splat,.ksplat",!1);e.properties["Resource Folder"]="",t.onchange=async()=>{await yo(t.files,e)},e.addWidget("button","upload 3d model","upload3dmodel",()=>{t.click()});const i=Je("*",!0);i.onchange=async()=>{await wo(i.files,e),i.value=""},e.addWidget("button","upload extra resources","uploadExtraResources",()=>{i.click()}),e.addWidget("button","clear","clear",()=>{ue(e).waitForLoad3d(s=>{s.clearModel()});const o=e.widgets?.find(s=>s.name==="model_file");o&&(o.value="")});const n=new Ae({node:e,name:"image",component:Le,inputSpec:mo,options:{}});return n.type="load3D",Oe(e,n),{widget:n}}}},getNodeMenuItems(e){if(e.constructor.comfyClass!=="Load3D")return[];const t=me().getLoad3d(e);return t?t.isSplatModel()?[]:we(t):[]},async nodeCreated(e){if(e.constructor.comfyClass!=="Load3D")return;const[t,i]=e.size;e.setSize([Math.max(t,300),Math.max(i,600)]),await Ee(),ue(e).waitForLoad3d(n=>{const o=e.properties["Camera Config"]?.state,s=new We(n,e.properties),r=e.widgets?.find(c=>c.name==="model_file"),a=e.widgets?.find(c=>c.name==="width"),l=e.widgets?.find(c=>c.name==="height"),d=e.widgets?.find(c=>c.name==="image");if(r&&a&&l&&d){const c={loadFolder:"input",modelWidget:r,cameraState:o,width:a,height:l};s.configure(c),d.serializeValue=async()=>{const m=jt.get(e);if(!m)return console.error("No load3d instance found for node"),null;const h=e.properties["Camera Config"]||{cameraType:m.getCurrentCameraType(),fov:m.cameraManager.perspectiveCamera.fov};h.state=m.getCameraState(),e.properties["Camera Config"]=h,m.stopRecording();const{scene:w,mask:p,normal:y}=await m.captureScene(a.value,l.value),[v,f,b]=await Promise.all([W.uploadTempImage(w,"scene"),W.uploadTempImage(p,"scene_mask"),W.uploadTempImage(y,"scene_normal")]);m.handleResize();const I={image:`threed/${v.name} [temp]`,mask:`threed/${f.name} [temp]`,normal:`threed/${b.name} [temp]`,camera_info:e.properties["Camera Config"]?.state||null,recording:""},C=m.getRecordingData();if(C){const[D]=await Promise.all([W.uploadTempImage(C,"recording","mp4")]);I.recording=`threed/${D.name} [temp]`}return I}}})}});K().registerExtension({name:"Comfy.Preview3D",async beforeRegisterNodeDef(e,t){t.name==="Preview3D"&&(t.input.required.image=["PREVIEW_3D"])},getNodeMenuItems(e){if(e.constructor.comfyClass!=="Preview3D")return[];const t=me().getLoad3d(e);return t?t.isSplatModel()?[]:we(t):[]},getCustomWidgets(){return{PREVIEW_3D(e){const t=new Ae({node:e,name:Xe.name,component:Le,inputSpec:Xe,options:{}});return t.type="load3D",Oe(e,t),{widget:t}}}},async nodeCreated(e){if(e.constructor.comfyClass!=="Preview3D")return;const[t,i]=e.size;e.setSize([Math.max(t,400),Math.max(i,550)]),await Ee();const n=e.onExecuted;ue(e).waitForLoad3d(o=>{const s=new We(o,e.properties),r=e.widgets?.find(a=>a.name==="model_file");if(r){const a=e.properties["Last Time Model File"];if(a){r.value=a;const l={loadFolder:"output",modelWidget:r,cameraState:e.properties["Camera Config"]?.state};s.configure(l)}e.onExecuted=function(l){n?.call(this,l);const d=l.result,c=d?.[0];if(!c){const p=_("toastMessages.unableToGetModelFilePath");console.error(p),M().addAlert(p)}const m=d?.[1],h=d?.[2];r.value=c?.replaceAll("\\","/"),e.properties["Last Time Model File"]=r.value;const w={loadFolder:"output",modelWidget:r,cameraState:m,bgImagePath:h};s.configure(w),h&&o.setBackgroundImage(h)}}})}});function pt(e){if(!e){console.error("[MaskEditor] No node provided");return}if(!e.imgs?.length&&e.previewMediaType!=="image"){console.error("[MaskEditor] Node has no images");return}qt().openMaskEditor(e)}u(pt,"openMaskEditor");function vo(){const e=S.clipspace_return_node;if(!e){console.error("[MaskEditor] No clipspace_return_node found");return}pt(e)}u(vo,"openMaskEditorFromClipspace");function oe(){return nt().isDialogOpen("global-mask-editor")}u(oe,"isOpened");var Ke=u(async e=>{if(!oe())return;const t=st(),i=t.brushSettings.size,n=e(i);t.setBrushSize(n)},"changeBrushSize");g.registerExtension({name:"Comfy.MaskEditor",settings:[{id:"Comfy.MaskEditor.BrushAdjustmentSpeed",category:["Mask Editor","BrushAdjustment","Sensitivity"],name:"Brush adjustment speed multiplier",tooltip:"Controls how quickly the brush size and hardness change when adjusting. Higher values mean faster changes.",type:"slider",attrs:{min:.1,max:2,step:.1},defaultValue:1,versionAdded:"1.0.0"},{id:"Comfy.MaskEditor.UseDominantAxis",category:["Mask Editor","BrushAdjustment","UseDominantAxis"],name:"Lock brush adjustment to dominant axis",tooltip:"When enabled, brush adjustments will only affect size OR hardness based on which direction you move more",type:"boolean",defaultValue:!0}],commands:[{id:"Comfy.MaskEditor.OpenMaskEditor",icon:"pi pi-pencil",label:"Open Mask Editor for Selected Node",function:u(()=>{const e=g.canvas.selected_nodes;if(!e||Object.keys(e).length!==1)return;const t=e[Object.keys(e)[0]];pt(t)},"function")},{id:"Comfy.MaskEditor.BrushSize.Increase",icon:"pi pi-plus-circle",label:"Increase Brush Size in MaskEditor",function:u(()=>Ke(e=>q.clamp(e+2,1,250)),"function")},{id:"Comfy.MaskEditor.BrushSize.Decrease",icon:"pi pi-minus-circle",label:"Decrease Brush Size in MaskEditor",function:u(()=>Ke(e=>q.clamp(e-2,1,250)),"function")},{id:"Comfy.MaskEditor.ColorPicker",icon:"pi pi-palette",label:"Open Color Picker in MaskEditor",function:u(()=>{oe()&&st().colorInput?.click()},"function")},{id:"Comfy.MaskEditor.Rotate.Right",icon:"pi pi-refresh",label:"Rotate Right in MaskEditor",function:u(async()=>{oe()&&await ge().rotateClockwise()},"function")},{id:"Comfy.MaskEditor.Rotate.Left",icon:"pi pi-undo",label:"Rotate Left in MaskEditor",function:u(async()=>{oe()&&await ge().rotateCounterclockwise()},"function")},{id:"Comfy.MaskEditor.Mirror.Horizontal",icon:"pi pi-arrows-h",label:"Mirror Horizontal in MaskEditor",function:u(async()=>{oe()&&await ge().mirrorHorizontal()},"function")},{id:"Comfy.MaskEditor.Mirror.Vertical",icon:"pi pi-arrows-v",label:"Mirror Vertical in MaskEditor",function:u(async()=>{oe()&&await ge().mirrorVertical()},"function")}],init(){S.open_maskeditor=vo,console.warn("[MaskEditor] ComfyApp.open_maskeditor is deprecated. Plugins should migrate to using the command system or direct node context menu integration.")}});var bo="Comfy.NodeTemplates",Qe="comfy.templates.json",No=class extends it{static{u(this,"ManageTemplates")}templates;draggedEl;saveVisualCue;emptyImg;importInput;constructor(){super(),this.load().then(e=>{this.templates=e}),this.element.classList.add("comfy-manage-templates"),this.draggedEl=null,this.saveVisualCue=null,this.emptyImg=new Image,this.emptyImg.src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=",this.importInput=N("input",{type:"file",accept:".json",multiple:!0,style:{display:"none"},parent:document.body,onchange:u(()=>this.importAll(),"onchange")})}createButtons(){const e=super.createButtons();return e[0].textContent="Close",e[0].onclick=()=>{clearTimeout(this.saveVisualCue),this.close()},e.unshift(N("button",{type:"button",textContent:"Export",onclick:u(()=>this.exportAll(),"onclick")})),e.unshift(N("button",{type:"button",textContent:"Import",onclick:u(()=>{this.importInput.click()},"onclick")})),e}async load(){let e=[];const t=await E.getUserData(Qe);if(t.status===200)try{e=await t.json()}catch{}else t.status!==404&&console.error(t.status+" "+t.statusText);return e??[]}async store(){const e=JSON.stringify(this.templates,void 0,4);try{await E.storeUserData(Qe,e,{stringify:!1})}catch(t){console.error(t),M().addAlert(t.message)}}async importAll(){for(const e of this.importInput.files)if(e.type==="application/json"||e.name.endsWith(".json")){const t=new FileReader;t.onload=async()=>{const i=JSON.parse(t.result);if(i?.templates){for(const n of i.templates)n?.name&&n?.data&&this.templates.push(n);await this.store()}},await t.readAsText(e)}this.importInput.value=null,this.close()}exportAll(){if(this.templates.length==0){M().addAlert(_("toastMessages.noTemplatesToExport"));return}const e=JSON.stringify({templates:this.templates},null,2);Be("node_templates.json",new Blob([e],{type:"application/json"}))}show(){super.show(N("div",{},this.templates.flatMap((e,t)=>{let i;return[N("div",{dataset:{id:t.toString()},className:"templateManagerRow",style:{display:"grid",gridTemplateColumns:"1fr auto",border:"1px dashed transparent",gap:"5px",backgroundColor:"var(--comfy-menu-bg)"},ondragstart:u(n=>{this.draggedEl=n.currentTarget,n.currentTarget.style.opacity="0.6",n.currentTarget.style.border="1px dashed yellow",n.dataTransfer.effectAllowed="move",n.dataTransfer.setDragImage(this.emptyImg,0,0)},"ondragstart"),ondragend:u(n=>{n.target.style.opacity="1",n.currentTarget.style.border="1px dashed transparent",n.currentTarget.removeAttribute("draggable"),this.element.querySelectorAll(".templateManagerRow").forEach((o,s)=>{var r=Number.parseInt(o.dataset.id);o==this.draggedEl&&r!=s&&this.templates.splice(s,0,this.templates.splice(r,1)[0]),o.dataset.id=s.toString()}),this.store()},"ondragend"),ondragover:u(n=>{if(n.preventDefault(),n.currentTarget==this.draggedEl)return;let o=n.currentTarget.getBoundingClientRect();n.clientY>o.top+o.height/2?n.currentTarget.parentNode.insertBefore(this.draggedEl,n.currentTarget.nextSibling):n.currentTarget.parentNode.insertBefore(this.draggedEl,n.currentTarget)},"ondragover")},[N("label",{textContent:"Name: ",style:{cursor:"grab"},onmousedown:u(n=>{n.target.localName=="label"&&(n.currentTarget.parentNode.draggable="true")},"onmousedown")},[N("input",{value:e.name,dataset:{name:e.name},style:{transitionProperty:"background-color",transitionDuration:"0s"},onchange:u(n=>{clearTimeout(this.saveVisualCue);var o=n.target,s=o.parentNode.parentNode;this.templates[s.dataset.id].name=o.value.trim()||"untitled",this.store(),o.style.backgroundColor="rgb(40, 95, 40)",o.style.transitionDuration="0s",this.saveVisualCue=setTimeout(function(){o.style.transitionDuration=".7s",o.style.backgroundColor="var(--comfy-input-bg)"},15)},"onchange"),onkeypress:u(n=>{var o=n.target;clearTimeout(this.saveVisualCue),o.style.transitionDuration="0s",o.style.backgroundColor="var(--comfy-input-bg)"},"onkeypress"),$:u(n=>i=n,"$")})]),N("div",{},[N("button",{textContent:"Export",style:{fontSize:"12px",fontWeight:"normal"},onclick:u(()=>{const n=JSON.stringify({templates:[e]},null,2),o=new Blob([n],{type:"application/json"});Be((i.value||e.name)+".json",o)},"onclick")}),N("button",{textContent:"Delete",style:{fontSize:"12px",color:"red",fontWeight:"normal"},onclick:u(n=>{const o=n.target.parentNode.parentNode;o.parentNode.removeChild(o),this.templates.splice(o.dataset.id*1,1),this.store();var s=this;setTimeout(function(){s.element.querySelectorAll(".templateManagerRow").forEach((r,a)=>{r.dataset.id=a.toString()})},0)},"onclick")})])])]})))}},fe=new No,Ze=u(async e=>{const t=localStorage.getItem("litegrapheditor_clipboard");await e(),localStorage.setItem("litegrapheditor_clipboard",t)},"clipboardAction"),Io={name:bo,getCanvasMenuItems(e){const t=[];t.push(null),t.push({content:"Save Selected as Template",disabled:!Object.keys(g.canvas.selected_nodes||{}).length,callback:u(async()=>{const n=await re().prompt({title:_("nodeTemplates.saveAsTemplate"),message:_("nodeTemplates.enterName"),defaultValue:""});n?.trim()&&Ze(()=>{g.canvas.copyToClipboard();let o=localStorage.getItem("litegrapheditor_clipboard");o=JSON.parse(o||"{}");const s=Object.keys(g.canvas.selected_nodes);for(let r=0;r<s.length;r++){const a=g.canvas.graph?.getNodeById(s[r]),l=a?.constructor.nodeData;if(!a)continue;const d=R.getGroupData(a);if(d){const c=d.nodeData;if(o.groupNodes||(o.groupNodes={}),l==null)throw new TypeError("nodeData is not set");o.groupNodes[l.name]=c,o.nodes[r].type=l.name}}fe.templates.push({name:n,data:JSON.stringify(o)}),fe.store()})},"callback")});const i=fe.templates.map(n=>({content:n.name,callback:u(()=>{Ze(async()=>{const o=JSON.parse(n.data);await ie.registerFromWorkflow(o.groupNodes??{},[]),o.reroutes?(localStorage.setItem("litegrapheditor_clipboard",n.data),g.canvas.pasteFromClipboard()):at(n.data,g.canvas)})},"callback")}));return i.push(null,{content:"Manage",callback:u(()=>fe.show(),"callback")}),t.push({content:"Node Templates",submenu:{options:i}}),t}};g.registerExtension(Io);g.registerExtension({name:"Comfy.NoteNode",registerCustomNodes(){class e extends he{static{u(this,"NoteNode")}static category;static collapsable;static title_mode;groupcolor=L.node_colors.yellow.groupcolor;isVirtualNode;constructor(n){super(n),this.color=L.node_colors.yellow.color,this.bgcolor=L.node_colors.yellow.bgcolor,this.properties||(this.properties={text:""}),$.STRING(this,"text",["STRING",{default:this.properties.text,multiline:!0}],g),this.serialize_widgets=!0,this.isVirtualNode=!0}}k.registerNodeType("Note",Object.assign(e,{title_mode:k.NORMAL_TITLE,title:"Note",collapsable:!0})),e.category="utils";class t extends he{static{u(this,"MarkdownNoteNode")}static title="Markdown Note";groupcolor=L.node_colors.yellow.groupcolor;constructor(n){super(n),this.color=L.node_colors.yellow.color,this.bgcolor=L.node_colors.yellow.bgcolor,this.properties||(this.properties={text:""}),$.MARKDOWN(this,"text",["STRING",{default:this.properties.text}],g),this.serialize_widgets=!0,this.isVirtualNode=!0}}k.registerNodeType("MarkdownNote",t),t.category="utils"}});K().registerExtension({name:"Comfy.PreviewAny",async beforeRegisterNodeDef(e,t){if(t.name==="PreviewAny"){const i=e.prototype.onNodeCreated;e.prototype.onNodeCreated=function(){i&&i.apply(this,[]);const o=$.MARKDOWN(this,"preview",["MARKDOWN",{}],g).widget,s=$.STRING(this,"preview",["STRING",{multiline:!0}],g).widget,r=$.BOOLEAN(this,"previewMode",["BOOLEAN",{label_on:"Markdown",label_off:"Plaintext",default:!1}],g);r.widget.callback=a=>{o.hidden=!a,o.options.hidden=!a,s.hidden=a,s.options.hidden=a},o.hidden=!0,o.options.hidden=!0,o.options.read_only=!0,o.element.readOnly=!0,o.element.disabled=!0,o.serialize=!1,s.hidden=!1,s.options.hidden=!1,s.options.read_only=!0,s.element.readOnly=!0,s.element.disabled=!0,s.serialize=!1};const n=e.prototype.onExecuted;e.prototype.onExecuted=function(o){n?.apply(this,[o]);const s=this.widgets?.filter(r=>r.name==="preview")??[];for(const r of s){const a=o.text??"";r.value=Array.isArray(a)?a[0]??"":a}}}}});g.registerExtension({name:"Comfy.RerouteNode",registerCustomNodes(e){class t extends he{static{u(this,"RerouteNode")}static category;static defaultVisibility=!1;constructor(n){super(n??""),this.properties||(this.properties={}),this.properties.showOutputText=t.defaultVisibility,this.properties.horizontal=!1,this.addInput("","*"),this.addOutput(this.properties.showOutputText?"*":"","*"),this.isVirtualNode=!0}onAfterGraphConfigured(){requestAnimationFrame(()=>{this.onConnectionsChange(k.INPUT,void 0,!0)})}clone(){const n=super.clone();return n&&(n.removeOutput(0),n.addOutput(this.properties.showOutputText?"*":"","*"),n.setSize(n.computeSize()),n)}onConnectionsChange(n,o,s){const{graph:r}=this;if(!r||e.configuringGraph)return;if(s&&n===k.OUTPUT&&new Set(this.outputs[0].links?.map(f=>r.links[f]?.type)?.filter(f=>f&&f!=="*")??[]).size>1){const f=[];for(const b of this.outputs[0].links??[]){const I=r.links[b];f.push(I)}f.pop();for(const b of f)r.getNodeById(b.target_id)?.disconnectInput(b.target_slot)}let a=this,l=[],d=null,c=null;for(;a;){l.unshift(a);const f=a.inputs[0].link;if(f!==null){const b=r.links[f];if(!b)return;const I=r.getNodeById(b.origin_id);if(!I)return;if(I instanceof t)I===this?(a.disconnectInput(b.target_slot),a=null):a=I;else{c=a,d=I.outputs[b.origin_slot]?.type??null;break}}else{a=null;break}}const m=[this];let h=null;for(;m.length;){a=m.pop();const f=a.outputs?.[0]?.links??[];for(const b of f){const I=r.links[b];if(!I)continue;const C=r.getNodeById(I.target_id);if(C)if(C instanceof t)m.push(C),l.push(C);else{const D=C.inputs[I.target_slot],x=D.type,T=!d||!x||k.isValidConnection(d,x);if(!T){C.disconnectInput(I.target_slot);continue}C.onConnectionsChange?.(k.INPUT,I.target_slot,T,I,D),h=C.inputs[I.target_slot].type}}}const w=d||h||"*",p=L.link_type_colors[w];let y,v;for(const f of l){f.outputs[0].type=d||"*",f.__outputType=w,f.outputs[0].name=f.properties.showOutputText?`${w}`:"",f.setSize(f.computeSize());for(const b of f.outputs[0].links||[]){const I=r.links[b];if(!I||(I.color=p,e.configuringGraph))continue;const C=r.getNodeById(I.target_id);if(!C)continue;const D=C.inputs?.[I.target_slot];if(D?.widget){const x=Ge(D);y||(y=x[1]??{},v=x[0]);const T=pe(D,[x[0],y]);T.customConfig&&(y=T.customConfig)}}}for(const f of l)y&&h?(f.inputs[0].widget={name:"value"},Se(f.inputs[0],[v??`${w}`,y])):Se(f.inputs[0],void 0);if(c?.inputs?.[0]?.link){const f=r.links[c.inputs[0].link];f&&(f.color=p)}}getExtraMenuOptions(n,o){return o.unshift({content:(this.properties.showOutputText?"Hide":"Show")+" Type",callback:u(()=>{this.properties.showOutputText=!this.properties.showOutputText,this.properties.showOutputText?this.outputs[0].name=`${this.__outputType||this.outputs[0].type}`:this.outputs[0].name="",this.setSize(this.computeSize()),e.canvas.setDirty(!0,!0)},"callback")},{content:(t.defaultVisibility?"Hide":"Show")+" Type By Default",callback:u(()=>{t.setDefaultTextVisibility(!t.defaultVisibility)},"callback")}),[]}computeSize(){return[this.properties.showOutputText&&this.outputs&&this.outputs.length?Math.max(75,k.NODE_TEXT_SIZE*this.outputs[0].name.length*.6+40):75,26]}static setDefaultTextVisibility(n){t.defaultVisibility=n,n?localStorage["Comfy.RerouteNode.DefaultVisibility"]="true":delete localStorage["Comfy.RerouteNode.DefaultVisibility"]}}t.setDefaultTextVisibility(!!localStorage["Comfy.RerouteNode.DefaultVisibility"]),k.registerNodeType("Reroute",Object.assign(t,{title_mode:k.NO_TITLE,title:"Reroute",collapsable:!1})),t.category="utils"}});var Co=new Set(["SaveImage","SaveVideo","SaveAnimatedWEBP","SaveWEBM","SaveAudio","SaveGLB","SaveAnimatedPNG","CLIPSave","VAESave","ModelSave","LoraSave","SaveLatent"]);g.registerExtension({name:"Comfy.SaveImageExtraOutput",async beforeRegisterNodeDef(e,t,i){if(Co.has(t.name)){const n=e.prototype.onNodeCreated;e.prototype.onNodeCreated=function(){const o=n?n.apply(this,arguments):void 0,s=this.widgets.find(r=>r.name==="filename_prefix");return s.serializeValue=()=>rt(i.graph,s.value),o}}else{const n=e.prototype.onNodeCreated;e.prototype.onNodeCreated=function(){const o=n?n.apply(this,arguments):void 0;return(!this.properties||!("Node name for S&R"in this.properties))&&this.addProperty("Node name for S&R",this.constructor.type,"string"),o}}}});var et={name:"image",type:"Preview3D",isPreview:!0};K().registerExtension({name:"Comfy.SaveGLB",async beforeRegisterNodeDef(e,t){t.name==="SaveGLB"&&(t.input.required.image=["PREVIEW_3D"])},getCustomWidgets(){return{PREVIEW_3D(e){const t=new Ae({node:e,name:et.name,component:Le,inputSpec:et,options:{}});return t.type="load3D",Oe(e,t),{widget:t}}}},getNodeMenuItems(e){if(e.constructor.comfyClass!=="SaveGLB")return[];const t=me().getLoad3d(e);return t?t.isSplatModel()?[]:we(t):[]},async nodeCreated(e){if(e.constructor.comfyClass!=="SaveGLB")return;const[t,i]=e.size;e.setSize([Math.max(t,400),Math.max(i,550)]),await Ee();const n=e.onExecuted;e.onExecuted=function(o){n?.call(this,o);const s=o["3d"]?.[0];s&&ue(e).waitForLoad3d(r=>{const a=e.widgets?.find(l=>l.name==="image");if(r&&a){const l=(s.subfolder??"")+"/"+(s.filename??"");a.value=l;const d=new We(r,e.properties),c=s.type,m=u(()=>{r.removeEventListener("modelLoadingEnd",m),W.generateThumbnailIfNeeded(r,l,c)},"onModelLoaded");r.addEventListener("modelLoadingEnd",m),d.configureForSaveMesh(c,l)}})}}});function ko(e,t){const i=t.selectedItems;if(i.size<=1)return;const n=_t(i,10);if(!n)return;const[o,s,r,a]=n;e.save(),e.lineWidth=2/t.ds.scale,e.strokeStyle=getComputedStyle(document.documentElement).getPropertyValue("--border-color").trim()||"#ffffff66";const l=5/t.ds.scale;e.setLineDash([l,l]),e.beginPath(),e.roundRect(o,s,r,a,8/t.ds.scale),e.stroke(),e.restore()}u(ko,"drawSelectionBorder");g.registerExtension({name:"Comfy.SelectionBorder",async init(){const e=g.canvas.onDrawForeground;g.canvas.onDrawForeground=function(t,i){e?.call(this,t,i),ko(t,g.canvas)}}});var de=!1,ce=0;g.registerExtension({name:"Comfy.SimpleTouchSupport",setup(){let e=null,t=null,i=null,n=null;function o(a){return Math.hypot(a.touches[0].clientX-a.touches[1].clientX,a.touches[0].clientY-a.touches[1].clientY)}u(o,"getMultiTouchPos");function s(a){return{clientX:(a.touches[0].clientX+a.touches[1].clientX)/2,clientY:(a.touches[0].clientY+a.touches[1].clientY)/2}}u(s,"getMultiTouchCenter"),g.canvasEl.parentElement?.addEventListener("touchstart",a=>{ce+=a.changedTouches.length,i=null,n=null,a.touches?.length===1?(t=new Date,i=a.touches[0]):(t=null,a.touches?.length===2&&(n=g.canvas.ds.scale,i=s(a),e=o(a),g.canvas.pointer.isDown=!1))},!0),g.canvasEl.parentElement?.addEventListener("touchend",a=>{if(ce-=a.changedTouches.length,a.touches?.length!==1&&(de=!1),t&&!a.touches?.length){if(new Date().getTime()-t.getTime()>600&&a.target===g.canvasEl){const l={button:2,clientX:a.changedTouches[0].clientX,clientY:a.changedTouches[0].clientY,pointerId:1,isPrimary:!0};g.canvasEl.dispatchEvent(new PointerEvent("pointerdown",l)),setTimeout(()=>{g.canvasEl.dispatchEvent(new PointerEvent("pointerup",l))}),a.preventDefault()}t=null}});const r=u(()=>{ce=0,de=!1,t=null,i=null,n=null,e=null},"resetTouchState");document.addEventListener("visibilitychange",()=>{document.hidden&&r()}),g.canvasEl.parentElement?.addEventListener("touchcancel",r),g.canvasEl.parentElement?.addEventListener("touchmove",a=>{if(t&&i&&a.touches?.length===1){const c=a.touches[0],m=c.clientX-i.clientX,h=c.clientY-i.clientY;m*m+h*h>30&&(t=null)}if(a.touches?.length===2&&i&&!a.ctrlKey&&!a.shiftKey){a.preventDefault(),g.canvas.pointer.isDown=!1,de=!0,k.closeAllContextMenus(window),g.canvas.search_box?.close();const c=o(a),m=s(a);if(n===null||e===null)return;let h=n*c/e;const w=(m.clientX-i.clientX)/h,p=(m.clientY-i.clientY)/h;h<g.canvas.ds.min_scale?h=g.canvas.ds.min_scale:h>g.canvas.ds.max_scale&&(h=g.canvas.ds.max_scale);const y=g.canvas.ds.scale;g.canvas.ds.scale=h,Math.abs(g.canvas.ds.scale-1)<.01&&(g.canvas.ds.scale=1);const v=g.canvas.ds.scale,f=u(b=>[m.clientX/b-g.canvas.ds.offset[0],m.clientY/b-g.canvas.ds.offset[1]],"convertScaleToOffset");var l=f(y),d=f(v);g.canvas.ds.offset[0]+=w+d[0]-l[0],g.canvas.ds.offset[1]+=p+d[1]-l[1],i.clientX=m.clientX,i.clientY=m.clientY,g.canvas.setDirty(!0,!0)}},!0)}});var Do=L.prototype.processMouseDown;L.prototype.processMouseDown=function(e){if(!(de||ce))return g.canvas.pointer.isDown=!1,Do.apply(this,[e])};var _o=L.prototype.processMouseMove;L.prototype.processMouseMove=function(e){if(!(de||ce>1))return _o.apply(this,[e])};g.registerExtension({name:"Comfy.SlotDefaults",suggestionsNumber:null,init(){k.search_filter_enabled=!0,k.middle_click_slot_add_default_node=!0,this.suggestionsNumber=g.ui.settings.addSetting({id:"Comfy.NodeSuggestions.number",category:["Comfy","Node Search Box","NodeSuggestions"],name:"Number of nodes suggestions",tooltip:"Only for litegraph searchbox/context menu",type:"slider",attrs:{min:1,max:100,step:1},defaultValue:5,onChange:u(e=>{this.setDefaults(e)},"onChange")})},slot_types_default_out:{},slot_types_default_in:{},async beforeRegisterNodeDef(e,t){var i=t.name;const n=t.input?.required;for(const l in n){var o=n[l];if(typeof o[0]!="string")continue;var s=o[0];if(s in $&&!o[1]?.forceInput||(s in this.slot_types_default_out||(this.slot_types_default_out[s]=["Reroute"]),this.slot_types_default_out[s].includes(i)))continue;this.slot_types_default_out[s].push(i);const d=s.toLocaleLowerCase();d in k.registered_slot_in_types||(k.registered_slot_in_types[d]={nodes:[]}),k.registered_slot_in_types[d].nodes.push(e.comfyClass)}var r=t.output??[];for(const l of r){const d=l;d in this.slot_types_default_in||(this.slot_types_default_in[d]=["Reroute"]),!this.slot_types_default_in[d].includes(i)&&(this.slot_types_default_in[d].push(i),d in k.registered_slot_out_types||(k.registered_slot_out_types[d]={nodes:[]}),k.registered_slot_out_types[d].nodes.push(e.comfyClass),k.slot_types_out.includes(d)||k.slot_types_out.push(d))}var a=this.suggestionsNumber.value;this.setDefaults(a)},setDefaults(e){k.slot_types_default_out={},k.slot_types_default_in={};for(const t in this.slot_types_default_out)k.slot_types_default_out[t]=this.slot_types_default_out[t].slice(0,e);for(const t in this.slot_types_default_in)k.slot_types_default_in[t]=this.slot_types_default_in[t].slice(0,e)}});async function xo(e,t,i,n,o=!1){try{const s=new FormData;s.append("image",i),o&&s.append("subfolder","pasted");const r=await E.fetchApi("/upload/image",{method:"POST",body:s});if(r.status===200){const a=await r.json();let l=a.name;a.subfolder&&(l=a.subfolder+"/"+l),e.options.values.includes(l)||e.options.values.push(l),n&&(t.element.src=E.apiURL(ye(...lt(l))),e.value=l,e.callback?.(l))}else M().addAlert(r.status+" - "+r.statusText)}catch(s){M().addAlert(s)}}u(xo,"uploadFile");g.registerExtension({name:"Comfy.AudioWidget",async beforeRegisterNodeDef(e,t){["LoadAudio","SaveAudio","PreviewAudio","SaveAudioMP3","SaveAudioOpus"].includes(e.prototype.comfyClass)&&(t.input.required.audioUI=["AUDIO_UI",{}])},getCustomWidgets(){return{AUDIO_UI(e,t){const i=document.createElement("audio");i.controls=!0,i.classList.add("comfy-audio"),i.setAttribute("name","media");const n=e.addDOMWidget(t,"audioUI",i);n.serialize=!1;const{nodeData:o}=e.constructor;if(o==null)throw new TypeError("nodeData is null");if(o.output_node){n.element.classList.add("empty-audio-widget");const s=e.onExecuted;e.onExecuted=function(r){s?.call(this,r);const a=r.audio;if(!a?.length)return;const l=a[0];n.element.src=E.apiURL(ye(l.subfolder??"",l.filename??"",l.type)),n.element.classList.remove("empty-audio-widget")}}return n.onRemove=J(n.onRemove,()=>{n.element&&(n.element.pause(),n.element.src="",n.element.remove())}),{widget:n}}}},onNodeOutputsUpdated(e){for(const[t,i]of Object.entries(e)){if(!i.audio?.length)continue;const n=Ct(g.rootGraph,t);if(!n)continue;const o=n.widgets?.find(r=>r.name==="audioUI"),s=i.audio[0];o.element.src=E.apiURL(ye(s.subfolder??"",s.filename??"",s.type)),o.element.classList.remove("empty-audio-widget")}}});g.registerExtension({name:"Comfy.UploadAudio",async beforeRegisterNodeDef(e,t){t?.input?.required?.audio?.[1]?.audio_upload===!0&&(t.input.required.upload=["AUDIOUPLOAD",{}])},getCustomWidgets(){return{AUDIOUPLOAD(e,t){const i=e.widgets.find(c=>c.name==="audio"),n=e.widgets.find(c=>c.name==="audioUI");n.options.canvasOnly=!0;const o=u(()=>{typeof i.value=="string"&&(n.element.src=E.apiURL(ye(...lt(i.value))))},"onAudioWidgetUpdate");i.value&&o(),i.callback=o;const s=e.onGraphConfigured;e.onGraphConfigured=function(){s?.apply(this,arguments),i.value&&o()};const r=u(async c=>(c?.length&&xo(i,n,c[0],!0),c),"handleUpload"),a=u(c=>c.type.startsWith("audio/"),"isAudioFile"),{openFileSelection:l}=Gt(e,{accept:"audio/*",onSelect:r}),d=e.addWidget("button",t,"",l,{serialize:!1,canvasOnly:!0});return d.label=_("g.choose_file_to_upload"),Ft(e,{fileFilter:a,onDrop:r}),Pt(e,{fileFilter:a,onPaste:r}),e.previewMediaType="audio",{widget:d}}}}});g.registerExtension({name:"Comfy.RecordAudio",getCustomWidgets(){return{AUDIO_RECORD(e,t){const i=document.createElement("audio");i.controls=!0,i.classList.add("comfy-audio"),i.setAttribute("name","media");const n=e.addDOMWidget(t,"audioUI",i);n.options.canvasOnly=!1;let o=null,s=!1,r=[],a=null,l=null,d=null,c=null;n.serializeValue=async()=>{s&&o&&(d=new Promise(p=>{c=p}),o.stop(),await d);const h=n.element.src;if(!h)return M().addAlert(_("g.noAudioRecorded")),"";const w=await fetch(h).then(p=>p.blob());return await Z().convertBlobToFileAndSubmit(w)},l=e.addWidget("button",t,"",async()=>{if(s)o&&s&&o.stop();else try{a=await navigator.mediaDevices.getUserMedia({audio:!0}),o=new wt(a,{mimeType:"audio/wav"}),r=[],o.ondataavailable=h=>{r.push(h.data)},o.onstop=async()=>{const h=new Blob(r,{type:"audio/wav"});Z().stopAllTracks(a),n.element.src&&n.element.src.startsWith("blob:")&&URL.revokeObjectURL(n.element.src),n.element.src=URL.createObjectURL(h),s=!1,l&&(l.label=_("g.startRecording")),c&&(c(),c=null,d=null)},o.onerror=h=>{console.error("MediaRecorder error:",h),Z().stopAllTracks(a),s=!1,l&&(l.label=_("g.startRecording")),c&&(c(),c=null,d=null)},o.start(),s=!0,l&&(l.label=_("g.stopRecording"))}catch(h){if(console.error("Error accessing microphone:",h),M().addAlert(_("g.micPermissionDenied")),o)try{o.stop()}catch{}Z().stopAllTracks(a),a=null,s=!1,l&&(l.label=_("g.startRecording"))}},{serialize:!1,canvasOnly:!1}),l.label=_("g.startRecording"),l.type="audiorecord";const m=e.onRemoved;return e.onRemoved=function(){s&&o&&o.stop(),Z().stopAllTracks(a),n.element.src?.startsWith("blob:")&&URL.revokeObjectURL(n.element.src),m?.call(this)},{widget:l}}}},async nodeCreated(e){e.constructor.comfyClass==="RecordAudio"&&await Z().registerWavEncoder()}});var To=u(e=>{const[t,i]=e;return i?(i.image_upload===!0||i.video_upload===!0||i.animated_image_upload===!0)&&(Ot(e)||t==="COMBO"):!1},"isMediaUploadComboInput"),So=u((e,t)=>["IMAGEUPLOAD",{...t[1],imageInputName:e}],"createUploadInput");g.registerExtension({name:"Comfy.UploadImage",beforeRegisterNodeDef(e,t){const{input:i}=t??{},{required:n}=i??{};if(!n)return;const o=Object.entries(n).find(([s,r])=>To(r));if(o){const[s,r]=o;n.upload=So(s,r)}}});var tt=Symbol();g.registerExtension({name:"Comfy.WebcamCapture",getCustomWidgets(){return{WEBCAM(e,t){let i;e[tt]=new Promise(r=>i=r);const n=document.createElement("div");n.style.background="rgba(0,0,0,0.25)",n.style.textAlign="center";const o=document.createElement("video");return o.style.height=o.style.width="100%",u(async()=>{try{const r=await navigator.mediaDevices.getUserMedia({video:!0,audio:!1});n.replaceChildren(o),setTimeout(()=>i(o),500),o.addEventListener("loadedmetadata",()=>i(o),!1),o.srcObject=r,o.play()}catch(r){const a=document.createElement("div");a.style.color="red",a.style.overflow="auto",a.style.maxHeight="100%",a.style.whiteSpace="pre-wrap",window.isSecureContext?a.textContent=`Unable to load webcam, please ensure access is granted:
3
3
  `+r.message:a.textContent=`Unable to load webcam. A secure context is required, if you are not accessing ComfyUI on localhost (127.0.0.1) you will have to enable TLS (https)
4
4
 
5
- `+r.message,n.replaceChildren(a)}},"loadVideo")(),{widget:e.addDOMWidget(t,"WEBCAM",n)}}}},nodeCreated(e){if(e.type,e.constructor.comfyClass!=="WebcamCapture")return;let t;const i=e.widgets.find(d=>d.name==="image"),n=e.widgets.find(d=>d.name==="width"),o=e.widgets.find(d=>d.name==="height"),s=e.widgets.find(d=>d.name==="capture_on_queue"),r=document.createElement("canvas"),a=u(()=>{r.width=n.value,r.height=o.value,r.getContext("2d").drawImage(t,0,0,n.value,o.value);const d=r.toDataURL("image/png"),c=new Image;c.onload=()=>{e.imgs=[c],g.canvas.setDirty(!0)},c.src=d},"capture"),l=e.addWidget("button","waiting for camera...","capture",a,{canvasOnly:!0});l.disabled=!0,l.serializeValue=()=>{},i.serializeValue=async()=>{if(s.value)a();else if(!e.imgs?.length){const p="No webcam image captured";throw M().addAlert(p),new Error(p)}const d=await new Promise(p=>r.toBlob(p)),c=`${+new Date}.png`,m=new File([d],c),h=new FormData;h.append("image",m),h.append("subfolder","webcam"),h.append("type","temp");const w=await E.fetchApi("/upload/image",{method:"POST",body:h});if(w.status!==200){const p=`Error uploading camera image: ${w.status} - ${w.statusText}`;throw M().addAlert(p),new Error(p)}return`webcam/${c} [temp]`},e[tt].then(d=>{t=d,n.value||(n.value=t.videoWidth||640,o.value=t.videoHeight||480),l.disabled=!1,l.label=_("g.capture")})}});bt&&(await se(()=>import("./cloudRemoteConfig-DhMjC5TB.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]),import.meta.url),await se(()=>import("./cloudBadges-C1a7fBky.js"),__vite__mapDeps([25,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]),import.meta.url),await se(()=>import("./cloudSessionCookie-Duxk6ux1.js"),__vite__mapDeps([26,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]),import.meta.url),await se(()=>import("./cloudFeedbackTopbarButton-DR0T8sWG.js"),__vite__mapDeps([27,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]),import.meta.url),window.__CONFIG__?.subscription_required&&await se(()=>import("./cloudSubscription-B8l6B9Nx.js"),__vite__mapDeps([28,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]),import.meta.url));
5
+ `+r.message,n.replaceChildren(a)}},"loadVideo")(),{widget:e.addDOMWidget(t,"WEBCAM",n)}}}},nodeCreated(e){if(e.type,e.constructor.comfyClass!=="WebcamCapture")return;let t;const i=e.widgets.find(d=>d.name==="image"),n=e.widgets.find(d=>d.name==="width"),o=e.widgets.find(d=>d.name==="height"),s=e.widgets.find(d=>d.name==="capture_on_queue"),r=document.createElement("canvas"),a=u(()=>{r.width=n.value,r.height=o.value,r.getContext("2d").drawImage(t,0,0,n.value,o.value);const d=r.toDataURL("image/png"),c=new Image;c.onload=()=>{e.imgs=[c],g.canvas.setDirty(!0)},c.src=d},"capture"),l=e.addWidget("button","waiting for camera...","capture",a,{canvasOnly:!0});l.disabled=!0,l.serializeValue=()=>{},i.serializeValue=async()=>{if(s.value)a();else if(!e.imgs?.length){const p="No webcam image captured";throw M().addAlert(p),new Error(p)}const d=await new Promise(p=>r.toBlob(p)),c=`${+new Date}.png`,m=new File([d],c),h=new FormData;h.append("image",m),h.append("subfolder","webcam"),h.append("type","temp");const w=await E.fetchApi("/upload/image",{method:"POST",body:h});if(w.status!==200){const p=`Error uploading camera image: ${w.status} - ${w.statusText}`;throw M().addAlert(p),new Error(p)}return`webcam/${c} [temp]`},e[tt].then(d=>{t=d,n.value||(n.value=t.videoWidth||640,o.value=t.videoHeight||480),l.disabled=!1,l.label=_("g.capture")})}});bt&&(await se(()=>import("./cloudRemoteConfig-F9J0iGyF.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]),import.meta.url),await se(()=>import("./cloudBadges-D5mGJbRy.js"),__vite__mapDeps([25,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]),import.meta.url),await se(()=>import("./cloudSessionCookie-MEORlqtg.js"),__vite__mapDeps([26,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]),import.meta.url),await se(()=>import("./cloudFeedbackTopbarButton-RZUssOmb.js"),__vite__mapDeps([27,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]),import.meta.url),window.__CONFIG__?.subscription_required&&await se(()=>import("./cloudSubscription-CuWNXKVx.js"),__vite__mapDeps([28,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]),import.meta.url));
6
6
 
7
- //# sourceMappingURL=core-DBfeqMDR.js.map
7
+ //# sourceMappingURL=core-IYu8XAIx.js.map