comfyui-frontend-package 1.37.9__py3-none-any.whl → 1.37.11__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- comfyui_frontend_package/static/assets/{AboutPanel-BudnQURa.js → AboutPanel-B-lCq9HV.js} +2 -2
- comfyui_frontend_package/static/assets/{AboutPanel-BudnQURa.js.map → AboutPanel-B-lCq9HV.js.map} +1 -1
- comfyui_frontend_package/static/assets/{AudioPreviewPlayer-CHjtFZRu.js → AudioPreviewPlayer-CXgr12AM.js} +2 -2
- comfyui_frontend_package/static/assets/{AudioPreviewPlayer-CHjtFZRu.js.map → AudioPreviewPlayer-CXgr12AM.js.map} +1 -1
- comfyui_frontend_package/static/assets/{ComfyQueueButton-QhN0FmOY.js → ComfyQueueButton-C6ttLtL6.js} +2 -2
- comfyui_frontend_package/static/assets/{ComfyQueueButton-QhN0FmOY.js.map → ComfyQueueButton-C6ttLtL6.js.map} +1 -1
- comfyui_frontend_package/static/assets/{ExtensionPanel-D2sITMri.js → ExtensionPanel-uFlj7Yfm.js} +2 -2
- comfyui_frontend_package/static/assets/{ExtensionPanel-D2sITMri.js.map → ExtensionPanel-uFlj7Yfm.js.map} +1 -1
- comfyui_frontend_package/static/assets/GraphView-0U0T8pwU.js +15 -0
- comfyui_frontend_package/static/assets/GraphView-0U0T8pwU.js.map +1 -0
- comfyui_frontend_package/static/assets/GraphView-2T90vQj0.css +1 -0
- comfyui_frontend_package/static/assets/{KeybindingPanel-Dm6H1RN2.js → KeybindingPanel-DtxoTOoX.js} +2 -2
- comfyui_frontend_package/static/assets/{KeybindingPanel-Dm6H1RN2.js.map → KeybindingPanel-DtxoTOoX.js.map} +1 -1
- comfyui_frontend_package/static/assets/LazyImage.vue_vue_type_script_setup_true_lang-BSzd4gKh.js +2 -0
- comfyui_frontend_package/static/assets/LazyImage.vue_vue_type_script_setup_true_lang-BSzd4gKh.js.map +1 -0
- comfyui_frontend_package/static/assets/{LegacyCreditsPanel-Be7L1Af3.js → LegacyCreditsPanel-CO0JRKfg.js} +2 -2
- comfyui_frontend_package/static/assets/{LegacyCreditsPanel-Be7L1Af3.js.map → LegacyCreditsPanel-CO0JRKfg.js.map} +1 -1
- comfyui_frontend_package/static/assets/{Load3D-BAJ3yM4D.js → Load3D-NG6IeknA.js} +2 -2
- comfyui_frontend_package/static/assets/Load3D-NG6IeknA.js.map +1 -0
- comfyui_frontend_package/static/assets/{Load3D.vue_vue_type_script_setup_true_lang-DMHpkO9N.js → Load3D.vue_vue_type_script_setup_true_lang-DYT5Ecka.js} +2 -2
- comfyui_frontend_package/static/assets/{Load3D.vue_vue_type_script_setup_true_lang-DMHpkO9N.js.map → Load3D.vue_vue_type_script_setup_true_lang-DYT5Ecka.js.map} +1 -1
- comfyui_frontend_package/static/assets/{Media3DTop-DdNgRlQW.js → Media3DTop-iLfJefgN.js} +2 -2
- comfyui_frontend_package/static/assets/{Media3DTop-DdNgRlQW.js.map → Media3DTop-iLfJefgN.js.map} +1 -1
- comfyui_frontend_package/static/assets/{ServerConfigPanel-LtRqEOzu.js → ServerConfigPanel-B8Qy2naY.js} +2 -2
- comfyui_frontend_package/static/assets/{ServerConfigPanel-LtRqEOzu.js.map → ServerConfigPanel-B8Qy2naY.js.map} +1 -1
- comfyui_frontend_package/static/assets/SubscriptionRequiredDialogContent-C1UryadQ.css +1 -0
- comfyui_frontend_package/static/assets/SubscriptionRequiredDialogContent-CIYbxFB5.js +2 -0
- comfyui_frontend_package/static/assets/{SubscriptionRequiredDialogContent-CDaF1jns.js.map → SubscriptionRequiredDialogContent-CIYbxFB5.js.map} +1 -1
- comfyui_frontend_package/static/assets/{UserAvatar.vue_vue_type_script_setup_true_lang-48WRCWXz.js → UserAvatar.vue_vue_type_script_setup_true_lang-COE-v4cY.js} +2 -2
- comfyui_frontend_package/static/assets/{UserAvatar.vue_vue_type_script_setup_true_lang-48WRCWXz.js.map → UserAvatar.vue_vue_type_script_setup_true_lang-COE-v4cY.js.map} +1 -1
- comfyui_frontend_package/static/assets/{UserPanel-_xK7KdbS.js → UserPanel-D5s95p9f.js} +2 -2
- comfyui_frontend_package/static/assets/{UserPanel-_xK7KdbS.js.map → UserPanel-D5s95p9f.js.map} +1 -1
- comfyui_frontend_package/static/assets/{UserSelectView-B_VOz5XU.js → UserSelectView-TWmqiRNC.js} +2 -2
- comfyui_frontend_package/static/assets/{UserSelectView-B_VOz5XU.js.map → UserSelectView-TWmqiRNC.js.map} +1 -1
- comfyui_frontend_package/static/assets/{ValueControlPopover-BPJIx3_y.js → ValueControlPopover-oFjRn7nT.js} +2 -2
- comfyui_frontend_package/static/assets/{ValueControlPopover-BPJIx3_y.js.map → ValueControlPopover-oFjRn7nT.js.map} +1 -1
- comfyui_frontend_package/static/assets/{WidgetAudioUI-5nP5sugf.js → WidgetAudioUI-DYG-X1jd.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetAudioUI-5nP5sugf.js.map → WidgetAudioUI-DYG-X1jd.js.map} +1 -1
- comfyui_frontend_package/static/assets/{WidgetButton-Cd9G_fIM.js → WidgetButton-pJqn_pIo.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetButton-Cd9G_fIM.js.map → WidgetButton-pJqn_pIo.js.map} +1 -1
- comfyui_frontend_package/static/assets/{WidgetChart-Dz4GcJwO.js → WidgetChart-BntGUEQZ.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetChart-Dz4GcJwO.js.map → WidgetChart-BntGUEQZ.js.map} +1 -1
- comfyui_frontend_package/static/assets/{WidgetColorPicker-x6uZPjSf.js → WidgetColorPicker-JIRhb2dg.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetColorPicker-x6uZPjSf.js.map → WidgetColorPicker-JIRhb2dg.js.map} +1 -1
- comfyui_frontend_package/static/assets/{WidgetGalleria-DHPc3hwg.js → WidgetGalleria-CtUTrKmF.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetGalleria-DHPc3hwg.js.map → WidgetGalleria-CtUTrKmF.js.map} +1 -1
- comfyui_frontend_package/static/assets/WidgetInputNumber-DPITONSH.js +2 -0
- comfyui_frontend_package/static/assets/WidgetInputNumber-DPITONSH.js.map +1 -0
- comfyui_frontend_package/static/assets/{WidgetInputNumber.vue_vue_type_script_setup_true_lang-vY96bQKz.js → WidgetInputNumber.vue_vue_type_script_setup_true_lang-Cb9Vjdsr.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetInputNumber.vue_vue_type_script_setup_true_lang-vY96bQKz.js.map → WidgetInputNumber.vue_vue_type_script_setup_true_lang-Cb9Vjdsr.js.map} +1 -1
- comfyui_frontend_package/static/assets/{WidgetInputText-BbfUME5C.js → WidgetInputText-C9e7Utok.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetInputText-BbfUME5C.js.map → WidgetInputText-C9e7Utok.js.map} +1 -1
- comfyui_frontend_package/static/assets/{WidgetLayoutField.vue_vue_type_script_setup_true_lang-7bIn_5fI.js → WidgetLayoutField.vue_vue_type_script_setup_true_lang-B2h9BxrZ.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetLayoutField.vue_vue_type_script_setup_true_lang-7bIn_5fI.js.map → WidgetLayoutField.vue_vue_type_script_setup_true_lang-B2h9BxrZ.js.map} +1 -1
- comfyui_frontend_package/static/assets/WidgetLegacy-DxWXa1q8.js +2 -0
- comfyui_frontend_package/static/assets/WidgetLegacy-DxWXa1q8.js.map +1 -0
- comfyui_frontend_package/static/assets/WidgetMarkdown-BbdYbwjR.js +2 -0
- comfyui_frontend_package/static/assets/{WidgetMarkdown-voa7Ohgp.js.map → WidgetMarkdown-BbdYbwjR.js.map} +1 -1
- comfyui_frontend_package/static/assets/WidgetRecordAudio-DQzt1Okr.js +2 -0
- comfyui_frontend_package/static/assets/WidgetRecordAudio-DQzt1Okr.js.map +1 -0
- comfyui_frontend_package/static/assets/WidgetSelect-BCeT8JsM.js +2 -0
- comfyui_frontend_package/static/assets/WidgetSelect-BCeT8JsM.js.map +1 -0
- comfyui_frontend_package/static/assets/{WidgetSelect.vue_vue_type_script_setup_true_lang-CT0J0vij.js → WidgetSelect.vue_vue_type_script_setup_true_lang-DnNAGP6n.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetSelect.vue_vue_type_script_setup_true_lang-CT0J0vij.js.map → WidgetSelect.vue_vue_type_script_setup_true_lang-DnNAGP6n.js.map} +1 -1
- comfyui_frontend_package/static/assets/{WidgetTextarea-SHMM72Cj.js → WidgetTextarea-DtdgdYZv.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetTextarea-SHMM72Cj.js.map → WidgetTextarea-DtdgdYZv.js.map} +1 -1
- comfyui_frontend_package/static/assets/{WidgetToggleSwitch-BmT1MQCn.js → WidgetToggleSwitch-BZnc8nGp.js} +2 -2
- comfyui_frontend_package/static/assets/{WidgetToggleSwitch-BmT1MQCn.js.map → WidgetToggleSwitch-BZnc8nGp.js.map} +1 -1
- comfyui_frontend_package/static/assets/{WidgetWithControl.vue_vue_type_script_setup_true_lang-CTEGWC4h.js → WidgetWithControl.vue_vue_type_script_setup_true_lang-39lKeCWN.js} +3 -3
- comfyui_frontend_package/static/assets/{WidgetWithControl.vue_vue_type_script_setup_true_lang-CTEGWC4h.js.map → WidgetWithControl.vue_vue_type_script_setup_true_lang-39lKeCWN.js.map} +1 -1
- comfyui_frontend_package/static/assets/{audioService-BcbrJBnn.js → audioService-CxmGtl4K.js} +2 -2
- comfyui_frontend_package/static/assets/{audioService-BcbrJBnn.js.map → audioService-CxmGtl4K.js.map} +1 -1
- comfyui_frontend_package/static/assets/{audioUtils-CJCA0wCG.js → audioUtils-B4fAuqez.js} +2 -2
- comfyui_frontend_package/static/assets/{audioUtils-CJCA0wCG.js.map → audioUtils-B4fAuqez.js.map} +1 -1
- comfyui_frontend_package/static/assets/commands-DHxq3nWN.js +2 -0
- comfyui_frontend_package/static/assets/commands-DHxq3nWN.js.map +1 -0
- comfyui_frontend_package/static/assets/{index-kQCr6fgp.js → index-B7ehZHKU.js} +2 -2
- comfyui_frontend_package/static/assets/{index-kQCr6fgp.js.map → index-B7ehZHKU.js.map} +1 -1
- comfyui_frontend_package/static/assets/{index-DvCHS_f2.js → index-BFHZsBkN.js} +25 -25
- comfyui_frontend_package/static/assets/index-BFHZsBkN.js.map +1 -0
- comfyui_frontend_package/static/assets/index-DJa4hQi7.css +1 -0
- comfyui_frontend_package/static/assets/index-tImAQKwZ.js +5 -0
- comfyui_frontend_package/static/assets/index-tImAQKwZ.js.map +1 -0
- comfyui_frontend_package/static/assets/{keybindingService-D3pQ4cJG.js → keybindingService-B_cUhEnt.js} +2 -2
- comfyui_frontend_package/static/assets/{keybindingService-D3pQ4cJG.js.map → keybindingService-B_cUhEnt.js.map} +1 -1
- comfyui_frontend_package/static/assets/{main-BFC5CmrY.js → main-B3vd7GL1.js} +3 -3
- comfyui_frontend_package/static/assets/main-B3vd7GL1.js.map +1 -0
- comfyui_frontend_package/static/assets/{main-M4YqFlAB.js → main-BKCc2TkD.js} +3 -3
- comfyui_frontend_package/static/assets/main-BKCc2TkD.js.map +1 -0
- comfyui_frontend_package/static/assets/{main-C0iYASPd.js → main-BNvzUx74.js} +3 -3
- comfyui_frontend_package/static/assets/main-BNvzUx74.js.map +1 -0
- comfyui_frontend_package/static/assets/main-BPu7av80.js +17 -0
- comfyui_frontend_package/static/assets/main-BPu7av80.js.map +1 -0
- comfyui_frontend_package/static/assets/{main-Dd3BY3MO.js → main-BQ4z0Xxc.js} +2 -2
- comfyui_frontend_package/static/assets/main-BQ4z0Xxc.js.map +1 -0
- comfyui_frontend_package/static/assets/{main-BI-3llij.js → main-BoyaoV4J.js} +2 -2
- comfyui_frontend_package/static/assets/main-BoyaoV4J.js.map +1 -0
- comfyui_frontend_package/static/assets/{main-DB30B6rY.js → main-CJ1ZmTbz.js} +3 -3
- comfyui_frontend_package/static/assets/main-CJ1ZmTbz.js.map +1 -0
- comfyui_frontend_package/static/assets/{main-D8hMMX5u.js → main-DxByB8u3.js} +2 -2
- comfyui_frontend_package/static/assets/main-DxByB8u3.js.map +1 -0
- comfyui_frontend_package/static/assets/{main-BdVq5c-Q.js → main-Dyk43SJi.js} +2 -2
- comfyui_frontend_package/static/assets/main-Dyk43SJi.js.map +1 -0
- comfyui_frontend_package/static/assets/{main-Cte3FX_T.js → main-QMLeyFJQ.js} +3 -3
- comfyui_frontend_package/static/assets/main-QMLeyFJQ.js.map +1 -0
- comfyui_frontend_package/static/assets/{main-BPVbVwRz.js → main-f7MqrMkx.js} +3 -3
- comfyui_frontend_package/static/assets/main-f7MqrMkx.js.map +1 -0
- comfyui_frontend_package/static/assets/nodeDefs-CqPqVYqF.js +54 -0
- comfyui_frontend_package/static/assets/nodeDefs-CqPqVYqF.js.map +1 -0
- comfyui_frontend_package/static/assets/settings-BDcsAddA.js +6 -0
- comfyui_frontend_package/static/assets/settings-BDcsAddA.js.map +1 -0
- comfyui_frontend_package/static/assets/settings-BscQZApb.js +6 -0
- comfyui_frontend_package/static/assets/settings-BscQZApb.js.map +1 -0
- comfyui_frontend_package/static/assets/settings-BxGvSZQt.js +6 -0
- comfyui_frontend_package/static/assets/settings-BxGvSZQt.js.map +1 -0
- comfyui_frontend_package/static/assets/settings-CRbIyGOx.js +6 -0
- comfyui_frontend_package/static/assets/settings-CRbIyGOx.js.map +1 -0
- comfyui_frontend_package/static/assets/settings-C_M95LcR.js +6 -0
- comfyui_frontend_package/static/assets/settings-C_M95LcR.js.map +1 -0
- comfyui_frontend_package/static/assets/{settings-C83z84hb.js → settings-CfAtcjYG.js} +3 -3
- comfyui_frontend_package/static/assets/settings-CfAtcjYG.js.map +1 -0
- comfyui_frontend_package/static/assets/settings-D1FGfDLO.js +6 -0
- comfyui_frontend_package/static/assets/settings-D1FGfDLO.js.map +1 -0
- comfyui_frontend_package/static/assets/settings-DIhoSYUg.js +6 -0
- comfyui_frontend_package/static/assets/settings-DIhoSYUg.js.map +1 -0
- comfyui_frontend_package/static/assets/settings-DR935Ify.js +6 -0
- comfyui_frontend_package/static/assets/settings-DR935Ify.js.map +1 -0
- comfyui_frontend_package/static/assets/settings-DwzAhg99.js +6 -0
- comfyui_frontend_package/static/assets/settings-DwzAhg99.js.map +1 -0
- comfyui_frontend_package/static/assets/settings-ydiuzS6H.js +6 -0
- comfyui_frontend_package/static/assets/settings-ydiuzS6H.js.map +1 -0
- comfyui_frontend_package/static/assets/{vendor-primevue-Bp7MMXLP.js → vendor-primevue-DeKsC2uk.js} +2 -2
- comfyui_frontend_package/static/assets/{vendor-primevue-Bp7MMXLP.js.map → vendor-primevue-DeKsC2uk.js.map} +1 -1
- comfyui_frontend_package/static/index.html +1 -1
- {comfyui_frontend_package-1.37.9.dist-info → comfyui_frontend_package-1.37.11.dist-info}/METADATA +1 -1
- {comfyui_frontend_package-1.37.9.dist-info → comfyui_frontend_package-1.37.11.dist-info}/RECORD +138 -130
- comfyui_frontend_package/static/assets/GraphView-BZLpyVMl.css +0 -1
- comfyui_frontend_package/static/assets/GraphView-C35zkdNN.js +0 -15
- comfyui_frontend_package/static/assets/GraphView-C35zkdNN.js.map +0 -1
- comfyui_frontend_package/static/assets/LazyImage.vue_vue_type_script_setup_true_lang-C58MdJKR.js +0 -2
- comfyui_frontend_package/static/assets/LazyImage.vue_vue_type_script_setup_true_lang-C58MdJKR.js.map +0 -1
- comfyui_frontend_package/static/assets/Load3D-BAJ3yM4D.js.map +0 -1
- comfyui_frontend_package/static/assets/SubscriptionRequiredDialogContent-BJ80blC4.css +0 -1
- comfyui_frontend_package/static/assets/SubscriptionRequiredDialogContent-CDaF1jns.js +0 -2
- comfyui_frontend_package/static/assets/WidgetInputNumber-Cnhf4Ann.js +0 -2
- comfyui_frontend_package/static/assets/WidgetInputNumber-Cnhf4Ann.js.map +0 -1
- comfyui_frontend_package/static/assets/WidgetLegacy-AkIJRd8v.js +0 -2
- comfyui_frontend_package/static/assets/WidgetLegacy-AkIJRd8v.js.map +0 -1
- comfyui_frontend_package/static/assets/WidgetMarkdown-voa7Ohgp.js +0 -2
- comfyui_frontend_package/static/assets/WidgetRecordAudio-DelweXYm.js +0 -2
- comfyui_frontend_package/static/assets/WidgetRecordAudio-DelweXYm.js.map +0 -1
- comfyui_frontend_package/static/assets/WidgetSelect-XG4R8CnZ.js +0 -2
- comfyui_frontend_package/static/assets/WidgetSelect-XG4R8CnZ.js.map +0 -1
- comfyui_frontend_package/static/assets/index-BB_8e12C.css +0 -1
- comfyui_frontend_package/static/assets/index-Cm0D-ExL.js +0 -5
- comfyui_frontend_package/static/assets/index-Cm0D-ExL.js.map +0 -1
- comfyui_frontend_package/static/assets/index-DvCHS_f2.js.map +0 -1
- comfyui_frontend_package/static/assets/main-BFC5CmrY.js.map +0 -1
- comfyui_frontend_package/static/assets/main-BI-3llij.js.map +0 -1
- comfyui_frontend_package/static/assets/main-BPVbVwRz.js.map +0 -1
- comfyui_frontend_package/static/assets/main-BdVq5c-Q.js.map +0 -1
- comfyui_frontend_package/static/assets/main-C0iYASPd.js.map +0 -1
- comfyui_frontend_package/static/assets/main-Cte3FX_T.js.map +0 -1
- comfyui_frontend_package/static/assets/main-D8hMMX5u.js.map +0 -1
- comfyui_frontend_package/static/assets/main-DB30B6rY.js.map +0 -1
- comfyui_frontend_package/static/assets/main-Dd3BY3MO.js.map +0 -1
- comfyui_frontend_package/static/assets/main-M4YqFlAB.js.map +0 -1
- comfyui_frontend_package/static/assets/settings-2GCqRrJG.js +0 -6
- comfyui_frontend_package/static/assets/settings-2GCqRrJG.js.map +0 -1
- comfyui_frontend_package/static/assets/settings-BwT6YspU.js +0 -6
- comfyui_frontend_package/static/assets/settings-BwT6YspU.js.map +0 -1
- comfyui_frontend_package/static/assets/settings-C83z84hb.js.map +0 -1
- comfyui_frontend_package/static/assets/settings-CpGAolL8.js +0 -6
- comfyui_frontend_package/static/assets/settings-CpGAolL8.js.map +0 -1
- comfyui_frontend_package/static/assets/settings-DHYEklkf.js +0 -6
- comfyui_frontend_package/static/assets/settings-DHYEklkf.js.map +0 -1
- comfyui_frontend_package/static/assets/settings-DLFPCNJr.js +0 -6
- comfyui_frontend_package/static/assets/settings-DLFPCNJr.js.map +0 -1
- comfyui_frontend_package/static/assets/settings-JVJwzdtf.js +0 -6
- comfyui_frontend_package/static/assets/settings-JVJwzdtf.js.map +0 -1
- comfyui_frontend_package/static/assets/settings-Tg5NBf0t.js +0 -6
- comfyui_frontend_package/static/assets/settings-Tg5NBf0t.js.map +0 -1
- comfyui_frontend_package/static/assets/settings-_tes1LYa.js +0 -6
- comfyui_frontend_package/static/assets/settings-_tes1LYa.js.map +0 -1
- comfyui_frontend_package/static/assets/settings-cav_bQJj.js +0 -6
- comfyui_frontend_package/static/assets/settings-cav_bQJj.js.map +0 -1
- {comfyui_frontend_package-1.37.9.dist-info → comfyui_frontend_package-1.37.11.dist-info}/WHEEL +0 -0
- {comfyui_frontend_package-1.37.9.dist-info → comfyui_frontend_package-1.37.11.dist-info}/top_level.txt +0 -0
comfyui_frontend_package/static/assets/LazyImage.vue_vue_type_script_setup_true_lang-C58MdJKR.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var ce=Object.defineProperty;var m=(i,e)=>ce(i,"name",{value:e,configurable:!0});import{cG as E,a as I,c as se,_ as F,k as pe,cu as me,l as fe,h as q,s as ge,u as ee,d as te,m as ve}from"./index-DvCHS_f2.js";import{b as le,E as V,a as he,bx as B,cM as O,cN as N,j as S,d,by as p,m as be,k as y,e as l,G as Z,c as g,q as _,u,p as ye,d3 as we,cw as _e,z as $,w as G,d2 as $e,eE as ke,r as x,A as D,f as re,o as Me,bg as Ue,dc as xe,cd as Se,s as X}from"./vendor-other-B8t_Wf2K.js";import{i as Ce,y as Ie,e as ne,a as Be}from"./vendor-primevue-Bp7MMXLP.js";import{u as ie}from"./vendor-vue-DaLZjKA7.js";function A(){const i=le({get supportsPreviewMetadata(){return I.getServerFeature("supports_preview_metadata")},get maxUploadSize(){return I.getServerFeature("max_upload_size")},get supportsManagerV4(){return I.getServerFeature("extension.manager.supports_v4")},get modelUploadButtonEnabled(){return E.value.model_upload_button_enabled??I.getServerFeature("model_upload_button_enabled",!1)},get assetDeletionEnabled(){return E.value.asset_deletion_enabled??I.getServerFeature("asset_deletion_enabled",!1)},get assetRenameEnabled(){return E.value.asset_rename_enabled??I.getServerFeature("asset_rename_enabled",!1)},get privateModelsEnabled(){return E.value.private_models_enabled??I.getServerFeature("private_models_enabled",!1)},get onboardingSurveyEnabled(){return E.value.onboarding_survey_enabled??I.getServerFeature("onboarding_survey_enabled",!0)},get huggingfaceModelImportEnabled(){return E.value.huggingface_model_import_enabled??I.getServerFeature("huggingface_model_import_enabled",!1)},get asyncModelUploadEnabled(){return E.value.async_model_upload_enabled??I.getServerFeature("async_model_upload_enabled",!1)}}),e=m((n,s)=>V(()=>I.getServerFeature(n,s)),"featureFlag");return{flags:he(i),featureFlag:e}}m(A,"useFeatureFlags");const Fe={class:"flex items-center gap-2 text-sm"},Ve={key:0,class:"text-base-foreground"},Le={key:1,class:"text-base-foreground"},je={class:"truncate"},Ee={key:0,class:"icon-[lucide--check] text-base-foreground"},De=B({inheritAttrs:!1,__name:"SingleSelect",props:O({label:{},options:{},listMaxHeight:{default:"28rem"},popoverMinWidth:{},popoverMaxWidth:{}},{modelValue:{required:!0},modelModifiers:{}}),emits:["update:modelValue"],setup(i){const e=N(i,"modelValue"),{t:n}=ie(),s=m(o=>{if(o==null||!i.options)return i.label??"";const a=i.options.find(r=>r.value===o);return a?a.name:i.label??""},"getLabel"),t=V(()=>{if(!i.popoverMinWidth&&!i.popoverMaxWidth)return;const o=[];return i.popoverMinWidth&&o.push(`min-width: ${i.popoverMinWidth}`),i.popoverMaxWidth&&o.push(`max-width: ${i.popoverMaxWidth}`),o.join("; ")});return(o,a)=>(d(),S(p(Ce),be({modelValue:e.value,"onUpdate:modelValue":a[0]||(a[0]=r=>e.value=r)},o.$attrs,{options:o.options,"option-label":"name","option-value":"value",unstyled:"",pt:{root:m(({props:r})=>({class:["h-10 relative inline-flex cursor-pointer select-none items-center","rounded-lg","bg-secondary-background text-base-foreground","border-[2.5px] border-solid border-transparent","transition-all duration-200 ease-in-out","focus-within:border-node-component-border",{"opacity-60 cursor-default":r.disabled}]}),"root"),label:{class:"flex-1 flex items-center whitespace-nowrap pl-4 py-2 outline-hidden"},dropdown:{class:"flex shrink-0 items-center justify-center px-3 py-2"},overlay:{class:p(se)("mt-2 p-2 rounded-lg","bg-base-background text-base-foreground","border border-solid border-border-default")},listContainer:m(()=>({style:`max-height: min(${o.listMaxHeight}, 50vh)`,class:"scrollbar-custom"}),"listContainer"),list:{class:"flex flex-col gap-0 p-0 m-0 list-none border-none text-sm"},option:m(({context:r})=>({class:p(se)("flex items-center justify-between gap-3 px-2 py-3 rounded","hover:bg-secondary-background-hover",r.focused&&"bg-secondary-background-hover",r.selected&&"bg-secondary-background-selected hover:bg-secondary-background-selected")}),"option"),optionLabel:{class:"truncate"},optionGroupLabel:{class:"px-3 py-2 text-xs uppercase tracking-wide text-muted-foreground"},emptyMessage:{class:"px-3 py-2 text-sm text-muted-foreground"}},"aria-label":o.label||p(n)("g.singleSelectDropdown"),role:"combobox","aria-expanded":!1,"aria-haspopup":"listbox",tabindex:0}),{value:y(r=>[l("div",Fe,[ye(o.$slots,"icon"),r.value!==null&&r.value!==void 0?(d(),g("span",Ve,u(s(r.value)),1)):(d(),g("span",Le,u(o.label),1))])]),dropdownicon:y(()=>a[1]||(a[1]=[l("i",{class:"icon-[lucide--chevron-down] text-muted-foreground"},null,-1)])),option:y(({option:r,selected:c})=>[l("div",{class:"flex w-full items-center justify-between gap-3",style:Z(t.value)},[l("span",je,u(r.name),1),c?(d(),g("i",Ee)):_("",!0)],4)]),_:3},16,["modelValue","options","pt","aria-label"]))}});function Ae(i){const e={loras:"LoRA",ipadapter:"IP-Adapter",sams:"SAM",clip_vision:"CLIP Vision",animatediff_motion_lora:"AnimateDiff Motion LoRA",animatediff_models:"AnimateDiff Model",vae:"VAE",sam2:"SAM 2",controlnet:"ControlNet",gligen:"GLIGEN"};return e[i]?e[i]:i.split("_").map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join(" ")}m(Ae,"formatDisplayName");const ze=["nlf"],de=we(()=>{const{state:i,isLoading:e,error:n,execute:s}=_e(async()=>(await I.getModelFolders()).filter(o=>!ze.includes(o.name)).map(o=>({name:Ae(o.name),value:o.name})).sort((o,a)=>o.name.localeCompare(a.name)),[],{immediate:!1,onError:m(t=>{console.error("Failed to fetch model types:",t)},"onError")});return{modelTypes:i,isLoading:e,error:n,fetchModelTypes:s}}),Re={class:"flex flex-col gap-4 text-sm text-muted-foreground"},Te={class:"flex flex-col gap-2"},He={class:"m-0"},Pe={class:"flex items-center gap-3 rounded-lg bg-secondary-background p-3"},qe=["src","alt"],We={class:"m-0 min-w-0 flex-1 truncate text-base-foreground"},Oe={class:"flex flex-col gap-2"},Ne={class:""},Ge={class:"flex items-center gap-2"},Ke=B({__name:"UploadModelConfirmation",props:O({metadata:{},previewImage:{}},{modelValue:{},modelModifiers:{}}),emits:["update:modelValue"],setup(i){const e=N(i,"modelValue"),{modelTypes:n,isLoading:s}=de();return(t,o)=>(d(),g("div",Re,[l("div",Te,[l("p",He,u(t.$t("assetBrowser.modelAssociatedWithLink")),1),l("div",Pe,[t.previewImage?(d(),g("img",{key:0,src:t.previewImage,alt:t.metadata?.filename||t.metadata?.name||"Model preview",class:"size-14 flex-shrink-0 rounded object-cover"},null,8,qe)):_("",!0),l("p",We,u(t.metadata?.filename||t.metadata?.name),1)])]),l("div",Oe,[l("label",Ne,u(t.$t("assetBrowser.modelTypeSelectorLabel")),1),$(De,{modelValue:e.value,"onUpdate:modelValue":o[0]||(o[0]=a=>e.value=a),label:p(s)?t.$t("g.loading"):t.$t("assetBrowser.modelTypeSelectorPlaceholder"),options:p(n),disabled:p(s),"data-attr":"upload-model-step2-type-selector"},null,8,["modelValue","label","options","disabled"]),l("div",Ge,[o[1]||(o[1]=l("i",{class:"icon-[lucide--circle-question-mark]"},null,-1)),l("span",null,u(t.$t("assetBrowser.notSureLeaveAsIs")),1)])])]))}}),Ye={class:"relative"},Je=["aria-label","src"],oe=B({__name:"VideoHelpDialog",props:O({videoUrl:{},ariaLabel:{default:"Help video"}},{modelValue:{type:Boolean,required:!0},modelModifiers:{}}),emits:["update:modelValue"],setup(i){const e=N(i,"modelValue"),n=m(s=>{s.key==="Escape"&&(s.stopImmediatePropagation(),s.stopPropagation(),s.preventDefault(),e.value=!1)},"handleEscapeKey");return G(e,s=>{if(s){const t=$e(document,"keydown",n,{capture:!0});ke(t)}},{immediate:!0}),(s,t)=>(d(),S(p(Ie),{visible:e.value,"onUpdate:visible":t[1]||(t[1]=o=>e.value=o),modal:"",closable:!1,"close-on-escape":!1,"dismissable-mask":!0,pt:{root:{class:"video-help-dialog"},header:{class:"!hidden"},content:{class:"!p-0"},mask:{class:"!bg-black/70"}},style:{width:"90vw"}},{default:y(()=>[l("div",Ye,[$(F,{variant:"textonly",size:"icon",class:"absolute top-4 right-6 z-10","aria-label":s.$t("g.close"),onClick:t[0]||(t[0]=o=>e.value=!1)},{default:y(()=>t[2]||(t[2]=[l("i",{class:"pi pi-times text-sm"},null,-1)])),_:1},8,["aria-label"]),l("video",{autoplay:"",muted:"",loop:"","aria-label":s.ariaLabel,class:"w-full rounded-lg",src:s.videoUrl},u(s.$t("g.videoFailedToLoad")),9,Je)])]),_:1},8,["visible"]))}}),Qe={class:"flex justify-end gap-2 w-full"},Xe={key:0,class:"mr-auto flex items-center gap-2"},Ze={key:4},et={key:0,class:"icon-[lucide--loader-circle] animate-spin"},tt={key:0,class:"icon-[lucide--loader-circle] animate-spin"},at=B({__name:"UploadModelFooter",props:{currentStep:{},isFetchingMetadata:{type:Boolean},isUploading:{type:Boolean},canFetchMetadata:{type:Boolean},canUploadModel:{type:Boolean},uploadStatus:{}},emits:["back","fetchMetadata","upload","close"],setup(i,{emit:e}){const{flags:n}=A(),s=x(!1),t=x(!1),o=e;return(a,r)=>(d(),g("div",Qe,[a.currentStep===1&&p(n).huggingfaceModelImportEnabled?(d(),g("div",Xe,[r[10]||(r[10]=l("i",{class:"icon-[lucide--circle-question-mark] text-muted-foreground"},null,-1)),$(F,{variant:"muted-textonly",size:"sm","data-attr":"upload-model-step1-help-civitai",onClick:r[0]||(r[0]=c=>s.value=!0)},{default:y(()=>[D(u(a.$t("assetBrowser.providerCivitai")),1)]),_:1}),$(F,{variant:"muted-textonly",size:"sm","data-attr":"upload-model-step1-help-huggingface",onClick:r[1]||(r[1]=c=>t.value=!0)},{default:y(()=>[D(u(a.$t("assetBrowser.providerHuggingFace")),1)]),_:1})])):a.currentStep===1?(d(),S(F,{key:1,variant:"muted-textonly",size:"lg",class:"mr-auto underline","data-attr":"upload-model-step1-help-link",onClick:r[2]||(r[2]=c=>s.value=!0)},{default:y(()=>[r[11]||(r[11]=l("i",{class:"icon-[lucide--circle-question-mark]"},null,-1)),l("span",null,u(a.$t("assetBrowser.uploadModelHowDoIFindThis")),1)]),_:1})):_("",!0),a.currentStep===1?(d(),S(F,{key:2,variant:"muted-textonly",size:"lg","data-attr":"upload-model-step1-cancel-button",disabled:a.isFetchingMetadata||a.isUploading,onClick:r[3]||(r[3]=c=>o("close"))},{default:y(()=>[D(u(a.$t("g.cancel")),1)]),_:1},8,["disabled"])):_("",!0),a.currentStep!==1&&a.currentStep!==3?(d(),S(F,{key:3,variant:"muted-textonly",size:"lg","data-attr":`upload-model-step${a.currentStep}-back-button`,disabled:a.isFetchingMetadata||a.isUploading,onClick:r[4]||(r[4]=c=>o("back"))},{default:y(()=>[D(u(a.$t("g.back")),1)]),_:1},8,["data-attr","disabled"])):(d(),g("span",Ze)),a.currentStep===1?(d(),S(F,{key:5,variant:"secondary",size:"lg","data-attr":"upload-model-step1-continue-button",disabled:!a.canFetchMetadata||a.isFetchingMetadata,onClick:r[5]||(r[5]=c=>o("fetchMetadata"))},{default:y(()=>[a.isFetchingMetadata?(d(),g("i",et)):_("",!0),l("span",null,u(a.$t("g.continue")),1)]),_:1},8,["disabled"])):a.currentStep===2?(d(),S(F,{key:6,variant:"secondary",size:"lg","data-attr":"upload-model-step2-confirm-button",disabled:!a.canUploadModel||a.isUploading,onClick:r[6]||(r[6]=c=>o("upload"))},{default:y(()=>[a.isUploading?(d(),g("i",tt)):_("",!0),l("span",null,u(a.$t("assetBrowser.upload")),1)]),_:1},8,["disabled"])):a.currentStep===3&&(a.uploadStatus==="success"||a.uploadStatus==="processing")?(d(),S(F,{key:7,variant:"secondary","data-attr":"upload-model-step3-finish-button",onClick:r[7]||(r[7]=c=>o("close"))},{default:y(()=>[D(u(a.uploadStatus==="processing"?a.$t("g.close"):a.$t("assetBrowser.finish")),1)]),_:1})):_("",!0),$(oe,{modelValue:s.value,"onUpdate:modelValue":r[8]||(r[8]=c=>s.value=c),"video-url":"https://media.comfy.org/compressed_768/civitai_howto.webm","aria-label":a.$t("assetBrowser.uploadModelHelpVideo")},null,8,["modelValue","aria-label"]),$(oe,{modelValue:t.value,"onUpdate:modelValue":r[9]||(r[9]=c=>t.value=c),"video-url":"https://media.comfy.org/byom/huggingfacehowto.mp4","aria-label":a.$t("assetBrowser.uploadModelHelpVideo")},null,8,["modelValue","aria-label"])]))}}),st={class:"flex flex-1 flex-col gap-6 text-sm text-muted-foreground"},ot={key:0,class:"flex flex-col gap-2"},lt={class:"m-0 font-bold"},rt={class:"m-0"},nt={class:"flex flex-row items-center gap-3 rounded-lg bg-modal-card-background p-4"},it=["src","alt"],dt={class:"flex min-w-0 flex-1 flex-col items-start justify-center gap-1"},ut={class:"m-0 w-full truncate text-base-foreground"},ct={class:"m-0 text-sm text-muted"},pt={key:1,class:"flex flex-col gap-2"},mt={class:"m-0 font-bold"},ft={class:"m-0"},gt={class:"flex flex-row items-center gap-3 rounded-lg bg-modal-card-background p-4"},vt=["src","alt"],ht={class:"flex min-w-0 flex-1 flex-col items-start justify-center gap-1"},bt={class:"m-0 w-full truncate text-base-foreground"},yt={class:"m-0 text-sm text-muted"},wt={key:2,class:"flex flex-1 flex-col items-center justify-center gap-6"},_t={class:"text-center"},$t={class:"m-0 text-sm font-bold"},kt={key:0,class:"text-sm text-muted mb-0"},Mt=B({__name:"UploadModelProgress",props:{result:{},error:{},metadata:{},modelType:{},previewImage:{}},setup(i){return(e,n)=>(d(),g("div",st,[e.result==="processing"?(d(),g("div",ot,[l("p",lt,u(e.$t("assetBrowser.processingModel")),1),l("p",rt,u(e.$t("assetBrowser.processingModelDescription")),1),l("div",nt,[e.previewImage?(d(),g("img",{key:0,src:e.previewImage,alt:e.metadata?.filename||e.metadata?.name||"Model preview",class:"size-14 flex-shrink-0 rounded object-cover"},null,8,it)):_("",!0),l("div",dt,[l("p",ut,u(e.metadata?.filename||e.metadata?.name),1),l("p",ct,u(e.modelType),1)])])])):e.result==="success"?(d(),g("div",pt,[l("p",mt,u(e.$t("assetBrowser.modelUploaded")),1),l("p",ft,u(e.$t("assetBrowser.findInLibrary",{type:e.modelType})),1),l("div",gt,[e.previewImage?(d(),g("img",{key:0,src:e.previewImage,alt:e.metadata?.filename||e.metadata?.name||"Model preview",class:"size-14 flex-shrink-0 rounded object-cover"},null,8,vt)):_("",!0),l("div",ht,[l("p",bt,u(e.metadata?.filename||e.metadata?.name),1),l("p",yt,u(e.modelType),1)])])])):e.result==="error"?(d(),g("div",wt,[n[0]||(n[0]=l("i",{class:"icon-[lucide--x-circle] text-6xl text-error"},null,-1)),l("div",_t,[l("p",$t,u(e.$t("assetBrowser.uploadFailed")),1),e.error?(d(),g("p",kt,u(e.error),1)):_("",!0)])])):_("",!0)]))}}),W={type:"civitai",name:"Civitai",hostnames:["civitai.com"]},ue={type:"huggingface",name:"Hugging Face",hostnames:["huggingface.co"]};function ae(i,e){try{const n=new URL(i).hostname.toLowerCase();return e.hostnames.some(s=>n===s||n.endsWith(`.${s}`))}catch{return!1}}m(ae,"validateSourceUrl");const Ut={class:"flex flex-col justify-between h-full gap-6 text-sm"},xt={class:"flex flex-col gap-6"},St={class:"flex flex-col gap-2"},Ct={class:"m-0 text-foreground"},It={class:"m-0"},Bt={class:"m-0 text-muted-foreground"},Ft={class:"inline-flex items-center gap-1 flex-wrap mt-2"},Vt={class:"inline-flex items-center gap-1"},Lt=["alt"],jt={class:"inline-flex items-center gap-1"},Et=["alt"],Dt={class:"flex flex-col gap-2"},At={class:"relative"},zt={key:0,class:"icon-[lucide--circle-check-big] absolute top-1/2 right-3 size-5 -translate-y-1/2 text-green-500"},Rt={key:0,class:"text-xs text-error"},Tt={key:1,class:"text-foreground"},Ht={class:"font-bold italic"},Pt={class:"text-sm text-muted"},qt="/assets/images/civitai.svg",Wt="https://civitai.com/models",Ot="/assets/images/hf-logo.svg",Nt="https://huggingface.co",Gt=B({__name:"UploadModelUrlInput",props:{modelValue:{},error:{}},emits:["update:modelValue"],setup(i,{emit:e}){const{flags:n}=A(),s=i,t=e,o=V({get:m(()=>s.modelValue,"get"),set:m(c=>t("update:modelValue",c),"set")}),a=[W,ue],r=V(()=>{const c=o.value.trim();return c?a.some(w=>ae(c,w)):!1});return(c,w)=>{const k=re("i18n-t");return d(),g("div",Ut,[l("div",xt,[l("div",St,[l("p",Ct,u(c.$t("assetBrowser.uploadModelDescription1Generic")),1),l("div",It,[l("p",Bt,u(c.$t("assetBrowser.uploadModelDescription2Generic")),1),l("span",Ft,[l("span",Vt,[l("img",{src:qt,alt:c.$t("assetBrowser.providerCivitai"),class:"w-4 h-4"},null,8,Lt),l("a",{href:Wt,target:"_blank",rel:"noopener noreferrer",class:"text-muted underline"},u(c.$t("assetBrowser.providerCivitai")),1),w[1]||(w[1]=l("span",null,",",-1))]),l("span",jt,[l("img",{src:Ot,alt:c.$t("assetBrowser.providerHuggingFace"),class:"w-4 h-4"},null,8,Et),l("a",{href:Nt,target:"_blank",rel:"noopener noreferrer",class:"text-muted underline"},u(c.$t("assetBrowser.providerHuggingFace")),1)])])])]),l("div",Dt,[l("div",At,[$(p(ne),{modelValue:o.value,"onUpdate:modelValue":w[0]||(w[0]=h=>o.value=h),autofocus:"",placeholder:c.$t("assetBrowser.genericLinkPlaceholder"),class:"w-full border-0 bg-secondary-background p-4 pr-10","data-attr":"upload-model-step1-url-input"},null,8,["modelValue","placeholder"]),r.value?(d(),g("i",zt)):_("",!0)]),c.error?(d(),g("p",Rt,u(c.error),1)):p(n).asyncModelUploadEnabled?_("",!0):(d(),g("p",Tt,[$(k,{keypath:"assetBrowser.maxFileSize",tag:"span"},{size:y(()=>[l("span",Ht,u(c.$t("assetBrowser.maxFileSizeValue")),1)]),_:1})]))])]),l("div",Pt,u(c.$t("assetBrowser.uploadModelHelpFooterText")),1)])}}}),Kt={class:"flex flex-col gap-6 text-sm text-muted-foreground"},Yt={class:"flex flex-col gap-2"},Jt={class:"m-0"},Qt={class:"list-disc space-y-1 pl-5 mt-0"},Xt={href:"https://civitai.com/models",target:"_blank",class:"text-muted-foreground"},Zt={key:0},ea={class:"font-bold italic"},ta={class:"flex flex-col gap-2"},aa={class:"font-bold italic"},sa={class:"relative"},oa={key:0,class:"icon-[lucide--circle-check-big] absolute top-1/2 right-3 size-5 -translate-y-1/2 text-green-500"},la={key:0,class:"text-xs text-error"},ra={href:"https://civitai.com/models/10706/luisap-z-image-and-qwen-pixel-art-refiner?modelVersionId=2225295",target:"_blank",class:"text-muted-foreground"},na=B({__name:"UploadModelUrlInputCivitai",props:O({error:{}},{modelValue:{required:!0},modelModifiers:{}}),emits:["update:modelValue"],setup(i){const{flags:e}=A(),n=N(i,"modelValue"),s=V(()=>{const t=n.value.trim();return t?ae(t,W):!1});return(t,o)=>{const a=re("i18n-t");return d(),g("div",Kt,[l("div",Yt,[l("p",Jt,u(t.$t("assetBrowser.uploadModelDescription1")),1),l("ul",Qt,[l("li",null,[$(a,{keypath:"assetBrowser.uploadModelDescription2",tag:"span"},{link:y(()=>[l("a",Xt,u(t.$t("assetBrowser.uploadModelDescription2Link")),1)]),_:1})]),p(e).asyncModelUploadEnabled?_("",!0):(d(),g("li",Zt,[$(a,{keypath:"assetBrowser.uploadModelDescription3",tag:"span"},{size:y(()=>[l("span",ea,u(t.$t("assetBrowser.maxFileSizeValue")),1)]),_:1})]))])]),l("div",ta,[$(a,{keypath:"assetBrowser.civitaiLinkLabel",tag:"label",class:"mb-0"},{download:y(()=>[l("span",aa,u(t.$t("assetBrowser.civitaiLinkLabelDownload")),1)]),_:1}),l("div",sa,[$(p(ne),{modelValue:n.value,"onUpdate:modelValue":o[0]||(o[0]=r=>n.value=r),autofocus:"",placeholder:t.$t("assetBrowser.civitaiLinkPlaceholder"),class:"w-full border-0 bg-secondary-background p-4 pr-10","data-attr":"upload-model-step1-url-input"},null,8,["modelValue","placeholder"]),s.value?(d(),g("i",oa)):_("",!0)]),t.error?(d(),g("p",la,u(t.error),1)):(d(),S(a,{key:1,keypath:"assetBrowser.civitaiLinkExample",tag:"p",class:"text-xs"},{example:y(()=>[l("strong",null,u(t.$t("assetBrowser.civitaiLinkExampleStrong")),1)]),link:y(()=>[l("a",ra,u(t.$t("assetBrowser.civitaiLinkExampleUrl")),1)]),_:1}))])])}}});function ia(i){const{t:e}=ie(),n=pe(),s=me(),t=fe(),{flags:o}=A(),a=x(1),r=x(!1),c=x(!1),w=x(),k=x(""),h=x({url:"",name:"",tags:[]}),v=x(),M=o.huggingfaceModelImportEnabled?[W,ue]:[W],j=V(()=>{const U=h.value.url.trim();return U?M.find(b=>ae(U,b))??null:null});G(()=>h.value.url,()=>{k.value=""});const T=V(()=>h.value.url.trim().length>0),H=V(()=>!!v.value);async function K(){if(!T.value)return;let U=h.value.url.trim();try{U=new URL(encodeURI(U)).toString()}catch{}if(h.value.url=U,!j.value){const f=M.map(C=>C.name).join(", ");k.value=e("assetBrowser.unsupportedUrlSource",{sources:f});return}r.value=!0;try{const f=await q.getAssetMetadata(h.value.url);if(f.filename)try{f.filename=decodeURIComponent(f.filename)}catch{}if(f.name)try{f.name=decodeURIComponent(f.name)}catch{}if(h.value.metadata=f,h.value.name=f.filename||f.name||"",h.value.previewImage=f.preview_image,f.tags&&f.tags.length>0){h.value.tags=f.tags;const C=f.tags.find(z=>i.value.some(R=>R.value===z));C&&(v.value=C)}a.value=2}catch(f){console.error("Failed to retrieve metadata:",f),k.value=f instanceof Error?f.message:ge("assetBrowser.uploadModelFailedToRetrieveMetadata","Failed to retrieve metadata. Please check the link and try again."),a.value=1}finally{r.value=!1}}m(K,"fetchMetadata");async function Y(U){if(h.value.previewImage)try{const b=U.split(".")[0];let f="png";const C=h.value.previewImage.match(/^data:image\/([^;]+);/);return C&&(f=C[1]==="jpeg"?"jpg":C[1]),(await q.uploadAssetFromBase64({data:h.value.previewImage,name:`${b}_preview.${f}`,tags:["preview"]})).id}catch(b){console.error("Failed to upload preview image:",b);return}}m(Y,"uploadPreviewImage");async function P(){if(!v.value)return;const U=t.getAllNodeProviders(v.value);(await Promise.allSettled(U.map(f=>n.updateModelsForNodeType(f.nodeDef.name)))).forEach((f,C)=>{f.status==="rejected"&&console.error(`Failed to refresh ${U[C].nodeDef.name}:`,f.reason)})}m(P,"refreshModelCaches");async function J(){if(!H.value)return!1;const U=j.value;if(!U)return k.value=e("assetBrowser.noValidSourceDetected"),!1;c.value=!0;try{const b=v.value?["models",v.value]:["models"],f=h.value.metadata?.filename||h.value.metadata?.name||"model",C=await Y(f),z={source:U.type,source_url:h.value.url,model_type:v.value};if(o.asyncModelUploadEnabled){const R=await q.uploadAssetAsync({source_url:h.value.url,tags:b,user_metadata:z,preview_id:C});R.type==="async"&&R.task.status!=="completed"?(v.value&&s.trackDownload(R.task.task_id,v.value),w.value="processing"):(w.value="success",await P()),a.value=3}else await q.uploadAssetFromUrl({url:h.value.url,name:f,tags:b,user_metadata:z,preview_id:C}),w.value="success",await P(),a.value=3}catch(b){console.error("Failed to upload asset:",b),w.value="error",k.value=b instanceof Error?b.message:"Failed to upload model",a.value=3}finally{c.value=!1}return w.value!=="error"}m(J,"uploadModel");function Q(){a.value>1&&(a.value=a.value-1)}return m(Q,"goToPreviousStep"),{currentStep:a,isFetchingMetadata:r,isUploading:c,uploadStatus:w,uploadError:k,wizardData:h,selectedModelType:v,canFetchMetadata:T,canUploadModel:H,detectedSource:j,fetchMetadata:K,uploadModel:J,goToPreviousStep:Q}}m(ia,"useUploadModelWizard");const da={class:"upload-model-dialog flex flex-col gap-6 border-t border-border-default p-4 pt-6"},ua={class:"min-h-0 flex-auto basis-0 overflow-y-auto"},ca=B({__name:"UploadModelDialog",emits:["upload-success"],setup(i,{emit:e}){const{flags:n}=A(),s=ee(),{modelTypes:t,fetchModelTypes:o}=de(),a=e,{currentStep:r,isFetchingMetadata:c,isUploading:w,uploadStatus:k,uploadError:h,wizardData:v,selectedModelType:M,canFetchMetadata:j,canUploadModel:T,fetchMetadata:H,uploadModel:K,goToPreviousStep:Y}=ia(t);async function P(){await H()}m(P,"handleFetchMetadata");async function J(){await K()&&a("upload-success")}m(J,"handleUploadModel");function Q(){s.closeDialog({key:"upload-model"})}return m(Q,"handleClose"),Me(()=>{o()}),(U,b)=>(d(),g("div",da,[l("div",ua,[p(r)===1&&p(n).huggingfaceModelImportEnabled?(d(),S(Gt,{key:0,modelValue:p(v).url,"onUpdate:modelValue":b[0]||(b[0]=f=>p(v).url=f),error:p(h)},null,8,["modelValue","error"])):p(r)===1?(d(),S(na,{key:1,modelValue:p(v).url,"onUpdate:modelValue":b[1]||(b[1]=f=>p(v).url=f),error:p(h)},null,8,["modelValue","error"])):p(r)===2?(d(),S(Ke,{key:2,modelValue:p(M),"onUpdate:modelValue":b[2]||(b[2]=f=>Ue(M)?M.value=f:null),metadata:p(v).metadata,"preview-image":p(v).previewImage},null,8,["modelValue","metadata","preview-image"])):p(r)===3&&p(k)!=null?(d(),S(Mt,{key:3,result:p(k),error:p(h),metadata:p(v).metadata,"model-type":p(M),"preview-image":p(v).previewImage},null,8,["result","error","metadata","model-type","preview-image"])):_("",!0)]),$(at,{class:"flex-shrink-0","current-step":p(r),"is-fetching-metadata":p(c),"is-uploading":p(w),"can-fetch-metadata":p(j),"can-upload-model":p(T),"upload-status":p(k),onBack:p(Y),onFetchMetadata:P,onUpload:J,onClose:Q},null,8,["current-step","is-fetching-metadata","is-uploading","can-fetch-metadata","can-upload-model","upload-status","onBack"])]))}}),pa=te(ca,[["__scopeId","data-v-0825b930"]]),ma=""+new URL("images/civitai.svg",import.meta.url).href,fa={class:"flex items-center gap-2 p-4 font-bold"},ga={key:0,src:ma,class:"size-4"},va={class:"rounded-full bg-white px-1.5 py-0 text-xxs font-inter font-semibold uppercase text-black"},ha=B({__name:"UploadModelDialogHeader",setup(i){const{flags:e}=A(),n=V(()=>e.huggingfaceModelImportEnabled?"assetBrowser.uploadModelGeneric":"assetBrowser.uploadModelFromCivitai");return(s,t)=>(d(),g("div",fa,[p(e).huggingfaceModelImportEnabled?_("",!0):(d(),g("img",ga)),l("span",null,u(s.$t(n.value)),1),l("span",va,u(s.$t("g.beta")),1)]))}}),ba={},ya={class:"flex flex-1 flex-col items-center justify-center text-base text-muted-foreground"},wa={class:"m-0 max-w-md"};function _a(i,e){return d(),g("div",ya,[l("p",wa,u(i.$t("assetBrowser.upgradeFeatureDescription")),1)])}m(_a,"_sfc_render$1");const $a=te(ba,[["render",_a]]),ka={class:"flex flex-wrap justify-end gap-2 w-full"},Ma={href:"https://blog.comfy.org/p/comfy-cloud-new-features-and-pricing",target:"_blank",rel:"noopener noreferrer",class:"text-muted-foreground mr-auto underline flex items-center gap-2"},Ua=B({__name:"UploadModelUpgradeModalFooter",emits:["close","subscribe"],setup(i,{emit:e}){const n=e;return(s,t)=>(d(),g("div",ka,[l("a",Ma,[t[2]||(t[2]=l("i",{class:"icon-[lucide--external-link]"},null,-1)),l("span",null,u(s.$t("g.learnMore")),1)]),$(F,{variant:"textonly",onClick:t[0]||(t[0]=o=>n("close"))},{default:y(()=>[D(u(s.$t("g.close")),1)]),_:1}),$(F,{variant:"secondary",onClick:t[1]||(t[1]=o=>n("subscribe"))},{default:y(()=>[D(u(s.$t("subscription.required.subscribe")),1)]),_:1})]))}}),xa={class:"flex flex-col justify-between gap-10 p-4 border-t border-border-default w-auto max-w-[min(500px,90vw)]"},Sa=B({__name:"UploadModelUpgradeModal",setup(i){const e=ee(),{showSubscriptionDialog:n}=ve();function s(){e.closeDialog({key:"upload-model-upgrade"})}m(s,"handleClose");function t(){n()}return m(t,"handleSubscribe"),(o,a)=>(d(),g("div",xa,[$($a),$(Ua,{onClose:s,onSubscribe:t})]))}}),Ca={},Ia={class:"flex items-center gap-2 p-4 font-bold"};function Ba(i,e){return d(),g("div",Ia,[l("span",null,u(i.$t("assetBrowser.upgradeToUnlockFeature")),1)])}m(Ba,"_sfc_render");const Fa=te(Ca,[["render",Ba]]);function Wa(i){const e=ee(),{flags:n}=A(),s=V(()=>n.modelUploadButtonEnabled);function t(){n.privateModelsEnabled?e.showDialog({key:"upload-model",headerComponent:ha,component:pa,props:{onUploadSuccess:m(async()=>{await i?.()},"onUploadSuccess")},dialogComponentProps:{pt:{header:"py-0! pl-0!",content:"p-0! overflow-y-hidden!"}}}):e.showDialog({key:"upload-model-upgrade",headerComponent:Fa,component:Sa,dialogComponentProps:{pt:{header:"py-0! pl-0!",content:"p-0! overflow-y-hidden!"}}})}return m(t,"showUploadDialog"),{isUploadButtonEnabled:s,showUploadDialog:t}}m(Wa,"useModelUpload");const Va=""+new URL("images/default-template.png",import.meta.url).href;function La(i,e,n={}){const{immediate:s=!0,...t}=n,o=typeof window<"u"&&"IntersectionObserver"in window,a=x(!1);let r=null;const c=m(()=>{r&&(r.disconnect(),r=null)},"cleanup"),w=m(()=>{c(),!(!o||!i.value)&&(r=new IntersectionObserver(h=>{a.value=h.some(v=>v.isIntersecting),e(h,r)},t),r.observe(i.value))},"observe"),k=m(()=>{r&&i.value&&r.unobserve(i.value)},"unobserve");return s&&G(i,w,{immediate:!0,flush:"post"}),xe(c),{isSupported:o,isIntersecting:a,observe:w,unobserve:k,cleanup:c}}m(La,"useIntersectionObserver");class ja{static{m(this,"MediaCacheService")}cache=le(new Map);maxSize;maxAge;cleanupInterval=null;urlRefCount=new Map;constructor(e={}){this.maxSize=e.maxSize??100,this.maxAge=e.maxAge??1800*1e3,this.startCleanupInterval()}startCleanupInterval(){this.cleanupInterval=window.setInterval(()=>{this.cleanup()},300*1e3)}cleanup(){const e=Date.now(),n=[];for(const[s,t]of Array.from(this.cache.entries()))e-t.lastAccessed>this.maxAge&&(t.objectUrl?(this.urlRefCount.get(t.objectUrl)||0)===0&&(URL.revokeObjectURL(t.objectUrl),this.urlRefCount.delete(t.objectUrl),n.push(s)):n.push(s));if(n.forEach(s=>this.cache.delete(s)),this.cache.size>this.maxSize){const s=Array.from(this.cache.entries());s.sort((a,r)=>a[1].lastAccessed-r[1].lastAccessed);let t=0;const o=this.cache.size-this.maxSize;for(const[a,r]of s){if(t>=o)break;r.objectUrl?(this.urlRefCount.get(r.objectUrl)||0)===0&&(URL.revokeObjectURL(r.objectUrl),this.urlRefCount.delete(r.objectUrl),this.cache.delete(a),t++):(this.cache.delete(a),t++)}}}async getCachedMedia(e){let n=this.cache.get(e);if(n)return n.lastAccessed=Date.now(),n;n={src:e,isLoading:!0,lastAccessed:Date.now()},this.cache.set(e,n);try{const s=await fetch(e,{cache:"force-cache"});if(!s.ok)throw new Error(`Failed to fetch: ${s.status}`);const t=await s.blob(),o=URL.createObjectURL(t),a={src:e,blob:t,objectUrl:o,isLoading:!1,lastAccessed:Date.now()};return this.cache.set(e,a),a}catch(s){console.warn("Failed to cache media:",e,s);const t={src:e,error:!0,isLoading:!1,lastAccessed:Date.now()};return this.cache.set(e,t),t}}acquireUrl(e){const n=this.cache.get(e);if(n?.objectUrl){const s=this.urlRefCount.get(n.objectUrl)||0;return this.urlRefCount.set(n.objectUrl,s+1),n.objectUrl}}releaseUrl(e){const n=this.cache.get(e);if(n?.objectUrl){const s=(this.urlRefCount.get(n.objectUrl)||1)-1;s<=0?(URL.revokeObjectURL(n.objectUrl),this.urlRefCount.delete(n.objectUrl),this.cache.delete(e)):this.urlRefCount.set(n.objectUrl,s)}}clearCache(){for(const e of Array.from(this.cache.values()))e.objectUrl&&URL.revokeObjectURL(e.objectUrl);this.cache.clear(),this.urlRefCount.clear()}destroy(){this.cleanupInterval&&(clearInterval(this.cleanupInterval),this.cleanupInterval=null),this.clearCache()}}let L=null;function Ea(i){return L||(L=new ja(i)),{getCachedMedia:m(o=>L.getCachedMedia(o),"getCachedMedia"),clearCache:m(()=>L.clearCache(),"clearCache"),acquireUrl:m(o=>L.acquireUrl(o),"acquireUrl"),releaseUrl:m(o=>L.releaseUrl(o),"releaseUrl"),cache:L.cache}}m(Ea,"useMediaCache");typeof window<"u"&&window.addEventListener("beforeunload",()=>{L&&L.destroy()});const Da=["src","alt"],Aa={key:2,class:"absolute inset-0 flex items-center justify-center"},za=["alt"],Oa=B({__name:"LazyImage",props:{src:{},alt:{default:""},containerClass:{type:[Array,Object,String,Number,null,Boolean],default:""},imageClass:{type:[Array,Object,String,Number,null,Boolean],default:""},imageStyle:{},rootMargin:{default:"300px"}},setup(i){const e=x(null),n=x(!1),s=x(!1),t=x(!1),o=x(void 0),{getCachedMedia:a,acquireUrl:r,releaseUrl:c}=Ea();La(e,v=>{const M=v[0];n.value=M?.isIntersecting??!1},{rootMargin:i.rootMargin,threshold:.1});const w=V(()=>n.value);G(w,async v=>{if(v&&i.src&&!o.value&&!t.value)try{const M=await a(i.src);if(M.error)t.value=!0;else if(M.objectUrl){const j=r(i.src);o.value=j||M.objectUrl}else o.value=i.src}catch(M){console.warn("Failed to load cached media:",M),o.value=i.src}else v||(o.value?.startsWith("blob:")&&c(i.src),s.value=!1,o.value=void 0,t.value=!1)},{immediate:!0});const k=m(()=>{s.value=!0,t.value=!1},"onImageLoad"),h=m(()=>{t.value=!0,s.value=!1},"onImageError");return Se(()=>{o.value?.startsWith("blob:")&&c(i.src)}),(v,M)=>(d(),g("div",{ref_key:"containerRef",ref:e,class:X(["relative flex h-full w-full items-center justify-center overflow-hidden",v.containerClass])},[s.value?_("",!0):(d(),S(p(Be),{key:0,width:"100%",height:"100%",class:"absolute inset-0"})),o.value?(d(),g("img",{key:1,src:o.value,alt:v.alt,draggable:"false",class:X(v.imageClass),style:Z(v.imageStyle),onLoad:k,onError:h},null,46,Da)):_("",!0),t.value?(d(),g("div",Aa,[l("img",{src:Va,alt:v.alt,draggable:"false",class:X(v.imageClass),style:Z(v.imageStyle)},null,14,za)])):_("",!0)],2))}});export{De as _,Wa as a,Va as b,Oa as c,La as d,A as u};
|
|
2
|
-
//# sourceMappingURL=LazyImage.vue_vue_type_script_setup_true_lang-C58MdJKR.js.map
|
comfyui_frontend_package/static/assets/LazyImage.vue_vue_type_script_setup_true_lang-C58MdJKR.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LazyImage.vue_vue_type_script_setup_true_lang-C58MdJKR.js","sources":["../../src/composables/useFeatureFlags.ts","../../src/components/input/SingleSelect.vue","../../src/platform/assets/composables/useModelTypes.ts","../../src/platform/assets/components/UploadModelConfirmation.vue","../../src/platform/assets/components/VideoHelpDialog.vue","../../src/platform/assets/components/UploadModelFooter.vue","../../src/platform/assets/importSources/civitaiImportSource.ts","../../src/platform/assets/importSources/huggingfaceImportSource.ts","../../src/platform/assets/utils/importSourceUtil.ts","../../src/platform/assets/components/UploadModelUrlInput.vue","../../src/platform/assets/components/UploadModelUrlInputCivitai.vue","../../src/platform/assets/composables/useUploadModelWizard.ts","../../src/platform/assets/components/UploadModelDialog.vue","../../../../../../../assets/images/civitai.svg","../../src/platform/assets/components/UploadModelDialogHeader.vue","../../src/platform/assets/components/UploadModelUpgradeModalBody.vue","../../src/platform/assets/components/UploadModelUpgradeModalFooter.vue","../../src/platform/assets/components/UploadModelUpgradeModal.vue","../../src/platform/assets/components/UploadModelUpgradeModalHeader.vue","../../src/platform/assets/composables/useModelUpload.ts","../../../../../../../assets/images/default-template.png","../../src/composables/useIntersectionObserver.ts","../../src/services/mediaCacheService.ts","../../src/components/common/LazyImage.vue"],"sourcesContent":["import { computed, reactive, readonly } from 'vue'\n\nimport { remoteConfig } from '@/platform/remoteConfig/remoteConfig'\nimport { api } from '@/scripts/api'\n\n/**\n * Known server feature flags (top-level, not extensions)\n */\nexport enum ServerFeatureFlag {\n SUPPORTS_PREVIEW_METADATA = 'supports_preview_metadata',\n MAX_UPLOAD_SIZE = 'max_upload_size',\n MANAGER_SUPPORTS_V4 = 'extension.manager.supports_v4',\n MODEL_UPLOAD_BUTTON_ENABLED = 'model_upload_button_enabled',\n ASSET_DELETION_ENABLED = 'asset_deletion_enabled',\n ASSET_RENAME_ENABLED = 'asset_rename_enabled',\n PRIVATE_MODELS_ENABLED = 'private_models_enabled',\n ONBOARDING_SURVEY_ENABLED = 'onboarding_survey_enabled',\n HUGGINGFACE_MODEL_IMPORT_ENABLED = 'huggingface_model_import_enabled',\n ASYNC_MODEL_UPLOAD_ENABLED = 'async_model_upload_enabled'\n}\n\n/**\n * Composable for reactive access to server-side feature flags\n */\nexport function useFeatureFlags() {\n const flags = reactive({\n get supportsPreviewMetadata() {\n return api.getServerFeature(ServerFeatureFlag.SUPPORTS_PREVIEW_METADATA)\n },\n get maxUploadSize() {\n return api.getServerFeature(ServerFeatureFlag.MAX_UPLOAD_SIZE)\n },\n get supportsManagerV4() {\n return api.getServerFeature(ServerFeatureFlag.MANAGER_SUPPORTS_V4)\n },\n get modelUploadButtonEnabled() {\n // Check remote config first (from /api/features), fall back to websocket feature flags\n return (\n remoteConfig.value.model_upload_button_enabled ??\n api.getServerFeature(\n ServerFeatureFlag.MODEL_UPLOAD_BUTTON_ENABLED,\n false\n )\n )\n },\n get assetDeletionEnabled() {\n return (\n remoteConfig.value.asset_deletion_enabled ??\n api.getServerFeature(ServerFeatureFlag.ASSET_DELETION_ENABLED, false)\n )\n },\n get assetRenameEnabled() {\n return (\n remoteConfig.value.asset_rename_enabled ??\n api.getServerFeature(ServerFeatureFlag.ASSET_RENAME_ENABLED, false)\n )\n },\n get privateModelsEnabled() {\n // Check remote config first (from /api/features), fall back to websocket feature flags\n return (\n remoteConfig.value.private_models_enabled ??\n api.getServerFeature(ServerFeatureFlag.PRIVATE_MODELS_ENABLED, false)\n )\n },\n get onboardingSurveyEnabled() {\n return (\n remoteConfig.value.onboarding_survey_enabled ??\n api.getServerFeature(ServerFeatureFlag.ONBOARDING_SURVEY_ENABLED, true)\n )\n },\n get huggingfaceModelImportEnabled() {\n return (\n remoteConfig.value.huggingface_model_import_enabled ??\n api.getServerFeature(\n ServerFeatureFlag.HUGGINGFACE_MODEL_IMPORT_ENABLED,\n false\n )\n )\n },\n get asyncModelUploadEnabled() {\n return (\n remoteConfig.value.async_model_upload_enabled ??\n api.getServerFeature(\n ServerFeatureFlag.ASYNC_MODEL_UPLOAD_ENABLED,\n false\n )\n )\n }\n })\n\n const featureFlag = <T = unknown>(featurePath: string, defaultValue?: T) =>\n computed(() => api.getServerFeature(featurePath, defaultValue))\n\n return {\n flags: readonly(flags),\n featureFlag\n }\n}\n","<template>\n <!--\n Note: We explicitly pass options here (not just via $attrs) because:\n 1. Our custom value template needs options to look up labels from values\n 2. PrimeVue's value slot only provides 'value' and 'placeholder', not the selected item's label\n 3. We need to maintain the icon slot functionality in the value template\n option-label=\"name\" is required because our option template directly accesses option.name\n -->\n <Select\n v-model=\"selectedItem\"\n v-bind=\"$attrs\"\n :options=\"options\"\n option-label=\"name\"\n option-value=\"value\"\n unstyled\n :pt=\"{\n root: ({ props }: SelectPassThroughMethodOptions<SelectOption>) => ({\n class: [\n // container\n 'h-10 relative inline-flex cursor-pointer select-none items-center',\n // trigger surface\n 'rounded-lg',\n 'bg-secondary-background text-base-foreground',\n 'border-[2.5px] border-solid border-transparent',\n 'transition-all duration-200 ease-in-out',\n 'focus-within:border-node-component-border',\n // disabled\n { 'opacity-60 cursor-default': props.disabled }\n ]\n }),\n label: {\n class:\n // Align with MultiSelect labelContainer spacing\n 'flex-1 flex items-center whitespace-nowrap pl-4 py-2 outline-hidden'\n },\n dropdown: {\n class:\n // Right chevron touch area\n 'flex shrink-0 items-center justify-center px-3 py-2'\n },\n overlay: {\n class: cn(\n 'mt-2 p-2 rounded-lg',\n 'bg-base-background text-base-foreground',\n 'border border-solid border-border-default'\n )\n },\n listContainer: () => ({\n style: `max-height: min(${listMaxHeight}, 50vh)`,\n class: 'scrollbar-custom'\n }),\n list: {\n class:\n // Same list tone/size as MultiSelect\n 'flex flex-col gap-0 p-0 m-0 list-none border-none text-sm'\n },\n option: ({ context }: SelectPassThroughMethodOptions<SelectOption>) => ({\n class: cn(\n // Row layout\n 'flex items-center justify-between gap-3 px-2 py-3 rounded',\n 'hover:bg-secondary-background-hover',\n // Add focus state for keyboard navigation\n context.focused && 'bg-secondary-background-hover',\n // Selected state + check icon\n context.selected &&\n 'bg-secondary-background-selected hover:bg-secondary-background-selected'\n )\n }),\n optionLabel: {\n class: 'truncate'\n },\n optionGroupLabel: {\n class: 'px-3 py-2 text-xs uppercase tracking-wide text-muted-foreground'\n },\n emptyMessage: {\n class: 'px-3 py-2 text-sm text-muted-foreground'\n }\n }\"\n :aria-label=\"label || t('g.singleSelectDropdown')\"\n role=\"combobox\"\n :aria-expanded=\"false\"\n aria-haspopup=\"listbox\"\n :tabindex=\"0\"\n >\n <!-- Trigger value -->\n <template #value=\"slotProps\">\n <div class=\"flex items-center gap-2 text-sm\">\n <slot name=\"icon\" />\n <span\n v-if=\"slotProps.value !== null && slotProps.value !== undefined\"\n class=\"text-base-foreground\"\n >\n {{ getLabel(slotProps.value) }}\n </span>\n <span v-else class=\"text-base-foreground\">\n {{ label }}\n </span>\n </div>\n </template>\n\n <!-- Trigger caret -->\n <template #dropdownicon>\n <i class=\"icon-[lucide--chevron-down] text-muted-foreground\" />\n </template>\n\n <!-- Option row -->\n <template #option=\"{ option, selected }\">\n <div\n class=\"flex w-full items-center justify-between gap-3\"\n :style=\"optionStyle\"\n >\n <span class=\"truncate\">{{ option.name }}</span>\n <i v-if=\"selected\" class=\"icon-[lucide--check] text-base-foreground\" />\n </div>\n </template>\n </Select>\n</template>\n\n<script setup lang=\"ts\">\nimport type { SelectPassThroughMethodOptions } from 'primevue/select'\nimport Select from 'primevue/select'\nimport { computed } from 'vue'\nimport { useI18n } from 'vue-i18n'\n\nimport { cn } from '@/utils/tailwindUtil'\n\nimport type { SelectOption } from './types'\n\ndefineOptions({\n inheritAttrs: false\n})\n\nconst {\n label,\n options,\n listMaxHeight = '28rem',\n popoverMinWidth,\n popoverMaxWidth\n} = defineProps<{\n label?: string\n /**\n * Required for displaying the selected item's label.\n * Cannot rely on $attrs alone because we need to access options\n * in getLabel() to map values to their display names.\n */\n options?: SelectOption[]\n /** Maximum height of the dropdown panel (default: 28rem) */\n listMaxHeight?: string\n /** Minimum width of the popover (default: auto) */\n popoverMinWidth?: string\n /** Maximum width of the popover (default: auto) */\n popoverMaxWidth?: string\n}>()\n\nconst selectedItem = defineModel<string | undefined>({ required: true })\n\nconst { t } = useI18n()\n\n/**\n * Maps a value to its display label.\n * Necessary because PrimeVue's value slot doesn't provide the selected item's label,\n * only the raw value. We need this to show the correct text when an item is selected.\n */\nconst getLabel = (val: string | null | undefined) => {\n if (val == null) return label ?? ''\n if (!options) return label ?? ''\n const found = options.find((o) => o.value === val)\n return found ? found.name : (label ?? '')\n}\n\n// Extract complex style logic from template\nconst optionStyle = computed(() => {\n if (!popoverMinWidth && !popoverMaxWidth) return undefined\n\n const styles: string[] = []\n if (popoverMinWidth) styles.push(`min-width: ${popoverMinWidth}`)\n if (popoverMaxWidth) styles.push(`max-width: ${popoverMaxWidth}`)\n\n return styles.join('; ')\n})\n</script>\n","import { createSharedComposable, useAsyncState } from '@vueuse/core'\n\nimport { api } from '@/scripts/api'\n\n/**\n * Format folder name to display name\n * Converts \"upscale_models\" -> \"Upscale Model\"\n * Converts \"loras\" -> \"LoRA\"\n */\nfunction formatDisplayName(folderName: string): string {\n // Special cases for acronyms and proper nouns\n const specialCases: Record<string, string> = {\n loras: 'LoRA',\n ipadapter: 'IP-Adapter',\n sams: 'SAM',\n clip_vision: 'CLIP Vision',\n animatediff_motion_lora: 'AnimateDiff Motion LoRA',\n animatediff_models: 'AnimateDiff Model',\n vae: 'VAE',\n sam2: 'SAM 2',\n controlnet: 'ControlNet',\n gligen: 'GLIGEN'\n }\n\n if (specialCases[folderName]) {\n return specialCases[folderName]\n }\n\n return folderName\n .split('_')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ')\n}\n\ninterface ModelTypeOption {\n name: string // Display name\n value: string // Actual tag value\n}\n\nconst DISALLOWED_MODEL_TYPES = ['nlf'] as const\n\n/**\n * Composable for fetching and managing model types from the API\n * Uses shared state to ensure data is only fetched once\n */\nexport const useModelTypes = createSharedComposable(() => {\n const {\n state: modelTypes,\n isLoading,\n error,\n execute: fetchModelTypes\n } = useAsyncState(\n async (): Promise<ModelTypeOption[]> => {\n const response = await api.getModelFolders()\n return response\n .filter(\n (folder) =>\n !DISALLOWED_MODEL_TYPES.includes(\n folder.name as (typeof DISALLOWED_MODEL_TYPES)[number]\n )\n )\n .map((folder) => ({\n name: formatDisplayName(folder.name),\n value: folder.name\n }))\n .sort((a, b) => a.name.localeCompare(b.name))\n },\n [] as ModelTypeOption[],\n {\n immediate: false,\n onError: (err) => {\n console.error('Failed to fetch model types:', err)\n }\n }\n )\n\n return {\n modelTypes,\n isLoading,\n error,\n fetchModelTypes\n }\n})\n","<template>\n <div class=\"flex flex-col gap-4 text-sm text-muted-foreground\">\n <div class=\"flex flex-col gap-2\">\n <p class=\"m-0\">\n {{ $t('assetBrowser.modelAssociatedWithLink') }}\n </p>\n <div\n class=\"flex items-center gap-3 rounded-lg bg-secondary-background p-3\"\n >\n <img\n v-if=\"previewImage\"\n :src=\"previewImage\"\n :alt=\"metadata?.filename || metadata?.name || 'Model preview'\"\n class=\"size-14 flex-shrink-0 rounded object-cover\"\n />\n <p class=\"m-0 min-w-0 flex-1 truncate text-base-foreground\">\n {{ metadata?.filename || metadata?.name }}\n </p>\n </div>\n </div>\n\n <!-- Model Type Selection -->\n <div class=\"flex flex-col gap-2\">\n <label class=\"\">\n {{ $t('assetBrowser.modelTypeSelectorLabel') }}\n </label>\n <SingleSelect\n v-model=\"modelValue\"\n :label=\"\n isLoading\n ? $t('g.loading')\n : $t('assetBrowser.modelTypeSelectorPlaceholder')\n \"\n :options=\"modelTypes\"\n :disabled=\"isLoading\"\n data-attr=\"upload-model-step2-type-selector\"\n />\n <div class=\"flex items-center gap-2\">\n <i class=\"icon-[lucide--circle-question-mark]\" />\n <span>{{ $t('assetBrowser.notSureLeaveAsIs') }}</span>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport SingleSelect from '@/components/input/SingleSelect.vue'\nimport { useModelTypes } from '@/platform/assets/composables/useModelTypes'\nimport type { AssetMetadata } from '@/platform/assets/schemas/assetSchema'\n\ndefineProps<{\n metadata?: AssetMetadata\n previewImage?: string\n}>()\n\nconst modelValue = defineModel<string | undefined>()\n\nconst { modelTypes, isLoading } = useModelTypes()\n</script>\n","<template>\n <Dialog\n v-model:visible=\"isVisible\"\n modal\n :closable=\"false\"\n :close-on-escape=\"false\"\n :dismissable-mask=\"true\"\n :pt=\"{\n root: { class: 'video-help-dialog' },\n header: { class: '!hidden' },\n content: { class: '!p-0' },\n mask: { class: '!bg-black/70' }\n }\"\n :style=\"{ width: '90vw' }\"\n >\n <div class=\"relative\">\n <Button\n variant=\"textonly\"\n size=\"icon\"\n class=\"absolute top-4 right-6 z-10\"\n :aria-label=\"$t('g.close')\"\n @click=\"isVisible = false\"\n >\n <i class=\"pi pi-times text-sm\" />\n </Button>\n <video\n autoplay\n muted\n loop\n :aria-label=\"ariaLabel\"\n class=\"w-full rounded-lg\"\n :src=\"videoUrl\"\n >\n {{ $t('g.videoFailedToLoad') }}\n </video>\n </div>\n </Dialog>\n</template>\n\n<script setup lang=\"ts\">\nimport { useEventListener } from '@vueuse/core'\nimport Dialog from 'primevue/dialog'\nimport { onWatcherCleanup, watch } from 'vue'\n\nimport Button from '@/components/ui/button/Button.vue'\n\nconst isVisible = defineModel<boolean>({ required: true })\n\nconst { videoUrl, ariaLabel = 'Help video' } = defineProps<{\n videoUrl: string\n ariaLabel?: string\n}>()\n\nconst handleEscapeKey = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n event.stopImmediatePropagation()\n event.stopPropagation()\n event.preventDefault()\n isVisible.value = false\n }\n}\n\n// Add listener with capture phase to intercept before parent dialogs\n// Only active when dialog is visible\nwatch(\n isVisible,\n (visible) => {\n if (visible) {\n const stop = useEventListener(document, 'keydown', handleEscapeKey, {\n capture: true\n })\n onWatcherCleanup(stop)\n }\n },\n { immediate: true }\n)\n</script>\n","<template>\n <div class=\"flex justify-end gap-2 w-full\">\n <div\n v-if=\"currentStep === 1 && flags.huggingfaceModelImportEnabled\"\n class=\"mr-auto flex items-center gap-2\"\n >\n <i class=\"icon-[lucide--circle-question-mark] text-muted-foreground\" />\n <Button\n variant=\"muted-textonly\"\n size=\"sm\"\n data-attr=\"upload-model-step1-help-civitai\"\n @click=\"showCivitaiHelp = true\"\n >\n {{ $t('assetBrowser.providerCivitai') }}\n </Button>\n <Button\n variant=\"muted-textonly\"\n size=\"sm\"\n data-attr=\"upload-model-step1-help-huggingface\"\n @click=\"showHuggingFaceHelp = true\"\n >\n {{ $t('assetBrowser.providerHuggingFace') }}\n </Button>\n </div>\n <Button\n v-else-if=\"currentStep === 1\"\n variant=\"muted-textonly\"\n size=\"lg\"\n class=\"mr-auto underline\"\n data-attr=\"upload-model-step1-help-link\"\n @click=\"showCivitaiHelp = true\"\n >\n <i class=\"icon-[lucide--circle-question-mark]\" />\n <span>{{ $t('assetBrowser.uploadModelHowDoIFindThis') }}</span>\n </Button>\n <Button\n v-if=\"currentStep === 1\"\n variant=\"muted-textonly\"\n size=\"lg\"\n data-attr=\"upload-model-step1-cancel-button\"\n :disabled=\"isFetchingMetadata || isUploading\"\n @click=\"emit('close')\"\n >\n {{ $t('g.cancel') }}\n </Button>\n <Button\n v-if=\"currentStep !== 1 && currentStep !== 3\"\n variant=\"muted-textonly\"\n size=\"lg\"\n :data-attr=\"`upload-model-step${currentStep}-back-button`\"\n :disabled=\"isFetchingMetadata || isUploading\"\n @click=\"emit('back')\"\n >\n {{ $t('g.back') }}\n </Button>\n <span v-else />\n\n <Button\n v-if=\"currentStep === 1\"\n variant=\"secondary\"\n size=\"lg\"\n data-attr=\"upload-model-step1-continue-button\"\n :disabled=\"!canFetchMetadata || isFetchingMetadata\"\n @click=\"emit('fetchMetadata')\"\n >\n <i\n v-if=\"isFetchingMetadata\"\n class=\"icon-[lucide--loader-circle] animate-spin\"\n />\n <span>{{ $t('g.continue') }}</span>\n </Button>\n <Button\n v-else-if=\"currentStep === 2\"\n variant=\"secondary\"\n size=\"lg\"\n data-attr=\"upload-model-step2-confirm-button\"\n :disabled=\"!canUploadModel || isUploading\"\n @click=\"emit('upload')\"\n >\n <i v-if=\"isUploading\" class=\"icon-[lucide--loader-circle] animate-spin\" />\n <span>{{ $t('assetBrowser.upload') }}</span>\n </Button>\n <Button\n v-else-if=\"\n currentStep === 3 &&\n (uploadStatus === 'success' || uploadStatus === 'processing')\n \"\n variant=\"secondary\"\n data-attr=\"upload-model-step3-finish-button\"\n @click=\"emit('close')\"\n >\n {{\n uploadStatus === 'processing'\n ? $t('g.close')\n : $t('assetBrowser.finish')\n }}\n </Button>\n <VideoHelpDialog\n v-model=\"showCivitaiHelp\"\n video-url=\"https://media.comfy.org/compressed_768/civitai_howto.webm\"\n :aria-label=\"$t('assetBrowser.uploadModelHelpVideo')\"\n />\n <VideoHelpDialog\n v-model=\"showHuggingFaceHelp\"\n video-url=\"https://media.comfy.org/byom/huggingfacehowto.mp4\"\n :aria-label=\"$t('assetBrowser.uploadModelHelpVideo')\"\n />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue'\n\nimport Button from '@/components/ui/button/Button.vue'\nimport { useFeatureFlags } from '@/composables/useFeatureFlags'\nimport VideoHelpDialog from '@/platform/assets/components/VideoHelpDialog.vue'\n\nconst { flags } = useFeatureFlags()\n\nconst showCivitaiHelp = ref(false)\nconst showHuggingFaceHelp = ref(false)\n\ndefineProps<{\n currentStep: number\n isFetchingMetadata: boolean\n isUploading: boolean\n canFetchMetadata: boolean\n canUploadModel: boolean\n uploadStatus?: 'processing' | 'success' | 'error'\n}>()\n\nconst emit = defineEmits<{\n (e: 'back'): void\n (e: 'fetchMetadata'): void\n (e: 'upload'): void\n (e: 'close'): void\n}>()\n</script>\n","import type { ImportSource } from '@/platform/assets/types/importSource'\n\n/**\n * Civitai model import source configuration\n */\nexport const civitaiImportSource: ImportSource = {\n type: 'civitai',\n name: 'Civitai',\n hostnames: ['civitai.com']\n}\n","import type { ImportSource } from '@/platform/assets/types/importSource'\n\n/**\n * Hugging Face model import source configuration\n */\nexport const huggingfaceImportSource: ImportSource = {\n type: 'huggingface',\n name: 'Hugging Face',\n hostnames: ['huggingface.co']\n}\n","import type { ImportSource } from '@/platform/assets/types/importSource'\n\n/**\n * Check if a URL belongs to a specific import source\n */\nexport function validateSourceUrl(url: string, source: ImportSource): boolean {\n try {\n const hostname = new URL(url).hostname.toLowerCase()\n return source.hostnames.some(\n (h) => hostname === h || hostname.endsWith(`.${h}`)\n )\n } catch {\n return false\n }\n}\n","<template>\n <div class=\"flex flex-col justify-between h-full gap-6 text-sm\">\n <div class=\"flex flex-col gap-6\">\n <div class=\"flex flex-col gap-2\">\n <p class=\"m-0 text-foreground\">\n {{ $t('assetBrowser.uploadModelDescription1Generic') }}\n </p>\n <div class=\"m-0\">\n <p class=\"m-0 text-muted-foreground\">\n {{ $t('assetBrowser.uploadModelDescription2Generic') }}\n </p>\n <span class=\"inline-flex items-center gap-1 flex-wrap mt-2\">\n <span class=\"inline-flex items-center gap-1\">\n <img\n :src=\"civitaiIcon\"\n :alt=\"$t('assetBrowser.providerCivitai')\"\n class=\"w-4 h-4\"\n />\n <a\n :href=\"civitaiUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"text-muted underline\"\n >\n {{ $t('assetBrowser.providerCivitai') }}</a\n ><span>,</span>\n </span>\n <span class=\"inline-flex items-center gap-1\">\n <img\n :src=\"huggingFaceIcon\"\n :alt=\"$t('assetBrowser.providerHuggingFace')\"\n class=\"w-4 h-4\"\n />\n <a\n :href=\"huggingFaceUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"text-muted underline\"\n >\n {{ $t('assetBrowser.providerHuggingFace') }}\n </a>\n </span>\n </span>\n </div>\n </div>\n\n <div class=\"flex flex-col gap-2\">\n <div class=\"relative\">\n <InputText\n v-model=\"url\"\n autofocus\n :placeholder=\"$t('assetBrowser.genericLinkPlaceholder')\"\n class=\"w-full border-0 bg-secondary-background p-4 pr-10\"\n data-attr=\"upload-model-step1-url-input\"\n />\n <i\n v-if=\"isValidUrl\"\n class=\"icon-[lucide--circle-check-big] absolute top-1/2 right-3 size-5 -translate-y-1/2 text-green-500\"\n />\n </div>\n <p v-if=\"error\" class=\"text-xs text-error\">\n {{ error }}\n </p>\n <p v-else-if=\"!flags.asyncModelUploadEnabled\" class=\"text-foreground\">\n <i18n-t keypath=\"assetBrowser.maxFileSize\" tag=\"span\">\n <template #size>\n <span class=\"font-bold italic\">{{\n $t('assetBrowser.maxFileSizeValue')\n }}</span>\n </template>\n </i18n-t>\n </p>\n </div>\n </div>\n\n <div class=\"text-sm text-muted\">\n {{ $t('assetBrowser.uploadModelHelpFooterText') }}\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport InputText from 'primevue/inputtext'\nimport { computed } from 'vue'\n\nimport { useFeatureFlags } from '@/composables/useFeatureFlags'\nimport { civitaiImportSource } from '@/platform/assets/importSources/civitaiImportSource'\nimport { huggingfaceImportSource } from '@/platform/assets/importSources/huggingfaceImportSource'\nimport { validateSourceUrl } from '@/platform/assets/utils/importSourceUtil'\n\nconst { flags } = useFeatureFlags()\n\nconst props = defineProps<{\n modelValue: string\n error?: string\n}>()\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string]\n}>()\n\nconst url = computed({\n get: () => props.modelValue,\n set: (value: string) => emit('update:modelValue', value)\n})\n\nconst importSources = [civitaiImportSource, huggingfaceImportSource]\n\nconst isValidUrl = computed(() => {\n const trimmedUrl = url.value.trim()\n if (!trimmedUrl) return false\n return importSources.some((source) => validateSourceUrl(trimmedUrl, source))\n})\n\nconst civitaiIcon = '/assets/images/civitai.svg'\nconst civitaiUrl = 'https://civitai.com/models'\nconst huggingFaceIcon = '/assets/images/hf-logo.svg'\nconst huggingFaceUrl = 'https://huggingface.co'\n</script>\n","<template>\n <div class=\"flex flex-col gap-6 text-sm text-muted-foreground\">\n <div class=\"flex flex-col gap-2\">\n <p class=\"m-0\">\n {{ $t('assetBrowser.uploadModelDescription1') }}\n </p>\n <ul class=\"list-disc space-y-1 pl-5 mt-0\">\n <li>\n <i18n-t keypath=\"assetBrowser.uploadModelDescription2\" tag=\"span\">\n <template #link>\n <a\n href=\"https://civitai.com/models\"\n target=\"_blank\"\n class=\"text-muted-foreground\"\n >\n {{ $t('assetBrowser.uploadModelDescription2Link') }}\n </a>\n </template>\n </i18n-t>\n </li>\n <li v-if=\"!flags.asyncModelUploadEnabled\">\n <i18n-t keypath=\"assetBrowser.uploadModelDescription3\" tag=\"span\">\n <template #size>\n <span class=\"font-bold italic\">{{\n $t('assetBrowser.maxFileSizeValue')\n }}</span>\n </template>\n </i18n-t>\n </li>\n </ul>\n </div>\n\n <div class=\"flex flex-col gap-2\">\n <i18n-t keypath=\"assetBrowser.civitaiLinkLabel\" tag=\"label\" class=\"mb-0\">\n <template #download>\n <span class=\"font-bold italic\">{{\n $t('assetBrowser.civitaiLinkLabelDownload')\n }}</span>\n </template>\n </i18n-t>\n <div class=\"relative\">\n <InputText\n v-model=\"url\"\n autofocus\n :placeholder=\"$t('assetBrowser.civitaiLinkPlaceholder')\"\n class=\"w-full border-0 bg-secondary-background p-4 pr-10\"\n data-attr=\"upload-model-step1-url-input\"\n />\n <i\n v-if=\"isValidUrl\"\n class=\"icon-[lucide--circle-check-big] absolute top-1/2 right-3 size-5 -translate-y-1/2 text-green-500\"\n />\n </div>\n <p v-if=\"error\" class=\"text-xs text-error\">\n {{ error }}\n </p>\n <i18n-t\n v-else\n keypath=\"assetBrowser.civitaiLinkExample\"\n tag=\"p\"\n class=\"text-xs\"\n >\n <template #example>\n <strong>{{ $t('assetBrowser.civitaiLinkExampleStrong') }}</strong>\n </template>\n <template #link>\n <a\n href=\"https://civitai.com/models/10706/luisap-z-image-and-qwen-pixel-art-refiner?modelVersionId=2225295\"\n target=\"_blank\"\n class=\"text-muted-foreground\"\n >\n {{ $t('assetBrowser.civitaiLinkExampleUrl') }}\n </a>\n </template>\n </i18n-t>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport InputText from 'primevue/inputtext'\nimport { computed } from 'vue'\n\nimport { useFeatureFlags } from '@/composables/useFeatureFlags'\nimport { civitaiImportSource } from '@/platform/assets/importSources/civitaiImportSource'\nimport { validateSourceUrl } from '@/platform/assets/utils/importSourceUtil'\n\nconst { flags } = useFeatureFlags()\n\ndefineProps<{\n error?: string\n}>()\n\nconst url = defineModel<string>({ required: true })\n\nconst isValidUrl = computed(() => {\n const trimmedUrl = url.value.trim()\n if (!trimmedUrl) return false\n return validateSourceUrl(trimmedUrl, civitaiImportSource)\n})\n</script>\n","import type { Ref } from 'vue'\nimport { computed, ref, watch } from 'vue'\nimport { useI18n } from 'vue-i18n'\n\nimport { useFeatureFlags } from '@/composables/useFeatureFlags'\nimport { st } from '@/i18n'\nimport { civitaiImportSource } from '@/platform/assets/importSources/civitaiImportSource'\nimport { huggingfaceImportSource } from '@/platform/assets/importSources/huggingfaceImportSource'\nimport type { AssetMetadata } from '@/platform/assets/schemas/assetSchema'\nimport { assetService } from '@/platform/assets/services/assetService'\nimport type { ImportSource } from '@/platform/assets/types/importSource'\nimport { validateSourceUrl } from '@/platform/assets/utils/importSourceUtil'\nimport { useAssetDownloadStore } from '@/stores/assetDownloadStore'\nimport { useAssetsStore } from '@/stores/assetsStore'\nimport { useModelToNodeStore } from '@/stores/modelToNodeStore'\n\ninterface WizardData {\n url: string\n metadata?: AssetMetadata\n name: string\n tags: string[]\n previewImage?: string\n}\n\ninterface ModelTypeOption {\n name: string\n value: string\n}\n\nexport function useUploadModelWizard(modelTypes: Ref<ModelTypeOption[]>) {\n const { t } = useI18n()\n const assetsStore = useAssetsStore()\n const assetDownloadStore = useAssetDownloadStore()\n const modelToNodeStore = useModelToNodeStore()\n const { flags } = useFeatureFlags()\n const currentStep = ref(1)\n const isFetchingMetadata = ref(false)\n const isUploading = ref(false)\n const uploadStatus = ref<'processing' | 'success' | 'error'>()\n const uploadError = ref('')\n\n const wizardData = ref<WizardData>({\n url: '',\n name: '',\n tags: []\n })\n\n const selectedModelType = ref<string>()\n\n // Available import sources\n const importSources: ImportSource[] = flags.huggingfaceModelImportEnabled\n ? [civitaiImportSource, huggingfaceImportSource]\n : [civitaiImportSource]\n\n // Detected import source based on URL\n const detectedSource = computed(() => {\n const url = wizardData.value.url.trim()\n if (!url) return null\n return (\n importSources.find((source) => validateSourceUrl(url, source)) ?? null\n )\n })\n\n // Clear error when URL changes\n watch(\n () => wizardData.value.url,\n () => {\n uploadError.value = ''\n }\n )\n\n // Validation\n const canFetchMetadata = computed(() => {\n return wizardData.value.url.trim().length > 0\n })\n\n const canUploadModel = computed(() => {\n return !!selectedModelType.value\n })\n\n async function fetchMetadata() {\n if (!canFetchMetadata.value) return\n\n // Clean and normalize URL\n let cleanedUrl = wizardData.value.url.trim()\n try {\n cleanedUrl = new URL(encodeURI(cleanedUrl)).toString()\n } catch {\n // If URL parsing fails, just use the trimmed input\n }\n wizardData.value.url = cleanedUrl\n\n // Validate URL belongs to a supported import source\n const source = detectedSource.value\n if (!source) {\n const supportedSources = importSources.map((s) => s.name).join(', ')\n uploadError.value = t('assetBrowser.unsupportedUrlSource', {\n sources: supportedSources\n })\n return\n }\n\n isFetchingMetadata.value = true\n try {\n const metadata = await assetService.getAssetMetadata(wizardData.value.url)\n\n // Decode URL-encoded filenames (e.g., Chinese characters)\n if (metadata.filename) {\n try {\n metadata.filename = decodeURIComponent(metadata.filename)\n } catch {\n // Keep original if decoding fails\n }\n }\n if (metadata.name) {\n try {\n metadata.name = decodeURIComponent(metadata.name)\n } catch {\n // Keep original if decoding fails\n }\n }\n\n wizardData.value.metadata = metadata\n\n // Pre-fill name from metadata\n wizardData.value.name = metadata.filename || metadata.name || ''\n\n // Store preview image if available\n wizardData.value.previewImage = metadata.preview_image\n\n // Pre-fill model type from metadata tags if available\n if (metadata.tags && metadata.tags.length > 0) {\n wizardData.value.tags = metadata.tags\n // Try to detect model type from tags\n const typeTag = metadata.tags.find((tag) =>\n modelTypes.value.some((type) => type.value === tag)\n )\n if (typeTag) {\n selectedModelType.value = typeTag\n }\n }\n\n currentStep.value = 2\n } catch (error) {\n console.error('Failed to retrieve metadata:', error)\n uploadError.value =\n error instanceof Error\n ? error.message\n : st(\n 'assetBrowser.uploadModelFailedToRetrieveMetadata',\n 'Failed to retrieve metadata. Please check the link and try again.'\n )\n currentStep.value = 1\n } finally {\n isFetchingMetadata.value = false\n }\n }\n\n async function uploadPreviewImage(\n filename: string\n ): Promise<string | undefined> {\n if (!wizardData.value.previewImage) return undefined\n\n try {\n const baseFilename = filename.split('.')[0]\n let extension = 'png'\n const mimeMatch = wizardData.value.previewImage.match(\n /^data:image\\/([^;]+);/\n )\n if (mimeMatch) {\n extension = mimeMatch[1] === 'jpeg' ? 'jpg' : mimeMatch[1]\n }\n\n const previewAsset = await assetService.uploadAssetFromBase64({\n data: wizardData.value.previewImage,\n name: `${baseFilename}_preview.${extension}`,\n tags: ['preview']\n })\n return previewAsset.id\n } catch (error) {\n console.error('Failed to upload preview image:', error)\n return undefined\n }\n }\n\n async function refreshModelCaches() {\n if (!selectedModelType.value) return\n\n const providers = modelToNodeStore.getAllNodeProviders(\n selectedModelType.value\n )\n const results = await Promise.allSettled(\n providers.map((provider) =>\n assetsStore.updateModelsForNodeType(provider.nodeDef.name)\n )\n )\n results.forEach((result, index) => {\n if (result.status === 'rejected') {\n console.error(\n `Failed to refresh ${providers[index].nodeDef.name}:`,\n result.reason\n )\n }\n })\n }\n\n async function uploadModel(): Promise<boolean> {\n if (!canUploadModel.value) {\n return false\n }\n\n const source = detectedSource.value\n if (!source) {\n uploadError.value = t('assetBrowser.noValidSourceDetected')\n return false\n }\n\n isUploading.value = true\n\n try {\n const tags = selectedModelType.value\n ? ['models', selectedModelType.value]\n : ['models']\n const filename =\n wizardData.value.metadata?.filename ||\n wizardData.value.metadata?.name ||\n 'model'\n\n const previewId = await uploadPreviewImage(filename)\n const userMetadata = {\n source: source.type,\n source_url: wizardData.value.url,\n model_type: selectedModelType.value\n }\n\n if (flags.asyncModelUploadEnabled) {\n const result = await assetService.uploadAssetAsync({\n source_url: wizardData.value.url,\n tags,\n user_metadata: userMetadata,\n preview_id: previewId\n })\n\n if (result.type === 'async' && result.task.status !== 'completed') {\n if (selectedModelType.value) {\n assetDownloadStore.trackDownload(\n result.task.task_id,\n selectedModelType.value\n )\n }\n uploadStatus.value = 'processing'\n } else {\n uploadStatus.value = 'success'\n await refreshModelCaches()\n }\n currentStep.value = 3\n } else {\n await assetService.uploadAssetFromUrl({\n url: wizardData.value.url,\n name: filename,\n tags,\n user_metadata: userMetadata,\n preview_id: previewId\n })\n uploadStatus.value = 'success'\n await refreshModelCaches()\n currentStep.value = 3\n }\n } catch (error) {\n console.error('Failed to upload asset:', error)\n uploadStatus.value = 'error'\n uploadError.value =\n error instanceof Error ? error.message : 'Failed to upload model'\n currentStep.value = 3\n } finally {\n isUploading.value = false\n }\n return uploadStatus.value !== 'error'\n }\n\n function goToPreviousStep() {\n if (currentStep.value > 1) {\n currentStep.value = currentStep.value - 1\n }\n }\n\n return {\n // State\n currentStep,\n isFetchingMetadata,\n isUploading,\n uploadStatus,\n uploadError,\n wizardData,\n selectedModelType,\n\n // Computed\n canFetchMetadata,\n canUploadModel,\n detectedSource,\n\n // Actions\n fetchMetadata,\n uploadModel,\n goToPreviousStep\n }\n}\n","<template>\n <div\n class=\"upload-model-dialog flex flex-col gap-6 border-t border-border-default p-4 pt-6\"\n >\n <!-- Scrollable content area -->\n <div class=\"min-h-0 flex-auto basis-0 overflow-y-auto\">\n <!-- Step 1: Enter URL -->\n <UploadModelUrlInput\n v-if=\"currentStep === 1 && flags.huggingfaceModelImportEnabled\"\n v-model=\"wizardData.url\"\n :error=\"uploadError\"\n />\n <UploadModelUrlInputCivitai\n v-else-if=\"currentStep === 1\"\n v-model=\"wizardData.url\"\n :error=\"uploadError\"\n />\n\n <!-- Step 2: Confirm Metadata -->\n <UploadModelConfirmation\n v-else-if=\"currentStep === 2\"\n v-model=\"selectedModelType\"\n :metadata=\"wizardData.metadata\"\n :preview-image=\"wizardData.previewImage\"\n />\n\n <!-- Step 3: Upload Progress -->\n <UploadModelProgress\n v-else-if=\"currentStep === 3 && uploadStatus != null\"\n :result=\"uploadStatus\"\n :error=\"uploadError\"\n :metadata=\"wizardData.metadata\"\n :model-type=\"selectedModelType\"\n :preview-image=\"wizardData.previewImage\"\n />\n </div>\n\n <!-- Navigation Footer - always visible -->\n <UploadModelFooter\n class=\"flex-shrink-0\"\n :current-step=\"currentStep\"\n :is-fetching-metadata=\"isFetchingMetadata\"\n :is-uploading=\"isUploading\"\n :can-fetch-metadata=\"canFetchMetadata\"\n :can-upload-model=\"canUploadModel\"\n :upload-status=\"uploadStatus\"\n @back=\"goToPreviousStep\"\n @fetch-metadata=\"handleFetchMetadata\"\n @upload=\"handleUploadModel\"\n @close=\"handleClose\"\n />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { onMounted } from 'vue'\n\nimport { useFeatureFlags } from '@/composables/useFeatureFlags'\nimport UploadModelConfirmation from '@/platform/assets/components/UploadModelConfirmation.vue'\nimport UploadModelFooter from '@/platform/assets/components/UploadModelFooter.vue'\nimport UploadModelProgress from '@/platform/assets/components/UploadModelProgress.vue'\nimport UploadModelUrlInput from '@/platform/assets/components/UploadModelUrlInput.vue'\nimport UploadModelUrlInputCivitai from '@/platform/assets/components/UploadModelUrlInputCivitai.vue'\nimport { useModelTypes } from '@/platform/assets/composables/useModelTypes'\nimport { useUploadModelWizard } from '@/platform/assets/composables/useUploadModelWizard'\nimport { useDialogStore } from '@/stores/dialogStore'\n\nconst { flags } = useFeatureFlags()\nconst dialogStore = useDialogStore()\nconst { modelTypes, fetchModelTypes } = useModelTypes()\n\nconst emit = defineEmits<{\n 'upload-success': []\n}>()\n\nconst {\n currentStep,\n isFetchingMetadata,\n isUploading,\n uploadStatus,\n uploadError,\n wizardData,\n selectedModelType,\n canFetchMetadata,\n canUploadModel,\n fetchMetadata,\n uploadModel,\n goToPreviousStep\n} = useUploadModelWizard(modelTypes)\n\nasync function handleFetchMetadata() {\n await fetchMetadata()\n}\n\nasync function handleUploadModel() {\n const success = await uploadModel()\n if (success) {\n emit('upload-success')\n }\n}\n\nfunction handleClose() {\n dialogStore.closeDialog({ key: 'upload-model' })\n}\n\nonMounted(() => {\n fetchModelTypes()\n})\n</script>\n\n<style scoped>\n.upload-model-dialog {\n width: 90vw;\n max-width: 800px;\n min-height: min(400px, 80vh);\n max-height: 90vh;\n}\n\n@media (min-width: 640px) {\n .upload-model-dialog {\n width: auto;\n min-width: 600px;\n }\n}\n</style>\n","export default \"__VITE_PUBLIC_ASSET__53f47e52__\"","<template>\n <div class=\"flex items-center gap-2 p-4 font-bold\">\n <img\n v-if=\"!flags.huggingfaceModelImportEnabled\"\n src=\"/assets/images/civitai.svg\"\n class=\"size-4\"\n />\n <span>{{ $t(titleKey) }}</span>\n <span\n class=\"rounded-full bg-white px-1.5 py-0 text-xxs font-inter font-semibold uppercase text-black\"\n >\n {{ $t('g.beta') }}\n </span>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { useFeatureFlags } from '@/composables/useFeatureFlags'\n\nconst { flags } = useFeatureFlags()\n\nconst titleKey = computed(() => {\n return flags.huggingfaceModelImportEnabled\n ? 'assetBrowser.uploadModelGeneric'\n : 'assetBrowser.uploadModelFromCivitai'\n})\n</script>\n","<template>\n <div\n class=\"flex flex-1 flex-col items-center justify-center text-base text-muted-foreground\"\n >\n <p class=\"m-0 max-w-md\">\n {{ $t('assetBrowser.upgradeFeatureDescription') }}\n </p>\n </div>\n</template>\n","<template>\n <div class=\"flex flex-wrap justify-end gap-2 w-full\">\n <a\n href=\"https://blog.comfy.org/p/comfy-cloud-new-features-and-pricing\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"text-muted-foreground mr-auto underline flex items-center gap-2\"\n >\n <i class=\"icon-[lucide--external-link]\" />\n <span>{{ $t('g.learnMore') }}</span>\n </a>\n <Button variant=\"textonly\" @click=\"emit('close')\">{{\n $t('g.close')\n }}</Button>\n <Button variant=\"secondary\" @click=\"emit('subscribe')\">\n {{ $t('subscription.required.subscribe') }}\n </Button>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport Button from '@/components/ui/button/Button.vue'\n\nconst emit = defineEmits<{\n close: []\n subscribe: []\n}>()\n</script>\n","<template>\n <div\n class=\"flex flex-col justify-between gap-10 p-4 border-t border-border-default w-auto max-w-[min(500px,90vw)]\"\n >\n <UploadModelUpgradeModalBody />\n\n <UploadModelUpgradeModalFooter\n @close=\"handleClose\"\n @subscribe=\"handleSubscribe\"\n />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport UploadModelUpgradeModalBody from '@/platform/assets/components/UploadModelUpgradeModalBody.vue'\nimport UploadModelUpgradeModalFooter from '@/platform/assets/components/UploadModelUpgradeModalFooter.vue'\nimport { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'\nimport { useDialogStore } from '@/stores/dialogStore'\n\nconst dialogStore = useDialogStore()\nconst { showSubscriptionDialog } = useSubscription()\n\nfunction handleClose() {\n dialogStore.closeDialog({ key: 'upload-model-upgrade' })\n}\n\nfunction handleSubscribe() {\n showSubscriptionDialog()\n}\n</script>\n","<template>\n <div class=\"flex items-center gap-2 p-4 font-bold\">\n <span>{{ $t('assetBrowser.upgradeToUnlockFeature') }}</span>\n </div>\n</template>\n","import { useFeatureFlags } from '@/composables/useFeatureFlags'\nimport UploadModelDialog from '@/platform/assets/components/UploadModelDialog.vue'\nimport UploadModelDialogHeader from '@/platform/assets/components/UploadModelDialogHeader.vue'\nimport UploadModelUpgradeModal from '@/platform/assets/components/UploadModelUpgradeModal.vue'\nimport UploadModelUpgradeModalHeader from '@/platform/assets/components/UploadModelUpgradeModalHeader.vue'\nimport { useDialogStore } from '@/stores/dialogStore'\nimport { computed } from 'vue'\n\nexport function useModelUpload(\n onUploadSuccess?: () => Promise<unknown> | void\n) {\n const dialogStore = useDialogStore()\n const { flags } = useFeatureFlags()\n const isUploadButtonEnabled = computed(() => flags.modelUploadButtonEnabled)\n\n function showUploadDialog() {\n if (!flags.privateModelsEnabled) {\n // Show upgrade modal if private models are disabled\n dialogStore.showDialog({\n key: 'upload-model-upgrade',\n headerComponent: UploadModelUpgradeModalHeader,\n component: UploadModelUpgradeModal,\n dialogComponentProps: {\n pt: {\n header: 'py-0! pl-0!',\n content: 'p-0! overflow-y-hidden!'\n }\n }\n })\n } else {\n // Show regular upload modal\n dialogStore.showDialog({\n key: 'upload-model',\n headerComponent: UploadModelDialogHeader,\n component: UploadModelDialog,\n props: {\n onUploadSuccess: async () => {\n await onUploadSuccess?.()\n }\n },\n dialogComponentProps: {\n pt: {\n header: 'py-0! pl-0!',\n content: 'p-0! overflow-y-hidden!'\n }\n }\n })\n }\n }\n return { isUploadButtonEnabled, showUploadDialog }\n}\n","export default \"__VITE_PUBLIC_ASSET__c8cdd13f__\"","import { onBeforeUnmount, ref, watch } from 'vue'\nimport type { Ref } from 'vue'\n\ninterface UseIntersectionObserverOptions extends IntersectionObserverInit {\n immediate?: boolean\n}\n\nexport function useIntersectionObserver(\n target: Ref<Element | null>,\n callback: IntersectionObserverCallback,\n options: UseIntersectionObserverOptions = {}\n) {\n const { immediate = true, ...observerOptions } = options\n\n const isSupported =\n typeof window !== 'undefined' && 'IntersectionObserver' in window\n const isIntersecting = ref(false)\n\n let observer: IntersectionObserver | null = null\n\n const cleanup = () => {\n if (observer) {\n observer.disconnect()\n observer = null\n }\n }\n\n const observe = () => {\n cleanup()\n\n if (!isSupported || !target.value) return\n\n observer = new IntersectionObserver((entries) => {\n isIntersecting.value = entries.some((entry) => entry.isIntersecting)\n callback(entries, observer!)\n }, observerOptions)\n\n observer.observe(target.value)\n }\n\n const unobserve = () => {\n if (observer && target.value) {\n observer.unobserve(target.value)\n }\n }\n\n if (immediate) {\n watch(target, observe, { immediate: true, flush: 'post' })\n }\n\n onBeforeUnmount(cleanup)\n\n return {\n isSupported,\n isIntersecting,\n observe,\n unobserve,\n cleanup\n }\n}\n","import { reactive } from 'vue'\n\ninterface CachedMedia {\n src: string\n blob?: Blob\n objectUrl?: string\n error?: boolean\n isLoading: boolean\n lastAccessed: number\n}\n\ninterface MediaCacheOptions {\n maxSize?: number\n maxAge?: number // in milliseconds\n preloadDistance?: number // pixels from viewport\n}\n\nclass MediaCacheService {\n public cache = reactive(new Map<string, CachedMedia>())\n private readonly maxSize: number\n private readonly maxAge: number\n private cleanupInterval: number | null = null\n private urlRefCount = new Map<string, number>()\n\n constructor(options: MediaCacheOptions = {}) {\n this.maxSize = options.maxSize ?? 100\n this.maxAge = options.maxAge ?? 30 * 60 * 1000 // 30 minutes\n\n // Start cleanup interval\n this.startCleanupInterval()\n }\n\n private startCleanupInterval() {\n // Clean up every 5 minutes\n this.cleanupInterval = window.setInterval(\n () => {\n this.cleanup()\n },\n 5 * 60 * 1000\n )\n }\n\n private cleanup() {\n const now = Date.now()\n const keysToDelete: string[] = []\n\n // Find expired entries\n for (const [key, entry] of Array.from(this.cache.entries())) {\n if (now - entry.lastAccessed > this.maxAge) {\n // Only revoke object URL if no components are using it\n if (entry.objectUrl) {\n const refCount = this.urlRefCount.get(entry.objectUrl) || 0\n if (refCount === 0) {\n URL.revokeObjectURL(entry.objectUrl)\n this.urlRefCount.delete(entry.objectUrl)\n keysToDelete.push(key)\n }\n // Don't delete cache entry if URL is still in use\n } else {\n keysToDelete.push(key)\n }\n }\n }\n\n // Remove expired entries\n keysToDelete.forEach((key) => this.cache.delete(key))\n\n // If still over size limit, remove oldest entries that aren't in use\n if (this.cache.size > this.maxSize) {\n const entries = Array.from(this.cache.entries())\n entries.sort((a, b) => a[1].lastAccessed - b[1].lastAccessed)\n\n let removedCount = 0\n const targetRemoveCount = this.cache.size - this.maxSize\n\n for (const [key, entry] of entries) {\n if (removedCount >= targetRemoveCount) break\n\n if (entry.objectUrl) {\n const refCount = this.urlRefCount.get(entry.objectUrl) || 0\n if (refCount === 0) {\n URL.revokeObjectURL(entry.objectUrl)\n this.urlRefCount.delete(entry.objectUrl)\n this.cache.delete(key)\n removedCount++\n }\n } else {\n this.cache.delete(key)\n removedCount++\n }\n }\n }\n }\n\n async getCachedMedia(src: string): Promise<CachedMedia> {\n let entry = this.cache.get(src)\n\n if (entry) {\n // Update last accessed time\n entry.lastAccessed = Date.now()\n return entry\n }\n\n // Create new entry\n entry = {\n src,\n isLoading: true,\n lastAccessed: Date.now()\n }\n\n // Update cache with loading entry\n this.cache.set(src, entry)\n\n try {\n // Fetch the media\n const response = await fetch(src, { cache: 'force-cache' })\n if (!response.ok) {\n throw new Error(`Failed to fetch: ${response.status}`)\n }\n\n const blob = await response.blob()\n const objectUrl = URL.createObjectURL(blob)\n\n // Update entry with successful result\n const updatedEntry: CachedMedia = {\n src,\n blob,\n objectUrl,\n isLoading: false,\n lastAccessed: Date.now()\n }\n\n this.cache.set(src, updatedEntry)\n return updatedEntry\n } catch (error) {\n console.warn('Failed to cache media:', src, error)\n\n // Update entry with error\n const errorEntry: CachedMedia = {\n src,\n error: true,\n isLoading: false,\n lastAccessed: Date.now()\n }\n\n this.cache.set(src, errorEntry)\n return errorEntry\n }\n }\n\n acquireUrl(src: string): string | undefined {\n const entry = this.cache.get(src)\n if (entry?.objectUrl) {\n const currentCount = this.urlRefCount.get(entry.objectUrl) || 0\n this.urlRefCount.set(entry.objectUrl, currentCount + 1)\n return entry.objectUrl\n }\n return undefined\n }\n\n releaseUrl(src: string): void {\n const entry = this.cache.get(src)\n if (entry?.objectUrl) {\n const count = (this.urlRefCount.get(entry.objectUrl) || 1) - 1\n if (count <= 0) {\n URL.revokeObjectURL(entry.objectUrl)\n this.urlRefCount.delete(entry.objectUrl)\n // Remove from cache as well\n this.cache.delete(src)\n } else {\n this.urlRefCount.set(entry.objectUrl, count)\n }\n }\n }\n\n clearCache() {\n // Revoke all object URLs\n for (const entry of Array.from(this.cache.values())) {\n if (entry.objectUrl) {\n URL.revokeObjectURL(entry.objectUrl)\n }\n }\n this.cache.clear()\n this.urlRefCount.clear()\n }\n\n destroy() {\n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval)\n this.cleanupInterval = null\n }\n this.clearCache()\n }\n}\n\n// Global instance\nlet mediaCacheInstance: MediaCacheService | null = null\n\nexport function useMediaCache(options?: MediaCacheOptions) {\n if (!mediaCacheInstance) {\n mediaCacheInstance = new MediaCacheService(options)\n }\n\n const getCachedMedia = (src: string) =>\n mediaCacheInstance!.getCachedMedia(src)\n const clearCache = () => mediaCacheInstance!.clearCache()\n const acquireUrl = (src: string) => mediaCacheInstance!.acquireUrl(src)\n const releaseUrl = (src: string) => mediaCacheInstance!.releaseUrl(src)\n\n return {\n getCachedMedia,\n clearCache,\n acquireUrl,\n releaseUrl,\n cache: mediaCacheInstance.cache\n }\n}\n\n// Cleanup on page unload\nif (typeof window !== 'undefined') {\n window.addEventListener('beforeunload', () => {\n if (mediaCacheInstance) {\n mediaCacheInstance.destroy()\n }\n })\n}\n","<template>\n <div\n ref=\"containerRef\"\n class=\"relative flex h-full w-full items-center justify-center overflow-hidden\"\n :class=\"containerClass\"\n >\n <Skeleton\n v-if=\"!isImageLoaded\"\n width=\"100%\"\n height=\"100%\"\n class=\"absolute inset-0\"\n />\n <img\n v-if=\"cachedSrc\"\n :src=\"cachedSrc\"\n :alt=\"alt\"\n draggable=\"false\"\n :class=\"imageClass\"\n :style=\"imageStyle\"\n @load=\"onImageLoad\"\n @error=\"onImageError\"\n />\n <div\n v-if=\"hasError\"\n class=\"absolute inset-0 flex items-center justify-center\"\n >\n <img\n src=\"/assets/images/default-template.png\"\n :alt=\"alt\"\n draggable=\"false\"\n :class=\"imageClass\"\n :style=\"imageStyle\"\n />\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport Skeleton from 'primevue/skeleton'\nimport { computed, onUnmounted, ref, watch } from 'vue'\n\nimport { useIntersectionObserver } from '@/composables/useIntersectionObserver'\nimport { useMediaCache } from '@/services/mediaCacheService'\nimport type { ClassValue } from '@/utils/tailwindUtil'\n\nconst {\n src,\n alt = '',\n containerClass = '',\n imageClass = '',\n imageStyle,\n rootMargin = '300px'\n} = defineProps<{\n src: string\n alt?: string\n containerClass?: ClassValue\n imageClass?: ClassValue\n imageStyle?: Record<string, any>\n rootMargin?: string\n}>()\n\nconst containerRef = ref<HTMLElement | null>(null)\nconst isIntersecting = ref(false)\nconst isImageLoaded = ref(false)\nconst hasError = ref(false)\nconst cachedSrc = ref<string | undefined>(undefined)\n\nconst { getCachedMedia, acquireUrl, releaseUrl } = useMediaCache()\n\n// Use intersection observer to detect when the image container comes into view\nuseIntersectionObserver(\n containerRef,\n (entries) => {\n const entry = entries[0]\n isIntersecting.value = entry?.isIntersecting ?? false\n },\n {\n rootMargin,\n threshold: 0.1\n }\n)\n\n// Only start loading the image when it's in view\nconst shouldLoad = computed(() => isIntersecting.value)\n\nwatch(\n shouldLoad,\n async (shouldLoadVal) => {\n if (shouldLoadVal && src && !cachedSrc.value && !hasError.value) {\n try {\n const cachedMedia = await getCachedMedia(src)\n if (cachedMedia.error) {\n hasError.value = true\n } else if (cachedMedia.objectUrl) {\n const acquiredUrl = acquireUrl(src)\n cachedSrc.value = acquiredUrl || cachedMedia.objectUrl\n } else {\n cachedSrc.value = src\n }\n } catch (error) {\n console.warn('Failed to load cached media:', error)\n cachedSrc.value = src\n }\n } else if (!shouldLoadVal) {\n if (cachedSrc.value?.startsWith('blob:')) {\n releaseUrl(src)\n }\n // Hide image when out of view\n isImageLoaded.value = false\n cachedSrc.value = undefined\n hasError.value = false\n }\n },\n { immediate: true }\n)\n\nconst onImageLoad = () => {\n isImageLoaded.value = true\n hasError.value = false\n}\n\nconst onImageError = () => {\n hasError.value = true\n isImageLoaded.value = false\n}\n\nonUnmounted(() => {\n if (cachedSrc.value?.startsWith('blob:')) {\n releaseUrl(src)\n }\n})\n</script>\n"],"names":["useFeatureFlags","flags","reactive","api","remoteConfig","featureFlag","__name","featurePath","defaultValue","computed","readonly","selectedItem","_useModel","__props","t","useI18n","getLabel","val","found","o","optionStyle","styles","formatDisplayName","folderName","specialCases","word","DISALLOWED_MODEL_TYPES","useModelTypes","createSharedComposable","modelTypes","isLoading","error","fetchModelTypes","useAsyncState","folder","a","b","err","modelValue","isVisible","handleEscapeKey","event","watch","visible","stop","useEventListener","onWatcherCleanup","showCivitaiHelp","ref","showHuggingFaceHelp","emit","__emit","civitaiImportSource","huggingfaceImportSource","validateSourceUrl","url","source","hostname","h","civitaiIcon","civitaiUrl","huggingFaceIcon","huggingFaceUrl","props","value","importSources","isValidUrl","trimmedUrl","useUploadModelWizard","assetsStore","useAssetsStore","assetDownloadStore","useAssetDownloadStore","modelToNodeStore","useModelToNodeStore","currentStep","isFetchingMetadata","isUploading","uploadStatus","uploadError","wizardData","selectedModelType","detectedSource","canFetchMetadata","canUploadModel","fetchMetadata","cleanedUrl","supportedSources","s","metadata","assetService","typeTag","tag","type","st","uploadPreviewImage","filename","baseFilename","extension","mimeMatch","refreshModelCaches","providers","provider","result","index","uploadModel","tags","previewId","userMetadata","goToPreviousStep","dialogStore","useDialogStore","handleFetchMetadata","handleUploadModel","handleClose","onMounted","_imports_0$1","titleKey","_hoisted_1","_hoisted_2","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_ctx","showSubscriptionDialog","useSubscription","handleSubscribe","useModelUpload","onUploadSuccess","isUploadButtonEnabled","showUploadDialog","UploadModelDialogHeader","UploadModelDialog","UploadModelUpgradeModalHeader","UploadModelUpgradeModal","_imports_0","useIntersectionObserver","target","callback","options","immediate","observerOptions","isSupported","isIntersecting","observer","cleanup","observe","entries","entry","unobserve","onBeforeUnmount","MediaCacheService","now","keysToDelete","key","removedCount","targetRemoveCount","src","response","blob","objectUrl","updatedEntry","errorEntry","currentCount","count","mediaCacheInstance","useMediaCache","containerRef","isImageLoaded","hasError","cachedSrc","getCachedMedia","acquireUrl","releaseUrl","shouldLoad","shouldLoadVal","cachedMedia","acquiredUrl","onImageLoad","onImageError","onUnmounted"],"mappings":"wlBAwBO,SAASA,GAAkB,CAChC,MAAMC,EAAQC,GAAS,CACrB,IAAI,yBAA0B,CAC5B,OAAOC,EAAI,iBAAiB,2BAAA,CAC9B,EACA,IAAI,eAAgB,CAClB,OAAOA,EAAI,iBAAiB,iBAAA,CAC9B,EACA,IAAI,mBAAoB,CACtB,OAAOA,EAAI,iBAAiB,+BAAA,CAC9B,EACA,IAAI,0BAA2B,CAE7B,OACEC,EAAa,MAAM,6BACnBD,EAAI,iBACF,8BACA,EAAA,CAGN,EACA,IAAI,sBAAuB,CACzB,OACEC,EAAa,MAAM,wBACnBD,EAAI,iBAAiB,yBAA0C,EAAK,CAExE,EACA,IAAI,oBAAqB,CACvB,OACEC,EAAa,MAAM,sBACnBD,EAAI,iBAAiB,uBAAwC,EAAK,CAEtE,EACA,IAAI,sBAAuB,CAEzB,OACEC,EAAa,MAAM,wBACnBD,EAAI,iBAAiB,yBAA0C,EAAK,CAExE,EACA,IAAI,yBAA0B,CAC5B,OACEC,EAAa,MAAM,2BACnBD,EAAI,iBAAiB,4BAA6C,EAAI,CAE1E,EACA,IAAI,+BAAgC,CAClC,OACEC,EAAa,MAAM,kCACnBD,EAAI,iBACF,mCACA,EAAA,CAGN,EACA,IAAI,yBAA0B,CAC5B,OACEC,EAAa,MAAM,4BACnBD,EAAI,iBACF,6BACA,EAAA,CAGN,CAAA,CACD,EAEKE,EAAcC,EAAA,CAAcC,EAAqBC,IACrDC,EAAS,IAAMN,EAAI,iBAAiBI,EAAaC,CAAY,CAAC,EAD5C,eAGpB,MAAO,CACL,MAAOE,GAAST,CAAK,EACrB,YAAAI,CAAA,CAEJ,CAzEgBC,EAAAN,EAAA,4cCkIhB,MAAMW,EAAeC,EAA+BC,EAAA,YAAmB,EAEjE,CAAE,EAAAC,CAAA,EAAMC,GAAA,EAORC,EAAWV,EAACW,GAAmC,CAEnD,GADIA,GAAO,MACP,CAACJ,EAAA,QAAS,OAAOA,SAAS,GAC9B,MAAMK,EAAQL,UAAQ,KAAMM,GAAMA,EAAE,QAAUF,CAAG,EACjD,OAAOC,EAAQA,EAAM,KAAQL,SAAS,EACxC,EALiB,YAQXO,EAAcX,EAAS,IAAM,CACjC,GAAI,CAACI,EAAA,iBAAmB,CAACA,EAAA,gBAAiB,OAE1C,MAAMQ,EAAmB,CAAA,EACzB,OAAIR,mBAAiBQ,EAAO,KAAK,cAAcR,EAAA,eAAe,EAAE,EAC5DA,mBAAiBQ,EAAO,KAAK,cAAcR,EAAA,eAAe,EAAE,EAEzDQ,EAAO,KAAK,IAAI,CACzB,CAAC,0iEC1KD,SAASC,GAAkBC,EAA4B,CAErD,MAAMC,EAAuC,CAC3C,MAAO,OACP,UAAW,aACX,KAAM,MACN,YAAa,cACb,wBAAyB,0BACzB,mBAAoB,oBACpB,IAAK,MACL,KAAM,QACN,WAAY,aACZ,OAAQ,QAAA,EAGV,OAAIA,EAAaD,CAAU,EAClBC,EAAaD,CAAU,EAGzBA,EACJ,MAAM,GAAG,EACT,IAAKE,GAASA,EAAK,OAAO,CAAC,EAAE,YAAA,EAAgBA,EAAK,MAAM,CAAC,CAAC,EAC1D,KAAK,GAAG,CACb,CAvBSnB,EAAAgB,GAAA,qBA8BT,MAAMI,GAAyB,CAAC,KAAK,EAMxBC,GAAgBC,GAAuB,IAAM,CACxD,KAAM,CACJ,MAAOC,EACP,UAAAC,EACA,MAAAC,EACA,QAASC,CAAA,EACPC,GACF,UACmB,MAAM9B,EAAI,gBAAA,GAExB,OACE+B,GACC,CAACR,GAAuB,SACtBQ,EAAO,IAAA,CACT,EAEH,IAAKA,IAAY,CAChB,KAAMZ,GAAkBY,EAAO,IAAI,EACnC,MAAOA,EAAO,IAAA,EACd,EACD,KAAK,CAACC,EAAGC,IAAMD,EAAE,KAAK,cAAcC,EAAE,IAAI,CAAC,EAEhD,CAAA,EACA,CACE,UAAW,GACX,QAAS9B,EAAC+B,GAAQ,CAChB,QAAQ,MAAM,+BAAgCA,CAAG,CACnD,EAFS,UAET,CACF,EAGF,MAAO,CACL,WAAAR,EACA,UAAAC,EACA,MAAAC,EACA,gBAAAC,CAAA,CAEJ,CAAC,ufC3BD,MAAMM,EAAa1B,EAA+BC,EAAA,YAAC,EAE7C,CAAE,WAAAgB,EAAY,UAAAC,CAAA,EAAcH,GAAA,ykCCXlC,MAAMY,EAAY3B,EAAoBC,EAAA,YAAmB,EAOnD2B,EAAkBlC,EAACmC,GAAyB,CAC5CA,EAAM,MAAQ,WAChBA,EAAM,yBAAA,EACNA,EAAM,gBAAA,EACNA,EAAM,eAAA,EACNF,EAAU,MAAQ,GAEtB,EAPwB,mBAWxB,OAAAG,EACEH,EACCI,GAAY,CACX,GAAIA,EAAS,CACX,MAAMC,EAAOC,GAAiB,SAAU,UAAWL,EAAiB,CAClE,QAAS,EAAA,CACV,EACDM,GAAiBF,CAAI,CACvB,CACF,EACA,CAAE,UAAW,EAAA,CAAK,wrCC2CpB,KAAM,CAAE,MAAA3C,CAAA,EAAUD,EAAA,EAEZ+C,EAAkBC,EAAI,EAAK,EAC3BC,EAAsBD,EAAI,EAAK,EAW/BE,EAAOC,smKC9HAC,EAAoC,CAC/C,KAAM,UACN,KAAM,UACN,UAAW,CAAC,aAAa,CAC3B,ECJaC,GAAwC,CACnD,KAAM,cACN,KAAM,eACN,UAAW,CAAC,gBAAgB,CAC9B,ECJO,SAASC,GAAkBC,EAAaC,EAA+B,CAC5E,GAAI,CACF,MAAMC,EAAW,IAAI,IAAIF,CAAG,EAAE,SAAS,YAAA,EACvC,OAAOC,EAAO,UAAU,KACrBE,GAAMD,IAAaC,GAAKD,EAAS,SAAS,IAAIC,CAAC,EAAE,CAAA,CAEtD,MAAQ,CACN,MAAO,EACT,CACF,CATgBpD,EAAAgD,GAAA,gtBC6GVK,GAAc,6BACdC,GAAa,6BACbC,GAAkB,6BAClBC,GAAiB,yIA3BvB,KAAM,CAAE,MAAA7D,CAAA,EAAUD,EAAA,EAEZ+D,EAAQlD,EAKRqC,EAAOC,EAIPI,EAAM9C,EAAS,CACnB,IAAKH,EAAA,IAAMyD,EAAM,WAAZ,OACL,IAAKzD,EAAC0D,GAAkBd,EAAK,oBAAqBc,CAAK,EAAlD,MAAkD,CACxD,EAEKC,EAAgB,CAACb,EAAqBC,EAAuB,EAE7Da,EAAazD,EAAS,IAAM,CAChC,MAAM0D,EAAaZ,EAAI,MAAM,KAAA,EAC7B,OAAKY,EACEF,EAAc,KAAMT,GAAWF,GAAkBa,EAAYX,CAAM,CAAC,EADnD,EAE1B,CAAC,mqECzBD,KAAM,CAAE,MAAAvD,CAAA,EAAUD,EAAA,EAMZuD,EAAM3C,EAAmBC,EAAA,YAAmB,EAE5CqD,EAAazD,EAAS,IAAM,CAChC,MAAM0D,EAAaZ,EAAI,MAAM,KAAA,EAC7B,OAAKY,EACEb,GAAkBa,EAAYf,CAAmB,EADhC,EAE1B,CAAC,yxCCtEM,SAASgB,GAAqBvC,EAAoC,CACvE,KAAM,CAAE,EAAAf,CAAA,EAAMC,GAAA,EACRsD,EAAcC,GAAA,EACdC,EAAqBC,GAAA,EACrBC,EAAmBC,GAAA,EACnB,CAAE,MAAAzE,CAAA,EAAUD,EAAA,EACZ2E,EAAc3B,EAAI,CAAC,EACnB4B,EAAqB5B,EAAI,EAAK,EAC9B6B,EAAc7B,EAAI,EAAK,EACvB8B,EAAe9B,EAAA,EACf+B,EAAc/B,EAAI,EAAE,EAEpBgC,EAAahC,EAAgB,CACjC,IAAK,GACL,KAAM,GACN,KAAM,CAAA,CAAC,CACR,EAEKiC,EAAoBjC,EAAA,EAGpBiB,EAAgChE,EAAM,8BACxC,CAACmD,EAAqBC,EAAuB,EAC7C,CAACD,CAAmB,EAGlB8B,EAAiBzE,EAAS,IAAM,CACpC,MAAM8C,EAAMyB,EAAW,MAAM,IAAI,KAAA,EACjC,OAAKzB,EAEHU,EAAc,KAAMT,GAAWF,GAAkBC,EAAKC,CAAM,CAAC,GAAK,KAFnD,IAInB,CAAC,EAGDd,EACE,IAAMsC,EAAW,MAAM,IACvB,IAAM,CACJD,EAAY,MAAQ,EACtB,CAAA,EAIF,MAAMI,EAAmB1E,EAAS,IACzBuE,EAAW,MAAM,IAAI,KAAA,EAAO,OAAS,CAC7C,EAEKI,EAAiB3E,EAAS,IACvB,CAAC,CAACwE,EAAkB,KAC5B,EAED,eAAeI,GAAgB,CAC7B,GAAI,CAACF,EAAiB,MAAO,OAG7B,IAAIG,EAAaN,EAAW,MAAM,IAAI,KAAA,EACtC,GAAI,CACFM,EAAa,IAAI,IAAI,UAAUA,CAAU,CAAC,EAAE,SAAA,CAC9C,MAAQ,CAER,CAKA,GAJAN,EAAW,MAAM,IAAMM,EAInB,CADWJ,EAAe,MACjB,CACX,MAAMK,EAAmBtB,EAAc,IAAKuB,GAAMA,EAAE,IAAI,EAAE,KAAK,IAAI,EACnET,EAAY,MAAQjE,EAAE,oCAAqC,CACzD,QAASyE,CAAA,CACV,EACD,MACF,CAEAX,EAAmB,MAAQ,GAC3B,GAAI,CACF,MAAMa,EAAW,MAAMC,EAAa,iBAAiBV,EAAW,MAAM,GAAG,EAGzE,GAAIS,EAAS,SACX,GAAI,CACFA,EAAS,SAAW,mBAAmBA,EAAS,QAAQ,CAC1D,MAAQ,CAER,CAEF,GAAIA,EAAS,KACX,GAAI,CACFA,EAAS,KAAO,mBAAmBA,EAAS,IAAI,CAClD,MAAQ,CAER,CAYF,GATAT,EAAW,MAAM,SAAWS,EAG5BT,EAAW,MAAM,KAAOS,EAAS,UAAYA,EAAS,MAAQ,GAG9DT,EAAW,MAAM,aAAeS,EAAS,cAGrCA,EAAS,MAAQA,EAAS,KAAK,OAAS,EAAG,CAC7CT,EAAW,MAAM,KAAOS,EAAS,KAEjC,MAAME,EAAUF,EAAS,KAAK,KAAMG,GAClC/D,EAAW,MAAM,KAAMgE,GAASA,EAAK,QAAUD,CAAG,CAAA,EAEhDD,IACFV,EAAkB,MAAQU,EAE9B,CAEAhB,EAAY,MAAQ,CACtB,OAAS5C,EAAO,CACd,QAAQ,MAAM,+BAAgCA,CAAK,EACnDgD,EAAY,MACVhD,aAAiB,MACbA,EAAM,QACN+D,GACE,mDACA,mEAAA,EAERnB,EAAY,MAAQ,CACtB,QAAA,CACEC,EAAmB,MAAQ,EAC7B,CACF,CA5EetE,EAAA+E,EAAA,iBA8Ef,eAAeU,EACbC,EAC6B,CAC7B,GAAKhB,EAAW,MAAM,aAEtB,GAAI,CACF,MAAMiB,EAAeD,EAAS,MAAM,GAAG,EAAE,CAAC,EAC1C,IAAIE,EAAY,MAChB,MAAMC,EAAYnB,EAAW,MAAM,aAAa,MAC9C,uBAAA,EAEF,OAAImB,IACFD,EAAYC,EAAU,CAAC,IAAM,OAAS,MAAQA,EAAU,CAAC,IAGtC,MAAMT,EAAa,sBAAsB,CAC5D,KAAMV,EAAW,MAAM,aACvB,KAAM,GAAGiB,CAAY,YAAYC,CAAS,GAC1C,KAAM,CAAC,SAAS,CAAA,CACjB,GACmB,EACtB,OAASnE,EAAO,CACd,QAAQ,MAAM,kCAAmCA,CAAK,EACtD,MACF,CACF,CAzBezB,EAAAyF,EAAA,sBA2Bf,eAAeK,GAAqB,CAClC,GAAI,CAACnB,EAAkB,MAAO,OAE9B,MAAMoB,EAAY5B,EAAiB,oBACjCQ,EAAkB,KAAA,GAEJ,MAAM,QAAQ,WAC5BoB,EAAU,IAAKC,GACbjC,EAAY,wBAAwBiC,EAAS,QAAQ,IAAI,CAAA,CAC3D,GAEM,QAAQ,CAACC,EAAQC,IAAU,CAC7BD,EAAO,SAAW,YACpB,QAAQ,MACN,qBAAqBF,EAAUG,CAAK,EAAE,QAAQ,IAAI,IAClDD,EAAO,MAAA,CAGb,CAAC,CACH,CAnBejG,EAAA8F,EAAA,sBAqBf,eAAeK,GAAgC,CAC7C,GAAI,CAACrB,EAAe,MAClB,MAAO,GAGT,MAAM5B,EAAS0B,EAAe,MAC9B,GAAI,CAAC1B,EACH,OAAAuB,EAAY,MAAQjE,EAAE,oCAAoC,EACnD,GAGT+D,EAAY,MAAQ,GAEpB,GAAI,CACF,MAAM6B,EAAOzB,EAAkB,MAC3B,CAAC,SAAUA,EAAkB,KAAK,EAClC,CAAC,QAAQ,EACPe,EACJhB,EAAW,MAAM,UAAU,UAC3BA,EAAW,MAAM,UAAU,MAC3B,QAEI2B,EAAY,MAAMZ,EAAmBC,CAAQ,EAC7CY,EAAe,CACnB,OAAQpD,EAAO,KACf,WAAYwB,EAAW,MAAM,IAC7B,WAAYC,EAAkB,KAAA,EAGhC,GAAIhF,EAAM,wBAAyB,CACjC,MAAMsG,EAAS,MAAMb,EAAa,iBAAiB,CACjD,WAAYV,EAAW,MAAM,IAC7B,KAAA0B,EACA,cAAeE,EACf,WAAYD,CAAA,CACb,EAEGJ,EAAO,OAAS,SAAWA,EAAO,KAAK,SAAW,aAChDtB,EAAkB,OACpBV,EAAmB,cACjBgC,EAAO,KAAK,QACZtB,EAAkB,KAAA,EAGtBH,EAAa,MAAQ,eAErBA,EAAa,MAAQ,UACrB,MAAMsB,EAAA,GAERzB,EAAY,MAAQ,CACtB,MACE,MAAMe,EAAa,mBAAmB,CACpC,IAAKV,EAAW,MAAM,IACtB,KAAMgB,EACN,KAAAU,EACA,cAAeE,EACf,WAAYD,CAAA,CACb,EACD7B,EAAa,MAAQ,UACrB,MAAMsB,EAAA,EACNzB,EAAY,MAAQ,CAExB,OAAS5C,EAAO,CACd,QAAQ,MAAM,0BAA2BA,CAAK,EAC9C+C,EAAa,MAAQ,QACrBC,EAAY,MACVhD,aAAiB,MAAQA,EAAM,QAAU,yBAC3C4C,EAAY,MAAQ,CACtB,QAAA,CACEE,EAAY,MAAQ,EACtB,CACA,OAAOC,EAAa,QAAU,OAChC,CAxEexE,EAAAmG,EAAA,eA0Ef,SAASI,GAAmB,CACtBlC,EAAY,MAAQ,IACtBA,EAAY,MAAQA,EAAY,MAAQ,EAE5C,CAJS,OAAArE,EAAAuG,EAAA,oBAMF,CAEL,YAAAlC,EACA,mBAAAC,EACA,YAAAC,EACA,aAAAC,EACA,YAAAC,EACA,WAAAC,EACA,kBAAAC,EAGA,iBAAAE,EACA,eAAAC,EACA,eAAAF,EAGA,cAAAG,EACA,YAAAoB,EACA,iBAAAI,CAAA,CAEJ,CArRgBvG,EAAA8D,GAAA,8PCsChB,KAAM,CAAE,MAAAnE,CAAA,EAAUD,EAAA,EACZ8G,EAAcC,GAAA,EACd,CAAE,WAAAlF,EAAY,gBAAAG,CAAA,EAAoBL,GAAA,EAElCuB,EAAOC,EAIP,CACJ,YAAAwB,EACA,mBAAAC,EACA,YAAAC,EACA,aAAAC,EACA,YAAAC,EACA,WAAAC,EACA,kBAAAC,EACA,iBAAAE,EACA,eAAAC,EACA,cAAAC,EACA,YAAAoB,EACA,iBAAAI,CAAA,EACEzC,GAAqBvC,CAAU,EAEnC,eAAemF,GAAsB,CACnC,MAAM3B,EAAA,CACR,CAFe/E,EAAA0G,EAAA,uBAIf,eAAeC,GAAoB,CACjB,MAAMR,EAAA,GAEpBvD,EAAK,gBAAgB,CAEzB,CALe5C,EAAA2G,EAAA,qBAOf,SAASC,GAAc,CACrBJ,EAAY,YAAY,CAAE,IAAK,cAAA,CAAgB,CACjD,CAFS,OAAAxG,EAAA4G,EAAA,eAITC,GAAU,IAAM,CACdnF,EAAA,CACF,CAAC,upCC3GDoF,GAAe,GAAA,IAAA,IAAA,qBAAA,YAAA,GAAA,EAAA,+OCqBf,KAAM,CAAE,MAAAnH,CAAA,EAAUD,EAAA,EAEZqH,EAAW5G,EAAS,IACjBR,EAAM,8BACT,kCACA,qCACL,6KCzBGqH,GAAA,CAAA,MAAM,kFAAkF,EAErFC,GAAA,CAAA,MAAM,cAAc,mBAHzB,OAAAC,EAAA,EAAAC,EAMM,MANNH,GAMM,CAHJI,EAEI,IAFJH,GAEII,EADCC,EAAA,GAAE,wCAAA,CAAA,EAAA,CAAA,sYCkBX,MAAM1E,EAAOC,sjBCJb,MAAM2D,EAAcC,GAAA,EACd,CAAE,uBAAAc,CAAA,EAA2BC,GAAA,EAEnC,SAASZ,GAAc,CACrBJ,EAAY,YAAY,CAAE,IAAK,sBAAA,CAAwB,CACzD,CAFSxG,EAAA4G,EAAA,eAIT,SAASa,GAAkB,CACzBF,EAAA,CACF,CAFS,OAAAvH,EAAAyH,EAAA,6FCzBFT,GAAA,CAAA,MAAM,uCAAuC,mBAAlD,OAAAE,EAAA,EAAAC,EAEM,MAFNH,GAEM,CADJI,EAA4D,cAAnDE,EAAA,GAAE,qCAAA,CAAA,EAAA,CAAA,wDCMR,SAASI,GACdC,EACA,CACA,MAAMnB,EAAcC,GAAA,EACd,CAAE,MAAA9G,CAAA,EAAUD,EAAA,EACZkI,EAAwBzH,EAAS,IAAMR,EAAM,wBAAwB,EAE3E,SAASkI,GAAmB,CACrBlI,EAAM,qBAeT6G,EAAY,WAAW,CACrB,IAAK,eACL,gBAAiBsB,GACjB,UAAWC,GACX,MAAO,CACL,gBAAiB/H,EAAA,SAAY,CAC3B,MAAM2H,IAAA,CACR,EAFiB,kBAEjB,EAEF,qBAAsB,CACpB,GAAI,CACF,OAAQ,cACR,QAAS,yBAAA,CACX,CACF,CACD,EA5BDnB,EAAY,WAAW,CACrB,IAAK,uBACL,gBAAiBwB,GACjB,UAAWC,GACX,qBAAsB,CACpB,GAAI,CACF,OAAQ,cACR,QAAS,yBAAA,CACX,CACF,CACD,CAoBL,CAjCS,OAAAjI,EAAA6H,EAAA,oBAkCF,CAAE,sBAAAD,EAAuB,iBAAAC,CAAA,CAClC,CA1CgB7H,EAAA0H,GAAA,kBCRhB,MAAAQ,GAAe,+DCOR,SAASC,GACdC,EACAC,EACAC,EAA0C,CAAA,EAC1C,CACA,KAAM,CAAE,UAAAC,EAAY,GAAM,GAAGC,GAAoBF,EAE3CG,EACJ,OAAO,OAAW,KAAe,yBAA0B,OACvDC,EAAiBhG,EAAI,EAAK,EAEhC,IAAIiG,EAAwC,KAE5C,MAAMC,EAAU5I,EAAA,IAAM,CAChB2I,IACFA,EAAS,WAAA,EACTA,EAAW,KAEf,EALgB,WAOVE,EAAU7I,EAAA,IAAM,CACpB4I,EAAA,EAEI,GAACH,GAAe,CAACL,EAAO,SAE5BO,EAAW,IAAI,qBAAsBG,GAAY,CAC/CJ,EAAe,MAAQI,EAAQ,KAAMC,GAAUA,EAAM,cAAc,EACnEV,EAASS,EAASH,CAAS,CAC7B,EAAGH,CAAe,EAElBG,EAAS,QAAQP,EAAO,KAAK,EAC/B,EAXgB,WAaVY,EAAYhJ,EAAA,IAAM,CAClB2I,GAAYP,EAAO,OACrBO,EAAS,UAAUP,EAAO,KAAK,CAEnC,EAJkB,aAMlB,OAAIG,GACFnG,EAAMgG,EAAQS,EAAS,CAAE,UAAW,GAAM,MAAO,OAAQ,EAG3DI,GAAgBL,CAAO,EAEhB,CACL,YAAAH,EACA,eAAAC,EACA,QAAAG,EACA,UAAAG,EACA,QAAAJ,CAAA,CAEJ,CApDgB5I,EAAAmI,GAAA,2BCUhB,MAAMe,EAAkB,OAAA,CAAAlJ,EAAA,0BACf,MAAQJ,GAAS,IAAI,GAA0B,EACrC,QACA,OACT,gBAAiC,KACjC,gBAAkB,IAE1B,YAAY0I,EAA6B,GAAI,CAC3C,KAAK,QAAUA,EAAQ,SAAW,IAClC,KAAK,OAASA,EAAQ,QAAU,KAAU,IAG1C,KAAK,qBAAA,CACP,CAEQ,sBAAuB,CAE7B,KAAK,gBAAkB,OAAO,YAC5B,IAAM,CACJ,KAAK,QAAA,CACP,EACA,IAAS,GAAA,CAEb,CAEQ,SAAU,CAChB,MAAMa,EAAM,KAAK,IAAA,EACXC,EAAyB,CAAA,EAG/B,SAAW,CAACC,EAAKN,CAAK,IAAK,MAAM,KAAK,KAAK,MAAM,QAAA,CAAS,EACpDI,EAAMJ,EAAM,aAAe,KAAK,SAE9BA,EAAM,WACS,KAAK,YAAY,IAAIA,EAAM,SAAS,GAAK,KACzC,IACf,IAAI,gBAAgBA,EAAM,SAAS,EACnC,KAAK,YAAY,OAAOA,EAAM,SAAS,EACvCK,EAAa,KAAKC,CAAG,GAIvBD,EAAa,KAAKC,CAAG,GAS3B,GAHAD,EAAa,QAASC,GAAQ,KAAK,MAAM,OAAOA,CAAG,CAAC,EAGhD,KAAK,MAAM,KAAO,KAAK,QAAS,CAClC,MAAMP,EAAU,MAAM,KAAK,KAAK,MAAM,SAAS,EAC/CA,EAAQ,KAAK,CAAC,EAAGhH,IAAM,EAAE,CAAC,EAAE,aAAeA,EAAE,CAAC,EAAE,YAAY,EAE5D,IAAIwH,EAAe,EACnB,MAAMC,EAAoB,KAAK,MAAM,KAAO,KAAK,QAEjD,SAAW,CAACF,EAAKN,CAAK,IAAKD,EAAS,CAClC,GAAIQ,GAAgBC,EAAmB,MAEnCR,EAAM,WACS,KAAK,YAAY,IAAIA,EAAM,SAAS,GAAK,KACzC,IACf,IAAI,gBAAgBA,EAAM,SAAS,EACnC,KAAK,YAAY,OAAOA,EAAM,SAAS,EACvC,KAAK,MAAM,OAAOM,CAAG,EACrBC,MAGF,KAAK,MAAM,OAAOD,CAAG,EACrBC,IAEJ,CACF,CACF,CAEA,MAAM,eAAeE,EAAmC,CACtD,IAAIT,EAAQ,KAAK,MAAM,IAAIS,CAAG,EAE9B,GAAIT,EAEF,OAAAA,EAAM,aAAe,KAAK,IAAA,EACnBA,EAITA,EAAQ,CACN,IAAAS,EACA,UAAW,GACX,aAAc,KAAK,IAAA,CAAI,EAIzB,KAAK,MAAM,IAAIA,EAAKT,CAAK,EAEzB,GAAI,CAEF,MAAMU,EAAW,MAAM,MAAMD,EAAK,CAAE,MAAO,cAAe,EAC1D,GAAI,CAACC,EAAS,GACZ,MAAM,IAAI,MAAM,oBAAoBA,EAAS,MAAM,EAAE,EAGvD,MAAMC,EAAO,MAAMD,EAAS,KAAA,EACtBE,EAAY,IAAI,gBAAgBD,CAAI,EAGpCE,EAA4B,CAChC,IAAAJ,EACA,KAAAE,EACA,UAAAC,EACA,UAAW,GACX,aAAc,KAAK,IAAA,CAAI,EAGzB,YAAK,MAAM,IAAIH,EAAKI,CAAY,EACzBA,CACT,OAASnI,EAAO,CACd,QAAQ,KAAK,yBAA0B+H,EAAK/H,CAAK,EAGjD,MAAMoI,EAA0B,CAC9B,IAAAL,EACA,MAAO,GACP,UAAW,GACX,aAAc,KAAK,IAAA,CAAI,EAGzB,YAAK,MAAM,IAAIA,EAAKK,CAAU,EACvBA,CACT,CACF,CAEA,WAAWL,EAAiC,CAC1C,MAAMT,EAAQ,KAAK,MAAM,IAAIS,CAAG,EAChC,GAAIT,GAAO,UAAW,CACpB,MAAMe,EAAe,KAAK,YAAY,IAAIf,EAAM,SAAS,GAAK,EAC9D,YAAK,YAAY,IAAIA,EAAM,UAAWe,EAAe,CAAC,EAC/Cf,EAAM,SACf,CAEF,CAEA,WAAWS,EAAmB,CAC5B,MAAMT,EAAQ,KAAK,MAAM,IAAIS,CAAG,EAChC,GAAIT,GAAO,UAAW,CACpB,MAAMgB,GAAS,KAAK,YAAY,IAAIhB,EAAM,SAAS,GAAK,GAAK,EACzDgB,GAAS,GACX,IAAI,gBAAgBhB,EAAM,SAAS,EACnC,KAAK,YAAY,OAAOA,EAAM,SAAS,EAEvC,KAAK,MAAM,OAAOS,CAAG,GAErB,KAAK,YAAY,IAAIT,EAAM,UAAWgB,CAAK,CAE/C,CACF,CAEA,YAAa,CAEX,UAAWhB,KAAS,MAAM,KAAK,KAAK,MAAM,OAAA,CAAQ,EAC5CA,EAAM,WACR,IAAI,gBAAgBA,EAAM,SAAS,EAGvC,KAAK,MAAM,MAAA,EACX,KAAK,YAAY,MAAA,CACnB,CAEA,SAAU,CACJ,KAAK,kBACP,cAAc,KAAK,eAAe,EAClC,KAAK,gBAAkB,MAEzB,KAAK,WAAA,CACP,CACF,CAGA,IAAIiB,EAA+C,KAE5C,SAASC,GAAc3B,EAA6B,CACzD,OAAK0B,IACHA,EAAqB,IAAId,GAAkBZ,CAAO,GAS7C,CACL,eAPqBtI,EAACwJ,GACtBQ,EAAoB,eAAeR,CAAG,EADjB,kBAQrB,WANiBxJ,EAAA,IAAMgK,EAAoB,WAAA,EAA1B,cAOjB,WANiBhK,EAACwJ,GAAgBQ,EAAoB,WAAWR,CAAG,EAAnD,cAOjB,WANiBxJ,EAACwJ,GAAgBQ,EAAoB,WAAWR,CAAG,EAAnD,cAOjB,MAAOQ,EAAmB,KAAA,CAE9B,CAlBgBhK,EAAAiK,GAAA,iBAqBZ,OAAO,OAAW,KACpB,OAAO,iBAAiB,eAAgB,IAAM,CACxCD,GACFA,EAAmB,QAAA,CAEvB,CAAC,wWCnKH,MAAME,EAAexH,EAAwB,IAAI,EAC3CgG,EAAiBhG,EAAI,EAAK,EAC1ByH,EAAgBzH,EAAI,EAAK,EACzB0H,EAAW1H,EAAI,EAAK,EACpB2H,EAAY3H,EAAwB,MAAS,EAE7C,CAAE,eAAA4H,EAAgB,WAAAC,EAAY,WAAAC,CAAA,EAAeP,GAAA,EAGnD9B,GACE+B,EACCpB,GAAY,CACX,MAAMC,EAAQD,EAAQ,CAAC,EACvBJ,EAAe,MAAQK,GAAO,gBAAkB,EAClD,EACA,CACE,WAASxI,EAAA,WACT,UAAW,EAAA,CACb,EAIF,MAAMkK,EAAatK,EAAS,IAAMuI,EAAe,KAAK,EAEtDtG,EACEqI,EACA,MAAOC,GAAkB,CACvB,GAAIA,GAAiBnK,EAAA,KAAO,CAAC8J,EAAU,OAAS,CAACD,EAAS,MACxD,GAAI,CACF,MAAMO,EAAc,MAAML,EAAe/J,EAAA,GAAG,EAC5C,GAAIoK,EAAY,MACdP,EAAS,MAAQ,WACRO,EAAY,UAAW,CAChC,MAAMC,EAAcL,EAAWhK,EAAA,GAAG,EAClC8J,EAAU,MAAQO,GAAeD,EAAY,SAC/C,MACEN,EAAU,MAAQ9J,EAAA,GAEtB,OAASkB,EAAO,CACd,QAAQ,KAAK,+BAAgCA,CAAK,EAClD4I,EAAU,MAAQ9J,EAAA,GACpB,MACUmK,IACNL,EAAU,OAAO,WAAW,OAAO,GACrCG,EAAWjK,EAAA,GAAG,EAGhB4J,EAAc,MAAQ,GACtBE,EAAU,MAAQ,OAClBD,EAAS,MAAQ,GAErB,EACA,CAAE,UAAW,EAAA,CAAK,EAGpB,MAAMS,EAAc7K,EAAA,IAAM,CACxBmK,EAAc,MAAQ,GACtBC,EAAS,MAAQ,EACnB,EAHoB,eAKdU,EAAe9K,EAAA,IAAM,CACzBoK,EAAS,MAAQ,GACjBD,EAAc,MAAQ,EACxB,EAHqB,gBAKrB,OAAAY,GAAY,IAAM,CACZV,EAAU,OAAO,WAAW,OAAO,GACrCG,EAAWjK,EAAA,GAAG,CAElB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Load3D-BAJ3yM4D.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.legacy-dialog[data-v-44074ee0] .bg-comfy-menu-secondary{background-color:transparent}.legacy-dialog[data-v-44074ee0] .p-button{color:#fff}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var X=Object.defineProperty;var a=(m,c)=>X(m,"name",{value:c,configurable:!0});import{t as s,dx as I,a5 as G,m as V,a4 as Q,X as J,dy as Z,c as M,_ as L,d as U,A as ee,b as te}from"./index-DvCHS_f2.js";import{_ as se,a as oe}from"./GraphView-C35zkdNN.js";import{bx as j,E as T,j as ne,d as x,r as E,c as b,e,z as p,by as n,k as y,q as O,u as t,F as re,y as ae,s as F,l as le,A,v as ie,w as z,dc as ce}from"./vendor-other-B8t_Wf2K.js";import{v as de,p as ue}from"./vendor-primevue-Bp7MMXLP.js";import{u as pe}from"./vendor-vue-DaLZjKA7.js";import"./vendor-xterm-CWYFmgbN.js";import"./vendor-three-DH0o8VQ7.js";import"./vendor-tiptap-VxK0yxkd.js";import"./UserAvatar.vue_vue_type_script_setup_true_lang-48WRCWXz.js";import"./index-kQCr6fgp.js";import"./LazyImage.vue_vue_type_script_setup_true_lang-C58MdJKR.js";import"./keybindingService-D3pQ4cJG.js";import"./serverConfigStore-D8kGBwZ6.js";import"./WidgetInputNumber.vue_vue_type_script_setup_true_lang-vY96bQKz.js";import"./widgetPropFilter-CygYoMQt.js";import"./WidgetLayoutField.vue_vue_type_script_setup_true_lang-7bIn_5fI.js";import"./WidgetWithControl.vue_vue_type_script_setup_true_lang-CTEGWC4h.js";const me=j({__name:"CloudBadge",props:{displayMode:{default:"full"},reverseOrder:{type:Boolean,default:!1},noPadding:{type:Boolean,default:!1},backgroundColor:{default:"var(--comfy-menu-bg)"}},setup(m){const c=T(()=>({label:s("g.beta"),text:"Comfy Cloud"}));return(f,v)=>(x(),ne(se,{badge:c.value,"display-mode":f.displayMode,"reverse-order":f.reverseOrder,"no-padding":f.noPadding,"background-color":f.backgroundColor},null,8,["badge","display-mode","reverse-order","no-padding","background-color"]))}}),fe=""+new URL("images/cloud-subscription.webm",import.meta.url).href,xe=20,be=["yearly-pro","yearly-creator","yearly-standard","monthly-pro","monthly-creator","monthly-standard"];be.reduce((m,c,f)=>m.set(c,f),new Map);const ge={class:"flex flex-col gap-8"},_e={class:"flex justify-center"},ye={class:"flex items-center gap-2"},ve={key:0,class:"bg-primary-background text-white text-[11px] px-1 py-0.5 rounded-full flex items-center font-bold"},he={class:"flex flex-col xl:flex-row items-stretch gap-6"},we={class:"p-8 pb-0 flex flex-col gap-8"},ke={class:"flex flex-row items-center gap-2 justify-between"},$e={class:"font-inter text-base font-bold leading-normal text-base-foreground"},Ce={key:0,class:"rounded-full bg-base-foreground px-1.5 text-[11px] font-bold uppercase text-base-background h-5 tracking-tight flex items-center"},Le={class:"flex flex-col"},Pe={class:"flex flex-col gap-2"},Se={class:"flex flex-row items-baseline gap-2"},Ee={class:"font-inter text-[32px] font-semibold leading-normal text-base-foreground"},Te={class:"font-inter text-xl leading-normal text-base-foreground"},Ae={class:"flex items-center gap-2"},De={class:"text-sm text-muted-foreground"},Re={class:"flex flex-col gap-4 pb-0 flex-1"},Be={class:"flex flex-row items-center justify-between"},Ie={class:"font-inter text-sm font-normal leading-normal text-foreground"},je={class:"flex flex-row items-center gap-1"},Ne={class:"font-inter text-sm font-bold leading-normal text-base-foreground"},Me={class:"flex flex-row items-center justify-between"},Oe={class:"text-sm font-normal text-foreground"},Fe={class:"font-inter text-sm font-bold leading-normal text-base-foreground"},ze={class:"flex flex-row items-center justify-between"},Ve={class:"text-sm font-normal text-foreground"},Ue={class:"flex flex-row items-center justify-between"},He={class:"text-sm font-normal text-foreground"},Ye={class:"flex flex-row items-center justify-between"},qe={class:"text-sm font-normal text-foreground"},Ke={key:0,class:"pi pi-check text-xs text-success-foreground"},We={key:1,class:"pi pi-times text-xs text-foreground"},Xe={class:"flex flex-col gap-2"},Ge={class:"flex flex-row items-start justify-between"},Qe={class:"flex flex-col gap-2"},Je={class:"text-sm font-normal text-foreground leading-relaxed"},Ze={class:"flex flex-row items-center gap-2 group pt-2"},et={class:"font-inter text-sm font-bold leading-normal text-base-foreground"},tt={class:"flex flex-col p-8"},st={class:"flex flex-col gap-2"},ot={class:"text-sm text-base-foreground leading-normal"},nt={href:"https://cloud.comfy.org/?template=video_wan2_2_14B_fun_camera",target:"_blank",rel:"noopener noreferrer",class:"text-sm text-azure-600 hover:text-azure-400 no-underline flex gap-1"},rt={class:"underline"},at=j({__name:"PricingTable",setup(m){const c=[{label:s("subscription.yearly"),value:"yearly"},{label:s("subscription.monthly"),value:"monthly"}],f=[{id:"STANDARD",key:"standard",name:s("subscription.tiers.standard.name"),pricing:I.standard,maxDuration:s("subscription.maxDuration.standard"),customLoRAs:!1,isPopular:!1},{id:"CREATOR",key:"creator",name:s("subscription.tiers.creator.name"),pricing:I.creator,maxDuration:s("subscription.maxDuration.creator"),customLoRAs:!0,isPopular:!0},{id:"PRO",key:"pro",name:s("subscription.tiers.pro.name"),pricing:I.pro,maxDuration:s("subscription.maxDuration.pro"),customLoRAs:!0,isPopular:!1}],{n:v}=pe(),{getAuthHeader:N}=G(),{isActiveSubscription:D,subscriptionTier:P,isYearlySubscription:S}=V(),{accessBillingPortal:k,reportError:h}=Q(),{wrapWithErrorHandlingAsync:$}=J(),g=E(!1),R=E(null),w=E(),u=E("yearly"),_=T(()=>P.value?Z[P.value]:null);T(()=>_.value?{tierKey:_.value,billingCycle:S.value?"yearly":"monthly"}:null);const C=a(r=>{if(!_.value)return!1;const i=u.value==="yearly";return _.value===r&&S.value===i},"isCurrentPlan"),B=a(r=>{w.value.toggle(r)},"togglePopover"),l=a(r=>{if(C(r.key))return s("subscription.currentPlan");const i=u.value==="yearly"?s("subscription.tierNameYearly",{name:r.name}):r.name;return D.value?s("subscription.changeTo",{plan:i}):s("subscription.subscribeTo",{plan:i})},"getButtonLabel"),d=a(r=>C(r.key)?"secondary":r.key==="creator"?"primary":"secondary","getButtonSeverity"),H=a(r=>r.key==="creator"?"font-inter text-sm font-bold leading-normal text-base-background":"font-inter text-sm font-bold leading-normal text-primary-foreground","getButtonTextClass"),Y=a(r=>r.pricing[u.value],"getPrice"),q=a(r=>r.pricing.yearly*12,"getAnnualTotal"),K=a(r=>r.pricing.credits*(u.value==="yearly"?12:1),"getCreditsDisplay"),W=$(async r=>{},h);return(r,i)=>(x(),b("div",ge,[e("div",_e,[p(n(de),{modelValue:u.value,"onUpdate:modelValue":i[0]||(i[0]=o=>u.value=o),options:c,"option-label":"label","option-value":"value","allow-empty":!1,unstyled:"",pt:{root:{class:"flex gap-1 bg-secondary-background rounded-lg p-1.5"},pcToggleButton:{root:a(({context:o})=>({class:["w-36 h-8 rounded-md transition-colors cursor-pointer border-none outline-none ring-0 text-sm font-medium flex items-center justify-center",o.active?"bg-base-foreground text-base-background":"bg-transparent text-muted-foreground hover:bg-secondary-background-hover"]}),"root"),label:{class:"flex items-center gap-2 "}}}},{option:y(({option:o})=>[e("div",ye,[e("span",null,t(o.label),1),o.value==="yearly"?(x(),b("div",ve," -20% ")):O("",!0)])]),_:1},8,["modelValue","pt"])]),e("div",he,[(x(),b(re,null,ae(f,o=>e("div",{key:o.id,class:F(n(M)("flex-1 flex flex-col rounded-2xl border border-border-default bg-base-background shadow-[0_0_12px_rgba(0,0,0,0.1)]",o.isPopular?"border-muted-foreground":""))},[e("div",we,[e("div",ke,[e("span",$e,t(o.name),1),o.isPopular?(x(),b("div",Ce,t(n(s)("subscription.mostPopular")),1)):O("",!0)]),e("div",Le,[e("div",Pe,[e("div",Se,[e("span",Ee,[le(e("span",{class:"line-through text-2xl text-muted-foreground"}," $"+t(o.pricing.monthly),513),[[ie,u.value==="yearly"]]),A(" $"+t(Y(o)),1)]),e("span",Te,t(n(s)("subscription.usdPerMonth")),1)]),e("div",Ae,[e("span",De,t(u.value==="yearly"?n(s)("subscription.billedYearly",{total:`$${q(o)}`}):n(s)("subscription.billedMonthly")),1)])])]),e("div",Re,[e("div",Be,[e("span",Ie,t(u.value==="yearly"?n(s)("subscription.yearlyCreditsLabel"):n(s)("subscription.monthlyCreditsLabel")),1),e("div",je,[i[1]||(i[1]=e("i",{class:"icon-[lucide--component] text-amber-400 text-sm"},null,-1)),e("span",Ne,t(n(v)(K(o))),1)])]),e("div",Me,[e("span",Oe,t(n(s)("subscription.maxDurationLabel")),1),e("span",Fe,t(o.maxDuration),1)]),e("div",ze,[e("span",Ve,t(n(s)("subscription.gpuLabel")),1),i[2]||(i[2]=e("i",{class:"pi pi-check text-xs text-success-foreground"},null,-1))]),e("div",Ue,[e("span",He,t(n(s)("subscription.addCreditsLabel")),1),i[3]||(i[3]=e("i",{class:"pi pi-check text-xs text-success-foreground"},null,-1))]),e("div",Ye,[e("span",qe,t(n(s)("subscription.customLoRAsLabel")),1),o.customLoRAs?(x(),b("i",Ke)):(x(),b("i",We))]),e("div",Xe,[e("div",Ge,[e("div",Qe,[e("span",Je,t(n(s)("subscription.videoEstimateLabel")),1),e("div",Ze,[i[4]||(i[4]=e("i",{class:"pi pi-question-circle text-xs text-muted-foreground group-hover:text-base-foreground"},null,-1)),e("span",{class:"text-sm font-normal text-muted-foreground cursor-pointer group-hover:text-base-foreground",onClick:B},t(n(s)("subscription.videoEstimateHelp")),1)])]),e("span",et," ~"+t(n(v)(o.pricing.videoEstimate)),1)])])])]),e("div",tt,[p(L,{variant:d(o),disabled:g.value||C(o.key),loading:R.value===o.key,class:F(n(M)("h-10 w-full",H(o),o.key==="creator"?"bg-base-foreground border-transparent hover:bg-inverted-background-hover":"bg-secondary-background border-transparent hover:bg-secondary-background-hover focus:bg-secondary-background-selected")),onClick:a(()=>n(W)(o.key),"onClick")},{default:y(()=>[A(t(l(o)),1)]),_:2},1032,["variant","disabled","loading","class","onClick"])])],2)),64))]),p(n(ue),{ref_key:"popover",ref:w,"append-to":"body","auto-z-index":!0,"base-z-index":1e3,dismissable:!0,"close-on-escape":!0,unstyled:"",pt:{root:{class:"rounded-lg border border-interface-stroke bg-interface-panel-surface shadow-lg p-4 max-w-xs"}}},{default:y(()=>[e("div",st,[e("p",ot,t(n(s)("subscription.videoEstimateExplanation")),1),e("a",nt,[e("span",rt,t(n(s)("subscription.videoEstimateTryTemplate")),1),i[5]||(i[5]=e("span",{class:"no-underline",innerHTML:"→"},null,-1))])])]),_:1},512)]))}}),lt={},it={class:"flex flex-col items-start gap-0 self-stretch"},ct={class:"flex items-center gap-2 py-2"},dt={class:"text-sm text-text-primary"},ut={class:"flex items-center gap-2 py-2"},pt={class:"text-sm text-text-primary"};function mt(m,c){return x(),b("div",it,[e("div",ct,[c[0]||(c[0]=e("i",{class:"pi pi-check text-xs text-text-primary"},null,-1)),e("span",dt,t(m.$t("subscription.benefits.benefit1")),1)]),e("div",ut,[c[1]||(c[1]=e("i",{class:"pi pi-check text-xs text-text-primary"},null,-1)),e("span",pt,t(m.$t("subscription.benefits.benefit2")),1)])])}a(mt,"_sfc_render");const ft=U(lt,[["render",mt]]),xt={key:0,class:"relative flex flex-col p-4 pt-8 md:p-16 !overflow-y-auto h-full gap-8"},bt={class:"text-center"},gt={class:"text-xl lg:text-2xl text-muted-foreground m-0"},_t={class:"flex flex-col items-center gap-2"},yt={class:"text-sm text-text-secondary m-0"},vt={class:"flex items-center gap-1.5"},ht={class:"text-sm text-text-secondary"},wt={key:1,class:"legacy-dialog relative grid h-full grid-cols-5"},kt={class:"col-span-3 flex flex-col justify-between p-8"},$t={class:"flex flex-col gap-6"},Ct={class:"inline-flex items-center gap-2"},Lt={class:"text-sm text-text-primary"},Pt={class:"flex items-baseline gap-2"},St={class:"text-4xl font-bold"},Et={class:"text-xl"},Tt={class:"flex flex-col pt-8"},At=3e3,Dt=3,Rt=j({__name:"SubscriptionRequiredDialogContent",props:{onClose:{type:Function}},emits:["close"],setup(m,{emit:c}){const f=m,v=c,{fetchStatus:N,isActiveSubscription:D}=V(),P=new Intl.NumberFormat(navigator.language||"en-US",{style:"currency",currency:"USD",minimumFractionDigits:0,maximumFractionDigits:0}).format(xe),S=ee(),k=T(()=>te);let h=null,$=0;const g=a(()=>{h&&(clearInterval(h),h=null)},"stopPolling"),R=a(()=>{g(),$=0;const l=a(async()=>{try{await N(),$++,$>=Dt&&g()}catch(d){console.error("[SubscriptionDialog] Failed to poll subscription status",d),g()}},"poll");l(),h=window.setInterval(()=>{l()},At)},"startPolling"),w=a(()=>{k.value&&R()},"handleWindowFocus");z(k,l=>{l?window.addEventListener("focus",w):(window.removeEventListener("focus",w),g())},{immediate:!0}),z(()=>D.value,l=>{l&&k.value&&v("close",!0)});const u=a(()=>{v("close",!0)},"handleSubscribed"),_=a(()=>{g(),f.onClose()},"handleClose"),C=a(async()=>{await S.execute("Comfy.ContactSupport")},"handleContactUs"),B=a(()=>{window.open("https://www.comfy.org/cloud/enterprise","_blank")},"handleViewEnterprise");return ce(()=>{g(),window.removeEventListener("focus",w)}),(l,d)=>k.value?(x(),b("div",xt,[p(L,{size:"icon",variant:"muted-textonly",class:"rounded-full shrink-0 text-text-secondary hover:bg-white/10 absolute right-2.5 top-2.5","aria-label":l.$t("g.close"),onClick:_},{default:y(()=>d[0]||(d[0]=[e("i",{class:"pi pi-times text-xl"},null,-1)])),_:1},8,["aria-label"]),e("div",bt,[e("h2",gt,t(l.$t("subscription.description")),1)]),p(at,{class:"flex-1"}),e("div",_t,[e("p",yt,t(l.$t("subscription.haveQuestions")),1),e("div",vt,[p(L,{variant:"muted-textonly",class:"h-6 p-1 text-sm text-text-secondary hover:text-base-foreground",onClick:C},{default:y(()=>[A(t(l.$t("subscription.contactUs"))+" ",1),d[1]||(d[1]=e("i",{class:"pi pi-comments"},null,-1))]),_:1}),e("span",ht,t(l.$t("g.or")),1),p(L,{variant:"muted-textonly",class:"h-6 p-1 text-sm text-text-secondary hover:text-base-foreground",onClick:B},{default:y(()=>[A(t(l.$t("subscription.viewEnterprise"))+" ",1),d[2]||(d[2]=e("i",{class:"pi pi-external-link"},null,-1))]),_:1})])])])):(x(),b("div",wt,[p(L,{size:"icon",variant:"muted-textonly",class:"rounded-full absolute top-2.5 right-2.5 z-10 h-8 w-8 p-0 text-white hover:bg-white/20","aria-label":l.$t("g.close"),onClick:_},{default:y(()=>d[3]||(d[3]=[e("i",{class:"pi pi-times"},null,-1)])),_:1},8,["aria-label"]),d[4]||(d[4]=e("div",{class:"relative col-span-2 flex items-center justify-center overflow-hidden rounded-sm"},[e("video",{autoplay:"",loop:"",muted:"",playsinline:"",class:"h-full min-w-[125%] object-cover p-0",style:{"margin-left":"-20%"}},[e("source",{src:fe,type:"video/webm"})])],-1)),e("div",kt,[e("div",null,[e("div",$t,[e("div",Ct,[e("div",Lt,t(l.$t("subscription.required.title")),1),p(me,{"reverse-order":"","no-padding":"","background-color":"var(--p-dialog-background)","use-subscription":""})]),e("div",Pt,[e("span",St,t(n(P)),1),e("span",Et,t(l.$t("subscription.perMonth")),1)])]),p(ft,{class:"mt-6 text-muted"})]),e("div",Tt,[p(oe,{class:"py-2 px-4 rounded-lg",pt:{root:{style:"background: var(--color-accent-blue, #0B8CE9);"},label:{class:"font-inter font-[700] text-sm"}},onSubscribed:u})])])]))}}),Jt=U(Rt,[["__scopeId","data-v-44074ee0"]]);export{Jt as default};
|
|
2
|
-
//# sourceMappingURL=SubscriptionRequiredDialogContent-CDaF1jns.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{_ as o}from"./WidgetInputNumber.vue_vue_type_script_setup_true_lang-vY96bQKz.js";import"./vendor-primevue-Bp7MMXLP.js";import"./vendor-other-B8t_Wf2K.js";import"./index-DvCHS_f2.js";import"./vendor-vue-DaLZjKA7.js";import"./vendor-xterm-CWYFmgbN.js";import"./vendor-three-DH0o8VQ7.js";import"./vendor-tiptap-VxK0yxkd.js";import"./widgetPropFilter-CygYoMQt.js";import"./index-kQCr6fgp.js";import"./WidgetLayoutField.vue_vue_type_script_setup_true_lang-7bIn_5fI.js";import"./WidgetWithControl.vue_vue_type_script_setup_true_lang-CTEGWC4h.js";export{o as default};
|
|
2
|
-
//# sourceMappingURL=WidgetInputNumber-Cnhf4Ann.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WidgetInputNumber-Cnhf4Ann.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a_ as o}from"./index-DvCHS_f2.js";import"./vendor-primevue-Bp7MMXLP.js";import"./vendor-other-B8t_Wf2K.js";import"./vendor-vue-DaLZjKA7.js";import"./vendor-xterm-CWYFmgbN.js";import"./vendor-three-DH0o8VQ7.js";import"./vendor-tiptap-VxK0yxkd.js";export{o as default};
|
|
2
|
-
//# sourceMappingURL=WidgetLegacy-AkIJRd8v.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WidgetLegacy-AkIJRd8v.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var p=Object.defineProperty;var s=(t,a)=>p(t,"name",{value:a,configurable:!0});import{bx as c,cM as v,cN as w,r as n,E as g,c as k,d as b,e as M,l as V,s as y,v as $,z as x,I as i,by as B,n as h}from"./vendor-other-B8t_Wf2K.js";import{a9 as z}from"./vendor-primevue-Bp7MMXLP.js";import{br as E}from"./index-DvCHS_f2.js";import"./vendor-vue-DaLZjKA7.js";import"./vendor-xterm-CWYFmgbN.js";import"./vendor-three-DH0o8VQ7.js";import"./vendor-tiptap-VxK0yxkd.js";const H=["innerHTML"],S=c({__name:"WidgetMarkdown",props:v({widget:{}},{modelValue:{default:""},modelModifiers:{}}),emits:["update:modelValue"],setup(t){const a=w(t,"modelValue"),l=n(!1),r=n(),d=g(()=>E(a.value||"")),u=s(async()=>{l.value||t.widget.options?.read_only||(l.value=!0,await h(),r.value?.$el?.focus())},"startEditing"),m=s(()=>{l.value=!1},"handleBlur");return(o,e)=>(b(),k("div",{class:"widget-markdown relative w-full",onDblclick:u},[M("div",{class:y(["comfy-markdown-content size-full min-h-[60px] overflow-y-auto rounded-lg text-sm",l.value===!1?"visible":"invisible"]),innerHTML:d.value},null,10,H),V(x(B(z),{ref_key:"textareaRef",ref:r,modelValue:a.value,"onUpdate:modelValue":e[0]||(e[0]=f=>a.value=f),"aria-label":`${o.$t("g.edit")} ${o.widget.name||o.$t("g.markdown")} ${o.$t("g.content")}`,class:"absolute inset-0 min-h-[60px] w-full resize-none",pt:{root:{class:"text-sm w-full h-full",onBlur:m}},"data-capture-wheel":"true",onClick:e[1]||(e[1]=i(()=>{},["stop"])),onKeydown:e[2]||(e[2]=i(()=>{},["stop"]))},null,8,["modelValue","aria-label","pt"]),[[$,l.value]])],32))}});export{S as default};
|
|
2
|
-
//# sourceMappingURL=WidgetMarkdown-voa7Ohgp.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var $=Object.defineProperty;var a=(i,l)=>$(i,"name",{value:l,configurable:!0});import{bk as G,c as b,d as k,e as h,r as v,n as K,cd as F,eG as J,bx as Q,cM as X,de as Y,E as N,cN as Z,o as ee,q as U,z as q,k as ae,A as te,u as V,by as n,F as ne,y as oe,G as le}from"./vendor-other-B8t_Wf2K.js";import{r as D,t as R,f as H}from"./index-DvCHS_f2.js";import{u as O}from"./audioService-BcbrJBnn.js";import{f as re}from"./audioUtils-CJCA0wCG.js";import{ab as ie}from"./vendor-primevue-Bp7MMXLP.js";import"./vendor-vue-DaLZjKA7.js";import"./vendor-xterm-CWYFmgbN.js";import"./vendor-three-DH0o8VQ7.js";import"./vendor-tiptap-VxK0yxkd.js";const ue={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function se(i,l){return k(),b("svg",ue,[...l[0]||(l[0]=[h("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[h("path",{d:"M12 19v3m7-12v2a7 7 0 0 1-14 0v-2"}),h("rect",{width:"6",height:"13",x:"9",y:"2",rx:"3"})],-1)])])}a(se,"render");const ce=G({name:"lucide-mic",render:se});function de(i,l={}){const o=v(!1),f=v(0),u=v(null);async function e(){if(!i.value)return!1;try{return await i.value.play(),o.value=!0,!0}catch(A){return console.warn("Audio playback failed:",A),o.value=!1,!1}}a(e,"play");function t(){i.value&&(i.value.pause(),i.value.currentTime=0),o.value=!1,l.onPlaybackEnded&&l.onPlaybackEnded()}a(t,"stop");function s(){o.value=!1,l.onPlaybackEnded&&l.onPlaybackEnded()}a(s,"onPlaybackEnded");function g(){i.value?.duration&&l.onMetadataLoaded&&l.onMetadataLoaded(i.value.duration)}a(g,"onMetadataLoaded");async function p(){f.value+=1,await K()}a(p,"resetAudioElement");function r(){return i.value?.currentTime||0}a(r,"getCurrentTime");function y(){return i.value?.duration||0}return a(y,"getDuration"),{isPlaying:o,audioElementKey:f,play:e,stop:t,onPlaybackEnded:s,onMetadataLoaded:g,resetAudioElement:p,getCurrentTime:r,getDuration:y,playbackTimerInterval:u}}a(de,"useAudioPlayback");function ve(i={}){const l=v(!1),o=v(null),f=v([]),u=v(null),e=v(null);async function t(){try{e.value?.startsWith("blob:")&&URL.revokeObjectURL(e.value),f.value=[],e.value=null,await O().registerWavEncoder(),u.value=await navigator.mediaDevices.getUserMedia({audio:!0}),o.value=new J(u.value,{mimeType:"audio/wav"}),o.value.ondataavailable=r=>{f.value.push(r.data)},o.value.onstop=async()=>{const r=new Blob(f.value,{type:"audio/wav"});e.value?.startsWith("blob:")&&URL.revokeObjectURL(e.value),e.value=URL.createObjectURL(r),i.onRecordingComplete&&await i.onRecordingComplete(r),g()},o.value.start(100),l.value=!0}catch(r){throw i.onError&&i.onError(r),r}}a(t,"startRecording");function s(){o.value&&o.value.state!=="inactive"?o.value.stop():g()}a(s,"stopRecording");function g(){l.value=!1,u.value&&(u.value.getTracks().forEach(r=>r.stop()),u.value=null)}a(g,"cleanup");function p(){s(),e.value&&(URL.revokeObjectURL(e.value),e.value=null)}return a(p,"dispose"),F(()=>{p()}),{isRecording:l,recordedURL:e,mediaRecorder:o,startRecording:t,stopRecording:s,dispose:p}}a(ve,"useAudioRecorder");function me(i={}){const{barCount:l=18,minHeight:o=4,maxHeight:f=32}=i,u=v(Array.from({length:l},()=>({height:16}))),e=v(null),t=v(null),s=v(null),g=v(null),p=v(null);function r(){u.value=Array.from({length:l},()=>({height:Math.random()*(f-o)+o}))}a(r,"initWaveform");function y(m){m.value&&(t.value&&s.value?A():w(),g.value=requestAnimationFrame(()=>y(m)))}a(y,"updateWaveform");function A(){if(!t.value||!s.value)return;t.value.getByteFrequencyData(s.value);const m=Math.floor(s.value.length/l);u.value=u.value.map((L,I)=>{let S=0;for(let P=0;P<m;P++)S+=s.value[I*m+P]||0;return{height:S/m/255*(f-o)+o}})}a(A,"updateWaveformFromAudio");function w(){u.value=u.value.map(m=>({height:Math.max(o,Math.min(f,m.height+(Math.random()-.5)*4))}))}a(w,"updateWaveformRandom");async function W(){e.value&&e.value.state!=="closed"&&await e.value.close(),e.value=null,p.value=null}a(W,"setupAudioContext");async function E(m){e.value=new window.AudioContext,t.value=e.value.createAnalyser(),e.value.createMediaStreamSource(m).connect(t.value),t.value.fftSize=256,s.value=new Uint8Array(t.value.frequencyBinCount)}a(E,"setupRecordingVisualization");async function C(m){return e.value&&e.value.state!=="closed"&&await e.value.close(),p.value=null,m?(e.value=new window.AudioContext,t.value=e.value.createAnalyser(),p.value=e.value.createMediaElementSource(m),p.value.connect(t.value),t.value.connect(e.value.destination),t.value.fftSize=256,s.value=new Uint8Array(t.value.frequencyBinCount),!0):!1}a(C,"setupPlaybackVisualization");function T(){g.value&&(cancelAnimationFrame(g.value),g.value=null)}a(T,"stopWaveform");function z(){T(),e.value&&e.value.state!=="closed"&&e.value.close(),e.value=null,p.value=null}return a(z,"dispose"),F(()=>{z()}),{waveformBars:u,initWaveform:r,updateWaveform:y,setupAudioContext:W,setupRecordingVisualization:E,setupPlaybackVisualization:C,stopWaveform:T,dispose:z}}a(me,"useAudioWaveform");const fe={class:"relative"},pe={class:"mb-4"},ge={key:0,class:"flex h-14 w-full items-center gap-4 rounded-lg px-4 bg-node-component-surface text-text-secondary"},ye={class:"flex min-w-30 items-center gap-2"},he={class:"min-w-20 text-xs"},be={class:"min-w-10 text-sm"},ke={class:"flex h-8 flex-1 items-center gap-2 overflow-x-clip"},we=["title"],xe=["title"],Re=["title"],_e=["title"],Ae=["src"],Be=Q({__name:"WidgetRecordAudio",props:X({readonly:{type:Boolean},nodeId:{}},{modelValue:{default:""},modelModifiers:{}}),emits:["update:modelValue"],setup(i){const l=i,o=v();let f="";const u=ve({onRecordingComplete:z,onError:a(()=>{H().addAlert(R("g.micPermissionDenied")||"Microphone permission denied")},"onError")}),e=me({barCount:18,minHeight:4,maxHeight:32}),t=de(o,{onPlaybackEnded:B,onMetadataLoaded:a(d=>{!w.value&&!r.value&&(s.value=Math.floor(d))},"onMetadataLoaded")}),s=v(0),{pause:g,resume:p}=Y(()=>{s.value+=1},1e3,{immediate:!1}),{isRecording:r,recordedURL:y}=u,{waveformBars:A}=e,{isPlaying:w,audioElementKey:W}=t,E=N(()=>r.value||w.value),C=Z(i,"modelValue"),T=N(()=>!l.nodeId||!D.canvas.graph?null:D.canvas.graph.getNodeById(l.nodeId));async function z(d){try{const c=await O().convertBlobToFileAndSubmit(d);C.value=c,f=c}catch{H().addAlert("Failed to upload recorded audio")}}a(z,"handleRecordingComplete");async function m(){if(!l.readonly)try{if(await e.setupAudioContext(),await u.startRecording(),u.mediaRecorder.value){const d=u.mediaRecorder.value.stream;d&&await e.setupRecordingVisualization(d)}s.value=0,p(),e.initWaveform(),e.updateWaveform(E)}catch(d){console.error("Failed to start recording:",d)}}a(m,"handleStartRecording");function L(){u.stopRecording(),g(),e.stopWaveform()}a(L,"handleStopRecording");async function I(){if(!y.value||(s.value=0,await t.resetAudioElement(),await new Promise(_=>setTimeout(_,50)),!o.value)||!await e.setupPlaybackVisualization(o.value))return;await t.play(),e.initWaveform(),e.updateWaveform(E);const c=setInterval(()=>{s.value=Math.floor(t.getCurrentTime())},100);t.playbackTimerInterval.value=c}a(I,"handlePlayRecording");function S(){t.stop(),B()}a(S,"handleStopPlayback");function B(){e.stopWaveform(),t.playbackTimerInterval.value!==null&&(clearInterval(t.playbackTimerInterval.value),t.playbackTimerInterval.value=null);const d=t.getDuration();d?s.value=Math.floor(d):s.value=0}a(B,"handlePlaybackEnded");async function j(){return r.value&&u.mediaRecorder.value&&(u.mediaRecorder.value.stop(),await new Promise((d,c)=>{let _=0;const x=50,M=a(()=>{!r.value&&C.value?d(void 0):++_>=x?c(new Error("Recording serialization timeout after 5 seconds")):setTimeout(M,100)},"checkRecording");M()})),C.value||f||""}a(j,"serializeValue");function P(){const d=T.value;if(!d?.widgets)return;const c=d.widgets.find(_=>_.name==="audio");c&&(c.serializeValue=j)}return a(P,"registerWidgetSerialization"),ee(()=>{e.initWaveform(),P()}),F(()=>{t.playbackTimerInterval.value!==null&&(clearInterval(t.playbackTimerInterval.value),t.playbackTimerInterval.value=null)}),(d,c)=>{const _=ce;return k(),b("div",fe,[h("div",pe,[q(n(ie),{class:"text-base-foreground w-full border-0 bg-secondary-background hover:bg-secondary-background-hover",disabled:n(r)||d.readonly,onClick:m},{default:ae(()=>[te(V(n(R)("g.startRecording","Start Recording"))+" ",1),q(_,{class:"ml-1"})]),_:1},8,["disabled"])]),n(r)||n(w)||n(y)?(k(),b("div",ge,[h("div",ye,[h("span",he,V(n(r)?n(R)("g.listening","Listening..."):n(w)?n(R)("g.playing","Playing..."):n(y)?n(R)("g.ready","Ready"):""),1),h("span",be,V(n(re)(s.value)),1)]),h("div",ke,[(k(!0),b(ne,null,oe(n(A),(x,M)=>(k(),b("div",{key:M,class:"max-h-8 min-h-1 w-0.75 rounded-[1.5px] bg-slate-100 transition-all duration-100",style:le({height:x.height+"px"}),title:`Bar ${M+1}: ${x.height}px`},null,12,we))),128))]),n(r)?(k(),b("button",{key:0,title:n(R)("g.stopRecording","Stop Recording"),class:"flex size-8 animate-pulse items-center justify-center rounded-full border-0 bg-smoke-500/33 transition-colors",onClick:L},c[2]||(c[2]=[h("div",{class:"size-2.5 rounded-sm bg-danger-100"},null,-1)]),8,xe)):!n(r)&&n(y)&&!n(w)?(k(),b("button",{key:1,title:n(R)("g.playRecording")||"Play Recording",class:"flex size-8 items-center justify-center rounded-full border-0 bg-smoke-500/33 transition-colors",onClick:I},c[3]||(c[3]=[h("i",{class:"text-text-secondary icon-[lucide--play] size-4"},null,-1)]),8,Re)):n(w)?(k(),b("button",{key:2,title:n(R)("g.stopPlayback")||"Stop Playback",class:"flex size-8 items-center justify-center rounded-full border-0 bg-smoke-500/33 transition-colors",onClick:S},c[4]||(c[4]=[h("i",{class:"text-text-secondary icon-[lucide--square] size-4"},null,-1)]),8,_e)):U("",!0)])):U("",!0),n(y)?(k(),b("audio",{ref_key:"audioRef",ref:o,key:n(W),src:n(y),class:"hidden",onEnded:c[0]||(c[0]=(...x)=>n(t).onPlaybackEnded&&n(t).onPlaybackEnded(...x)),onLoadedmetadata:c[1]||(c[1]=(...x)=>n(t).onMetadataLoaded&&n(t).onMetadataLoaded(...x))},null,40,Ae)):U("",!0)])}}});export{Be as default};
|
|
2
|
-
//# sourceMappingURL=WidgetRecordAudio-DelweXYm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WidgetRecordAudio-DelweXYm.js","sources":["../../src/renderer/extensions/vueNodes/widgets/composables/audio/useAudioPlayback.ts","../../src/renderer/extensions/vueNodes/widgets/composables/audio/useAudioRecorder.ts","../../src/renderer/extensions/vueNodes/widgets/composables/audio/useAudioWaveform.ts","../../src/renderer/extensions/vueNodes/widgets/components/WidgetRecordAudio.vue"],"sourcesContent":["import { nextTick, ref } from 'vue'\nimport type { Ref } from 'vue'\n\ninterface AudioPlaybackOptions {\n onPlaybackEnded?: () => void\n onMetadataLoaded?: (duration: number) => void\n}\n\nexport function useAudioPlayback(\n audioRef: Ref<HTMLAudioElement | undefined>,\n options: AudioPlaybackOptions = {}\n) {\n const isPlaying = ref(false)\n const audioElementKey = ref(0)\n const playbackTimerInterval = ref<ReturnType<typeof setInterval> | null>(null)\n\n async function play() {\n if (!audioRef.value) return false\n\n try {\n await audioRef.value.play()\n isPlaying.value = true\n return true\n } catch (error) {\n console.warn('Audio playback failed:', error)\n isPlaying.value = false\n return false\n }\n }\n\n function stop() {\n if (audioRef.value) {\n audioRef.value.pause()\n audioRef.value.currentTime = 0\n }\n isPlaying.value = false\n if (options.onPlaybackEnded) {\n options.onPlaybackEnded()\n }\n }\n\n function onPlaybackEnded() {\n isPlaying.value = false\n if (options.onPlaybackEnded) {\n options.onPlaybackEnded()\n }\n }\n\n function onMetadataLoaded() {\n if (audioRef.value?.duration && options.onMetadataLoaded) {\n options.onMetadataLoaded(audioRef.value.duration)\n }\n }\n\n async function resetAudioElement() {\n audioElementKey.value += 1\n await nextTick()\n }\n\n function getCurrentTime() {\n return audioRef.value?.currentTime || 0\n }\n\n function getDuration() {\n return audioRef.value?.duration || 0\n }\n\n return {\n isPlaying,\n audioElementKey,\n play,\n stop,\n onPlaybackEnded,\n onMetadataLoaded,\n resetAudioElement,\n getCurrentTime,\n getDuration,\n playbackTimerInterval\n }\n}\n","import { MediaRecorder as ExtendableMediaRecorder } from 'extendable-media-recorder'\nimport { onUnmounted, ref } from 'vue'\n\nimport { useAudioService } from '@/services/audioService'\n\ninterface AudioRecorderOptions {\n onRecordingComplete?: (audioBlob: Blob) => Promise<void>\n onError?: (error: Error) => void\n}\n\nexport function useAudioRecorder(options: AudioRecorderOptions = {}) {\n const isRecording = ref(false)\n const mediaRecorder = ref<MediaRecorder | null>(null)\n const audioChunks = ref<Blob[]>([])\n const stream = ref<MediaStream | null>(null)\n const recordedURL = ref<string | null>(null)\n\n async function startRecording() {\n try {\n // Clean up previous recording\n if (recordedURL.value?.startsWith('blob:')) {\n URL.revokeObjectURL(recordedURL.value)\n }\n\n // Initialize\n audioChunks.value = []\n recordedURL.value = null\n\n // Register wav encoder and get media stream\n await useAudioService().registerWavEncoder()\n stream.value = await navigator.mediaDevices.getUserMedia({ audio: true })\n\n // Create media recorder\n mediaRecorder.value = new ExtendableMediaRecorder(stream.value, {\n mimeType: 'audio/wav'\n }) as unknown as MediaRecorder\n\n mediaRecorder.value.ondataavailable = (e) => {\n audioChunks.value.push(e.data)\n }\n\n mediaRecorder.value.onstop = async () => {\n const blob = new Blob(audioChunks.value, { type: 'audio/wav' })\n\n // Create blob URL for preview\n if (recordedURL.value?.startsWith('blob:')) {\n URL.revokeObjectURL(recordedURL.value)\n }\n recordedURL.value = URL.createObjectURL(blob)\n\n // Notify completion\n if (options.onRecordingComplete) {\n await options.onRecordingComplete(blob)\n }\n\n cleanup()\n }\n\n // Start recording\n mediaRecorder.value.start(100)\n isRecording.value = true\n } catch (err) {\n if (options.onError) {\n options.onError(err as Error)\n }\n throw err\n }\n }\n\n function stopRecording() {\n if (mediaRecorder.value && mediaRecorder.value.state !== 'inactive') {\n mediaRecorder.value.stop()\n } else {\n cleanup()\n }\n }\n\n function cleanup() {\n isRecording.value = false\n\n if (stream.value) {\n stream.value.getTracks().forEach((track) => track.stop())\n stream.value = null\n }\n }\n\n function dispose() {\n stopRecording()\n if (recordedURL.value) {\n URL.revokeObjectURL(recordedURL.value)\n recordedURL.value = null\n }\n }\n\n onUnmounted(() => {\n dispose()\n })\n\n return {\n isRecording,\n recordedURL,\n mediaRecorder,\n startRecording,\n stopRecording,\n dispose\n }\n}\n","import { onUnmounted, ref } from 'vue'\nimport type { Ref } from 'vue'\n\ninterface WaveformBar {\n height: number\n}\n\ninterface AudioWaveformOptions {\n barCount?: number\n minHeight?: number\n maxHeight?: number\n}\n\nexport function useAudioWaveform(options: AudioWaveformOptions = {}) {\n const { barCount = 18, minHeight = 4, maxHeight = 32 } = options\n\n const waveformBars = ref<WaveformBar[]>(\n Array.from({ length: barCount }, () => ({ height: 16 }))\n )\n const audioContext = ref<AudioContext | null>(null)\n const analyser = ref<AnalyserNode | null>(null)\n const dataArray = ref<Uint8Array | null>(null)\n const animationId = ref<number | null>(null)\n const mediaElementSource = ref<MediaElementAudioSourceNode | null>(null)\n\n function initWaveform() {\n waveformBars.value = Array.from({ length: barCount }, () => ({\n height: Math.random() * (maxHeight - minHeight) + minHeight\n }))\n }\n\n function updateWaveform(isActive: Ref<boolean>) {\n if (!isActive.value) return\n\n if (analyser.value && dataArray.value) {\n updateWaveformFromAudio()\n } else {\n updateWaveformRandom()\n }\n\n animationId.value = requestAnimationFrame(() => updateWaveform(isActive))\n }\n\n function updateWaveformFromAudio() {\n if (!analyser.value || !dataArray.value) return\n\n analyser.value.getByteFrequencyData(\n dataArray.value as Uint8Array<ArrayBuffer>\n )\n const samplesPerBar = Math.floor(dataArray.value.length / barCount)\n\n waveformBars.value = waveformBars.value.map((_, i) => {\n let sum = 0\n for (let j = 0; j < samplesPerBar; j++) {\n sum += dataArray.value![i * samplesPerBar + j] || 0\n }\n const average = sum / samplesPerBar\n const normalizedHeight =\n (average / 255) * (maxHeight - minHeight) + minHeight\n return { height: normalizedHeight }\n })\n }\n\n function updateWaveformRandom() {\n waveformBars.value = waveformBars.value.map((bar) => ({\n height: Math.max(\n minHeight,\n Math.min(maxHeight, bar.height + (Math.random() - 0.5) * 4)\n )\n }))\n }\n\n async function setupAudioContext() {\n if (audioContext.value && audioContext.value.state !== 'closed') {\n await audioContext.value.close()\n }\n audioContext.value = null\n mediaElementSource.value = null\n }\n\n async function setupRecordingVisualization(stream: MediaStream) {\n audioContext.value = new window.AudioContext()\n analyser.value = audioContext.value.createAnalyser()\n const source = audioContext.value.createMediaStreamSource(stream)\n source.connect(analyser.value)\n\n analyser.value.fftSize = 256\n dataArray.value = new Uint8Array(analyser.value.frequencyBinCount)\n }\n\n async function setupPlaybackVisualization(audioElement: HTMLAudioElement) {\n if (audioContext.value && audioContext.value.state !== 'closed') {\n await audioContext.value.close()\n }\n\n mediaElementSource.value = null\n\n if (!audioElement) return false\n\n audioContext.value = new window.AudioContext()\n analyser.value = audioContext.value.createAnalyser()\n\n mediaElementSource.value =\n audioContext.value.createMediaElementSource(audioElement)\n\n mediaElementSource.value.connect(analyser.value)\n analyser.value.connect(audioContext.value.destination)\n\n analyser.value.fftSize = 256\n dataArray.value = new Uint8Array(analyser.value.frequencyBinCount)\n\n return true\n }\n\n function stopWaveform() {\n if (animationId.value) {\n cancelAnimationFrame(animationId.value)\n animationId.value = null\n }\n }\n\n function dispose() {\n stopWaveform()\n if (audioContext.value && audioContext.value.state !== 'closed') {\n void audioContext.value.close()\n }\n audioContext.value = null\n mediaElementSource.value = null\n }\n\n onUnmounted(() => {\n dispose()\n })\n\n return {\n waveformBars,\n initWaveform,\n updateWaveform,\n setupAudioContext,\n setupRecordingVisualization,\n setupPlaybackVisualization,\n stopWaveform,\n dispose\n }\n}\n","<template>\n <div class=\"relative\">\n <div class=\"mb-4\">\n <Button\n class=\"text-base-foreground w-full border-0 bg-secondary-background hover:bg-secondary-background-hover\"\n :disabled=\"isRecording || readonly\"\n @click=\"handleStartRecording\"\n >\n {{ t('g.startRecording', 'Start Recording') }}\n <i-lucide:mic class=\"ml-1\" />\n </Button>\n </div>\n <div\n v-if=\"isRecording || isPlaying || recordedURL\"\n class=\"flex h-14 w-full items-center gap-4 rounded-lg px-4 bg-node-component-surface text-text-secondary\"\n >\n <!-- Recording Status -->\n <div class=\"flex min-w-30 items-center gap-2\">\n <span class=\"min-w-20 text-xs\">\n {{\n isRecording\n ? t('g.listening', 'Listening...')\n : isPlaying\n ? t('g.playing', 'Playing...')\n : recordedURL\n ? t('g.ready', 'Ready')\n : ''\n }}\n </span>\n <span class=\"min-w-10 text-sm\">{{ formatTime(timer) }}</span>\n </div>\n\n <!-- Waveform Visualization -->\n <div class=\"flex h-8 flex-1 items-center gap-2 overflow-x-clip\">\n <div\n v-for=\"(bar, index) in waveformBars\"\n :key=\"index\"\n class=\"max-h-8 min-h-1 w-0.75 rounded-[1.5px] bg-slate-100 transition-all duration-100\"\n :style=\"{ height: bar.height + 'px' }\"\n :title=\"`Bar ${index + 1}: ${bar.height}px`\"\n />\n </div>\n\n <!-- Control Button -->\n <button\n v-if=\"isRecording\"\n :title=\"t('g.stopRecording', 'Stop Recording')\"\n class=\"flex size-8 animate-pulse items-center justify-center rounded-full border-0 bg-smoke-500/33 transition-colors\"\n @click=\"handleStopRecording\"\n >\n <div class=\"size-2.5 rounded-sm bg-danger-100\" />\n </button>\n\n <button\n v-else-if=\"!isRecording && recordedURL && !isPlaying\"\n :title=\"t('g.playRecording') || 'Play Recording'\"\n class=\"flex size-8 items-center justify-center rounded-full border-0 bg-smoke-500/33 transition-colors\"\n @click=\"handlePlayRecording\"\n >\n <i class=\"text-text-secondary icon-[lucide--play] size-4\" />\n </button>\n\n <button\n v-else-if=\"isPlaying\"\n :title=\"t('g.stopPlayback') || 'Stop Playback'\"\n class=\"flex size-8 items-center justify-center rounded-full border-0 bg-smoke-500/33 transition-colors\"\n @click=\"handleStopPlayback\"\n >\n <i class=\"text-text-secondary icon-[lucide--square] size-4\" />\n </button>\n </div>\n <audio\n v-if=\"recordedURL\"\n ref=\"audioRef\"\n :key=\"audioElementKey\"\n :src=\"recordedURL\"\n class=\"hidden\"\n @ended=\"playback.onPlaybackEnded\"\n @loadedmetadata=\"playback.onMetadataLoaded\"\n />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useIntervalFn } from '@vueuse/core'\nimport { Button } from 'primevue'\nimport { computed, onMounted, onUnmounted, ref } from 'vue'\n\nimport { t } from '@/i18n'\nimport type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'\nimport type { IBaseWidget } from '@/lib/litegraph/src/types/widgets'\nimport { useToastStore } from '@/platform/updates/common/toastStore'\nimport { app } from '@/scripts/app'\nimport { useAudioService } from '@/services/audioService'\n\nimport { useAudioPlayback } from '../composables/audio/useAudioPlayback'\nimport { useAudioRecorder } from '../composables/audio/useAudioRecorder'\nimport { useAudioWaveform } from '../composables/audio/useAudioWaveform'\nimport { formatTime } from '../utils/audioUtils'\n\nconst props = defineProps<{\n readonly?: boolean\n nodeId: string\n}>()\n\n// Audio element ref\nconst audioRef = ref<HTMLAudioElement>()\n\n// Keep track of the last uploaded path as a backup\nlet lastUploadedPath = ''\n\n// Composables\nconst recorder = useAudioRecorder({\n onRecordingComplete: handleRecordingComplete,\n onError: () => {\n useToastStore().addAlert(\n t('g.micPermissionDenied') || 'Microphone permission denied'\n )\n }\n})\n\nconst waveform = useAudioWaveform({\n barCount: 18,\n minHeight: 4,\n maxHeight: 32\n})\n\nconst playback = useAudioPlayback(audioRef, {\n onPlaybackEnded: handlePlaybackEnded,\n onMetadataLoaded: (duration) => {\n if (!isPlaying.value && !isRecording.value) {\n timer.value = Math.floor(duration)\n }\n }\n})\n\n// Timer for recording\nconst timer = ref(0)\nconst { pause: pauseTimer, resume: resumeTimer } = useIntervalFn(\n () => {\n timer.value += 1\n },\n 1000,\n { immediate: false }\n)\n\n// Destructure for template access\nconst { isRecording, recordedURL } = recorder\nconst { waveformBars } = waveform\nconst { isPlaying, audioElementKey } = playback\n\n// Computed for waveform animation\nconst isWaveformActive = computed(() => isRecording.value || isPlaying.value)\n\nconst modelValue = defineModel<string>({ default: '' })\n\nconst litegraphNode = computed(() => {\n if (!props.nodeId || !app.canvas.graph) return null\n return app.canvas.graph.getNodeById(props.nodeId) as LGraphNode | null\n})\n\nasync function handleRecordingComplete(blob: Blob) {\n try {\n const path = await useAudioService().convertBlobToFileAndSubmit(blob)\n modelValue.value = path\n lastUploadedPath = path\n } catch (e) {\n useToastStore().addAlert('Failed to upload recorded audio')\n }\n}\n\nasync function handleStartRecording() {\n if (props.readonly) return\n\n try {\n await waveform.setupAudioContext()\n await recorder.startRecording()\n\n // Setup waveform visualization for recording\n if (recorder.mediaRecorder.value) {\n const stream = recorder.mediaRecorder.value.stream\n if (stream) {\n await waveform.setupRecordingVisualization(stream)\n }\n }\n\n // Start timer\n timer.value = 0\n resumeTimer()\n waveform.initWaveform()\n waveform.updateWaveform(isWaveformActive)\n } catch (err) {\n console.error('Failed to start recording:', err)\n }\n}\n\nfunction handleStopRecording() {\n recorder.stopRecording()\n pauseTimer()\n waveform.stopWaveform()\n}\n\nasync function handlePlayRecording() {\n if (!recordedURL.value) return\n\n // Reset timer\n timer.value = 0\n\n // Reset and setup audio element\n await playback.resetAudioElement()\n\n // Wait for audio element to be ready\n await new Promise((resolve) => setTimeout(resolve, 50))\n\n if (!audioRef.value) return\n\n // Setup waveform visualization for playback\n const setupSuccess = await waveform.setupPlaybackVisualization(audioRef.value)\n if (!setupSuccess) return\n\n // Start playback\n await playback.play()\n\n // Update waveform\n waveform.initWaveform()\n waveform.updateWaveform(isWaveformActive)\n\n // Update timer from audio current time\n const timerInterval = setInterval(() => {\n timer.value = Math.floor(playback.getCurrentTime())\n }, 100)\n\n // Store interval for cleanup\n playback.playbackTimerInterval.value = timerInterval\n}\n\nfunction handleStopPlayback() {\n playback.stop()\n handlePlaybackEnded()\n}\n\nfunction handlePlaybackEnded() {\n waveform.stopWaveform()\n\n // Clear playback timer interval\n if (playback.playbackTimerInterval.value !== null) {\n clearInterval(playback.playbackTimerInterval.value)\n playback.playbackTimerInterval.value = null\n }\n\n const duration = playback.getDuration()\n if (duration) {\n timer.value = Math.floor(duration)\n } else {\n timer.value = 0\n }\n}\n\n// Serialization function for workflow execution\nasync function serializeValue() {\n if (isRecording.value && recorder.mediaRecorder.value) {\n recorder.mediaRecorder.value.stop()\n\n await new Promise((resolve, reject) => {\n let attempts = 0\n const maxAttempts = 50 // 5 seconds max (50 * 100ms)\n const checkRecording = () => {\n if (!isRecording.value && modelValue.value) {\n resolve(undefined)\n } else if (++attempts >= maxAttempts) {\n reject(new Error('Recording serialization timeout after 5 seconds'))\n } else {\n setTimeout(checkRecording, 100)\n }\n }\n checkRecording()\n })\n }\n\n return modelValue.value || lastUploadedPath || ''\n}\n\nfunction registerWidgetSerialization() {\n const node = litegraphNode.value\n if (!node?.widgets) return\n const targetWidget = node.widgets.find((w: IBaseWidget) => w.name === 'audio')\n if (targetWidget) {\n targetWidget.serializeValue = serializeValue\n }\n}\n\nonMounted(() => {\n waveform.initWaveform()\n registerWidgetSerialization()\n})\n\nonUnmounted(() => {\n if (playback.playbackTimerInterval.value !== null) {\n clearInterval(playback.playbackTimerInterval.value)\n playback.playbackTimerInterval.value = null\n }\n})\n</script>\n"],"names":["useAudioPlayback","audioRef","options","isPlaying","ref","audioElementKey","playbackTimerInterval","play","error","__name","stop","onPlaybackEnded","onMetadataLoaded","resetAudioElement","nextTick","getCurrentTime","getDuration","useAudioRecorder","isRecording","mediaRecorder","audioChunks","stream","recordedURL","startRecording","useAudioService","ExtendableMediaRecorder","e","blob","cleanup","err","stopRecording","track","dispose","onUnmounted","useAudioWaveform","barCount","minHeight","maxHeight","waveformBars","audioContext","analyser","dataArray","animationId","mediaElementSource","initWaveform","updateWaveform","isActive","updateWaveformFromAudio","updateWaveformRandom","samplesPerBar","_","i","sum","j","bar","setupAudioContext","setupRecordingVisualization","setupPlaybackVisualization","audioElement","stopWaveform","props","__props","lastUploadedPath","recorder","handleRecordingComplete","useToastStore","t","waveform","playback","handlePlaybackEnded","duration","timer","pauseTimer","resumeTimer","useIntervalFn","isWaveformActive","computed","modelValue","_useModel","litegraphNode","app","path","handleStartRecording","handleStopRecording","handlePlayRecording","resolve","timerInterval","handleStopPlayback","serializeValue","reject","attempts","maxAttempts","checkRecording","registerWidgetSerialization","node","targetWidget","w","onMounted"],"mappings":"sgCAQO,SAASA,GACdC,EACAC,EAAgC,GAChC,CACA,MAAMC,EAAYC,EAAI,EAAK,EACrBC,EAAkBD,EAAI,CAAC,EACvBE,EAAwBF,EAA2C,IAAI,EAE7E,eAAeG,GAAO,CACpB,GAAI,CAACN,EAAS,MAAO,MAAO,GAE5B,GAAI,CACF,aAAMA,EAAS,MAAM,KAAA,EACrBE,EAAU,MAAQ,GACX,EACT,OAASK,EAAO,CACd,eAAQ,KAAK,yBAA0BA,CAAK,EAC5CL,EAAU,MAAQ,GACX,EACT,CACF,CAZeM,EAAAF,EAAA,QAcf,SAASG,GAAO,CACVT,EAAS,QACXA,EAAS,MAAM,MAAA,EACfA,EAAS,MAAM,YAAc,GAE/BE,EAAU,MAAQ,GACdD,EAAQ,iBACVA,EAAQ,gBAAA,CAEZ,CATSO,EAAAC,EAAA,QAWT,SAASC,GAAkB,CACzBR,EAAU,MAAQ,GACdD,EAAQ,iBACVA,EAAQ,gBAAA,CAEZ,CALSO,EAAAE,EAAA,mBAOT,SAASC,GAAmB,CACtBX,EAAS,OAAO,UAAYC,EAAQ,kBACtCA,EAAQ,iBAAiBD,EAAS,MAAM,QAAQ,CAEpD,CAJSQ,EAAAG,EAAA,oBAMT,eAAeC,GAAoB,CACjCR,EAAgB,OAAS,EACzB,MAAMS,EAAA,CACR,CAHeL,EAAAI,EAAA,qBAKf,SAASE,GAAiB,CACxB,OAAOd,EAAS,OAAO,aAAe,CACxC,CAFSQ,EAAAM,EAAA,kBAIT,SAASC,GAAc,CACrB,OAAOf,EAAS,OAAO,UAAY,CACrC,CAFS,OAAAQ,EAAAO,EAAA,eAIF,CACL,UAAAb,EACA,gBAAAE,EACA,KAAAE,EACA,KAAAG,EACA,gBAAAC,EACA,iBAAAC,EACA,kBAAAC,EACA,eAAAE,EACA,YAAAC,EACA,sBAAAV,CAAA,CAEJ,CAvEgBG,EAAAT,GAAA,oBCET,SAASiB,GAAiBf,EAAgC,GAAI,CACnE,MAAMgB,EAAcd,EAAI,EAAK,EACvBe,EAAgBf,EAA0B,IAAI,EAC9CgB,EAAchB,EAAY,EAAE,EAC5BiB,EAASjB,EAAwB,IAAI,EACrCkB,EAAclB,EAAmB,IAAI,EAE3C,eAAemB,GAAiB,CAC9B,GAAI,CAEED,EAAY,OAAO,WAAW,OAAO,GACvC,IAAI,gBAAgBA,EAAY,KAAK,EAIvCF,EAAY,MAAQ,CAAA,EACpBE,EAAY,MAAQ,KAGpB,MAAME,EAAA,EAAkB,mBAAA,EACxBH,EAAO,MAAQ,MAAM,UAAU,aAAa,aAAa,CAAE,MAAO,GAAM,EAGxEF,EAAc,MAAQ,IAAIM,EAAwBJ,EAAO,MAAO,CAC9D,SAAU,WAAA,CACX,EAEDF,EAAc,MAAM,gBAAmBO,GAAM,CAC3CN,EAAY,MAAM,KAAKM,EAAE,IAAI,CAC/B,EAEAP,EAAc,MAAM,OAAS,SAAY,CACvC,MAAMQ,EAAO,IAAI,KAAKP,EAAY,MAAO,CAAE,KAAM,YAAa,EAG1DE,EAAY,OAAO,WAAW,OAAO,GACvC,IAAI,gBAAgBA,EAAY,KAAK,EAEvCA,EAAY,MAAQ,IAAI,gBAAgBK,CAAI,EAGxCzB,EAAQ,qBACV,MAAMA,EAAQ,oBAAoByB,CAAI,EAGxCC,EAAA,CACF,EAGAT,EAAc,MAAM,MAAM,GAAG,EAC7BD,EAAY,MAAQ,EACtB,OAASW,EAAK,CACZ,MAAI3B,EAAQ,SACVA,EAAQ,QAAQ2B,CAAY,EAExBA,CACR,CACF,CAlDepB,EAAAc,EAAA,kBAoDf,SAASO,GAAgB,CACnBX,EAAc,OAASA,EAAc,MAAM,QAAU,WACvDA,EAAc,MAAM,KAAA,EAEpBS,EAAA,CAEJ,CANSnB,EAAAqB,EAAA,iBAQT,SAASF,GAAU,CACjBV,EAAY,MAAQ,GAEhBG,EAAO,QACTA,EAAO,MAAM,YAAY,QAASU,GAAUA,EAAM,MAAM,EACxDV,EAAO,MAAQ,KAEnB,CAPSZ,EAAAmB,EAAA,WAST,SAASI,GAAU,CACjBF,EAAA,EACIR,EAAY,QACd,IAAI,gBAAgBA,EAAY,KAAK,EACrCA,EAAY,MAAQ,KAExB,CANS,OAAAb,EAAAuB,EAAA,WAQTC,EAAY,IAAM,CAChBD,EAAA,CACF,CAAC,EAEM,CACL,YAAAd,EACA,YAAAI,EACA,cAAAH,EACA,eAAAI,EACA,cAAAO,EACA,QAAAE,CAAA,CAEJ,CAhGgBvB,EAAAQ,GAAA,oBCGT,SAASiB,GAAiBhC,EAAgC,GAAI,CACnE,KAAM,CAAE,SAAAiC,EAAW,GAAI,UAAAC,EAAY,EAAG,UAAAC,EAAY,IAAOnC,EAEnDoC,EAAelC,EACnB,MAAM,KAAK,CAAE,OAAQ+B,CAAA,EAAY,KAAO,CAAE,OAAQ,IAAK,CAAA,EAEnDI,EAAenC,EAAyB,IAAI,EAC5CoC,EAAWpC,EAAyB,IAAI,EACxCqC,EAAYrC,EAAuB,IAAI,EACvCsC,EAActC,EAAmB,IAAI,EACrCuC,EAAqBvC,EAAwC,IAAI,EAEvE,SAASwC,GAAe,CACtBN,EAAa,MAAQ,MAAM,KAAK,CAAE,OAAQH,CAAA,EAAY,KAAO,CAC3D,OAAQ,KAAK,OAAA,GAAYE,EAAYD,GAAaA,CAAA,EAClD,CACJ,CAJS3B,EAAAmC,EAAA,gBAMT,SAASC,EAAeC,EAAwB,CACzCA,EAAS,QAEVN,EAAS,OAASC,EAAU,MAC9BM,EAAA,EAEAC,EAAA,EAGFN,EAAY,MAAQ,sBAAsB,IAAMG,EAAeC,CAAQ,CAAC,EAC1E,CAVSrC,EAAAoC,EAAA,kBAYT,SAASE,GAA0B,CACjC,GAAI,CAACP,EAAS,OAAS,CAACC,EAAU,MAAO,OAEzCD,EAAS,MAAM,qBACbC,EAAU,KAAA,EAEZ,MAAMQ,EAAgB,KAAK,MAAMR,EAAU,MAAM,OAASN,CAAQ,EAElEG,EAAa,MAAQA,EAAa,MAAM,IAAI,CAACY,EAAGC,IAAM,CACpD,IAAIC,EAAM,EACV,QAASC,EAAI,EAAGA,EAAIJ,EAAeI,IACjCD,GAAOX,EAAU,MAAOU,EAAIF,EAAgBI,CAAC,GAAK,EAKpD,MAAO,CAAE,OAHOD,EAAMH,EAET,KAAQZ,EAAYD,GAAaA,CAC7B,CACnB,CAAC,CACH,CAlBS3B,EAAAsC,EAAA,2BAoBT,SAASC,GAAuB,CAC9BV,EAAa,MAAQA,EAAa,MAAM,IAAKgB,IAAS,CACpD,OAAQ,KAAK,IACXlB,EACA,KAAK,IAAIC,EAAWiB,EAAI,QAAU,KAAK,SAAW,IAAO,CAAC,CAAA,CAC5D,EACA,CACJ,CAPS7C,EAAAuC,EAAA,wBAST,eAAeO,GAAoB,CAC7BhB,EAAa,OAASA,EAAa,MAAM,QAAU,UACrD,MAAMA,EAAa,MAAM,MAAA,EAE3BA,EAAa,MAAQ,KACrBI,EAAmB,MAAQ,IAC7B,CANelC,EAAA8C,EAAA,qBAQf,eAAeC,EAA4BnC,EAAqB,CAC9DkB,EAAa,MAAQ,IAAI,OAAO,aAChCC,EAAS,MAAQD,EAAa,MAAM,eAAA,EACrBA,EAAa,MAAM,wBAAwBlB,CAAM,EACzD,QAAQmB,EAAS,KAAK,EAE7BA,EAAS,MAAM,QAAU,IACzBC,EAAU,MAAQ,IAAI,WAAWD,EAAS,MAAM,iBAAiB,CACnE,CARe/B,EAAA+C,EAAA,+BAUf,eAAeC,EAA2BC,EAAgC,CAOxE,OANInB,EAAa,OAASA,EAAa,MAAM,QAAU,UACrD,MAAMA,EAAa,MAAM,MAAA,EAG3BI,EAAmB,MAAQ,KAEtBe,GAELnB,EAAa,MAAQ,IAAI,OAAO,aAChCC,EAAS,MAAQD,EAAa,MAAM,eAAA,EAEpCI,EAAmB,MACjBJ,EAAa,MAAM,yBAAyBmB,CAAY,EAE1Df,EAAmB,MAAM,QAAQH,EAAS,KAAK,EAC/CA,EAAS,MAAM,QAAQD,EAAa,MAAM,WAAW,EAErDC,EAAS,MAAM,QAAU,IACzBC,EAAU,MAAQ,IAAI,WAAWD,EAAS,MAAM,iBAAiB,EAE1D,IAdmB,EAe5B,CAtBe/B,EAAAgD,EAAA,8BAwBf,SAASE,GAAe,CAClBjB,EAAY,QACd,qBAAqBA,EAAY,KAAK,EACtCA,EAAY,MAAQ,KAExB,CALSjC,EAAAkD,EAAA,gBAOT,SAAS3B,GAAU,CACjB2B,EAAA,EACIpB,EAAa,OAASA,EAAa,MAAM,QAAU,UAChDA,EAAa,MAAM,MAAA,EAE1BA,EAAa,MAAQ,KACrBI,EAAmB,MAAQ,IAC7B,CAPS,OAAAlC,EAAAuB,EAAA,WASTC,EAAY,IAAM,CAChBD,EAAA,CACF,CAAC,EAEM,CACL,aAAAM,EACA,aAAAM,EACA,eAAAC,EACA,kBAAAU,EACA,4BAAAC,EACA,2BAAAC,EACA,aAAAE,EACA,QAAA3B,CAAA,CAEJ,CAnIgBvB,EAAAyB,GAAA,+jBCuFhB,MAAM0B,EAAQC,EAMR5D,EAAWG,EAAA,EAGjB,IAAI0D,EAAmB,GAGvB,MAAMC,EAAW9C,GAAiB,CAChC,oBAAqB+C,EACrB,QAASvD,EAAA,IAAM,CACbwD,EAAA,EAAgB,SACdC,EAAE,uBAAuB,GAAK,8BAAA,CAElC,EAJS,UAIT,CACD,EAEKC,EAAWjC,GAAiB,CAChC,SAAU,GACV,UAAW,EACX,UAAW,EAAA,CACZ,EAEKkC,EAAWpE,GAAiBC,EAAU,CAC1C,gBAAiBoE,EACjB,iBAAkB5D,EAAC6D,GAAa,CAC1B,CAACnE,EAAU,OAAS,CAACe,EAAY,QACnCqD,EAAM,MAAQ,KAAK,MAAMD,CAAQ,EAErC,EAJkB,mBAIlB,CACD,EAGKC,EAAQnE,EAAI,CAAC,EACb,CAAE,MAAOoE,EAAY,OAAQC,GAAgBC,EACjD,IAAM,CACJH,EAAM,OAAS,CACjB,EACA,IACA,CAAE,UAAW,EAAA,CAAM,EAIf,CAAE,YAAArD,EAAa,YAAAI,CAAA,EAAgByC,EAC/B,CAAE,aAAAzB,GAAiB6B,EACnB,CAAE,UAAAhE,EAAW,gBAAAE,CAAA,EAAoB+D,EAGjCO,EAAmBC,EAAS,IAAM1D,EAAY,OAASf,EAAU,KAAK,EAEtE0E,EAAaC,EAAmBjB,EAAA,YAAgB,EAEhDkB,EAAgBH,EAAS,IACzB,CAAChB,EAAM,QAAU,CAACoB,EAAI,OAAO,MAAc,KACxCA,EAAI,OAAO,MAAM,YAAYpB,EAAM,MAAM,CACjD,EAED,eAAeI,EAAwBrC,EAAY,CACjD,GAAI,CACF,MAAMsD,EAAO,MAAMzD,IAAkB,2BAA2BG,CAAI,EACpEkD,EAAW,MAAQI,EACnBnB,EAAmBmB,CACrB,MAAY,CACVhB,EAAA,EAAgB,SAAS,iCAAiC,CAC5D,CACF,CARexD,EAAAuD,EAAA,2BAUf,eAAekB,GAAuB,CACpC,GAAI,CAAAtB,EAAM,SAEV,GAAI,CAKF,GAJA,MAAMO,EAAS,kBAAA,EACf,MAAMJ,EAAS,eAAA,EAGXA,EAAS,cAAc,MAAO,CAChC,MAAM1C,EAAS0C,EAAS,cAAc,MAAM,OACxC1C,GACF,MAAM8C,EAAS,4BAA4B9C,CAAM,CAErD,CAGAkD,EAAM,MAAQ,EACdE,EAAA,EACAN,EAAS,aAAA,EACTA,EAAS,eAAeQ,CAAgB,CAC1C,OAAS9C,EAAK,CACZ,QAAQ,MAAM,6BAA8BA,CAAG,CACjD,CACF,CAvBepB,EAAAyE,EAAA,wBAyBf,SAASC,GAAsB,CAC7BpB,EAAS,cAAA,EACTS,EAAA,EACAL,EAAS,aAAA,CACX,CAJS1D,EAAA0E,EAAA,uBAMT,eAAeC,GAAsB,CAgBnC,GAfI,CAAC9D,EAAY,QAGjBiD,EAAM,MAAQ,EAGd,MAAMH,EAAS,kBAAA,EAGf,MAAM,IAAI,QAASiB,GAAY,WAAWA,EAAS,EAAE,CAAC,EAElD,CAACpF,EAAS,QAIV,CADiB,MAAMkE,EAAS,2BAA2BlE,EAAS,KAAK,EAC1D,OAGnB,MAAMmE,EAAS,KAAA,EAGfD,EAAS,aAAA,EACTA,EAAS,eAAeQ,CAAgB,EAGxC,MAAMW,EAAgB,YAAY,IAAM,CACtCf,EAAM,MAAQ,KAAK,MAAMH,EAAS,gBAAgB,CACpD,EAAG,GAAG,EAGNA,EAAS,sBAAsB,MAAQkB,CACzC,CAhCe7E,EAAA2E,EAAA,uBAkCf,SAASG,GAAqB,CAC5BnB,EAAS,KAAA,EACTC,EAAA,CACF,CAHS5D,EAAA8E,EAAA,sBAKT,SAASlB,GAAsB,CAC7BF,EAAS,aAAA,EAGLC,EAAS,sBAAsB,QAAU,OAC3C,cAAcA,EAAS,sBAAsB,KAAK,EAClDA,EAAS,sBAAsB,MAAQ,MAGzC,MAAME,EAAWF,EAAS,YAAA,EACtBE,EACFC,EAAM,MAAQ,KAAK,MAAMD,CAAQ,EAEjCC,EAAM,MAAQ,CAElB,CAfS9D,EAAA4D,EAAA,uBAkBT,eAAemB,GAAiB,CAC9B,OAAItE,EAAY,OAAS6C,EAAS,cAAc,QAC9CA,EAAS,cAAc,MAAM,KAAA,EAE7B,MAAM,IAAI,QAAQ,CAACsB,EAASI,IAAW,CACrC,IAAIC,EAAW,EACf,MAAMC,EAAc,GACdC,EAAiBnF,EAAA,IAAM,CACvB,CAACS,EAAY,OAAS2D,EAAW,MACnCQ,EAAQ,MAAS,EACR,EAAEK,GAAYC,EACvBF,EAAO,IAAI,MAAM,iDAAiD,CAAC,EAEnE,WAAWG,EAAgB,GAAG,CAElC,EARuB,kBASvBA,EAAA,CACF,CAAC,GAGIf,EAAW,OAASf,GAAoB,EACjD,CArBerD,EAAA+E,EAAA,kBAuBf,SAASK,GAA8B,CACrC,MAAMC,EAAOf,EAAc,MAC3B,GAAI,CAACe,GAAM,QAAS,OACpB,MAAMC,EAAeD,EAAK,QAAQ,KAAME,GAAmBA,EAAE,OAAS,OAAO,EACzED,IACFA,EAAa,eAAiBP,EAElC,CAPS,OAAA/E,EAAAoF,EAAA,+BASTI,GAAU,IAAM,CACd9B,EAAS,aAAA,EACT0B,EAAA,CACF,CAAC,EAED5D,EAAY,IAAM,CACZmC,EAAS,sBAAsB,QAAU,OAC3C,cAAcA,EAAS,sBAAsB,KAAK,EAClDA,EAAS,sBAAsB,MAAQ,KAE3C,CAAC"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{_ as o}from"./WidgetSelect.vue_vue_type_script_setup_true_lang-CT0J0vij.js";import"./index-DvCHS_f2.js";import"./vendor-primevue-Bp7MMXLP.js";import"./vendor-other-B8t_Wf2K.js";import"./vendor-vue-DaLZjKA7.js";import"./vendor-xterm-CWYFmgbN.js";import"./vendor-three-DH0o8VQ7.js";import"./vendor-tiptap-VxK0yxkd.js";import"./widgetPropFilter-CygYoMQt.js";import"./index-kQCr6fgp.js";import"./WidgetLayoutField.vue_vue_type_script_setup_true_lang-7bIn_5fI.js";import"./LazyImage.vue_vue_type_script_setup_true_lang-C58MdJKR.js";import"./WidgetWithControl.vue_vue_type_script_setup_true_lang-CTEGWC4h.js";export{o as default};
|
|
2
|
-
//# sourceMappingURL=WidgetSelect-XG4R8CnZ.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WidgetSelect-XG4R8CnZ.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|