{"version":3,"file":"index-DkvOTKox.js","sources":["../../src/extensions/core/clipspace.ts","../../src/extensions/core/colorPalette.ts","../../src/extensions/core/contextMenuFilter.ts","../../src/extensions/core/dynamicPrompts.ts","../../src/extensions/core/editAttention.ts","../../src/extensions/core/widgetInputs.ts","../../src/extensions/core/groupNodeManage.ts","../../src/extensions/core/groupNode.ts","../../src/extensions/core/groupOptions.ts","../../src/extensions/core/invertMenuScrolling.ts","../../src/extensions/core/keybinds.ts","../../src/extensions/core/linkRenderMode.ts","../../src/extensions/core/maskeditor.ts","../../src/extensions/core/nodeTemplates.ts","../../src/extensions/core/noteNode.ts","../../src/extensions/core/rerouteNode.ts","../../src/extensions/core/saveImageExtraOutput.ts","../../src/extensions/core/simpleTouchSupport.ts","../../src/extensions/core/slotDefaults.ts","../../src/extensions/core/snapToGrid.ts","../../src/extensions/core/uploadImage.ts","../../src/extensions/core/webcamCapture.ts","../../src/extensions/core/uploadAudio.ts"],"sourcesContent":["import { app } from '../../scripts/app'\r\nimport { ComfyDialog, $el } from '../../scripts/ui'\r\nimport { ComfyApp } from '../../scripts/app'\r\n\r\nexport class ClipspaceDialog extends ComfyDialog {\r\n static items = []\r\n static instance = null\r\n\r\n static registerButton(name, contextPredicate, callback) {\r\n const item = $el('button', {\r\n type: 'button',\r\n textContent: name,\r\n contextPredicate: contextPredicate,\r\n onclick: callback\r\n })\r\n\r\n ClipspaceDialog.items.push(item)\r\n }\r\n\r\n static invalidatePreview() {\r\n if (\r\n ComfyApp.clipspace &&\r\n ComfyApp.clipspace.imgs &&\r\n ComfyApp.clipspace.imgs.length > 0\r\n ) {\r\n const img_preview = document.getElementById(\r\n 'clipspace_preview'\r\n ) as HTMLImageElement\r\n if (img_preview) {\r\n img_preview.src =\r\n ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']].src\r\n img_preview.style.maxHeight = '100%'\r\n img_preview.style.maxWidth = '100%'\r\n }\r\n }\r\n }\r\n\r\n static invalidate() {\r\n if (ClipspaceDialog.instance) {\r\n const self = ClipspaceDialog.instance\r\n // allow reconstruct controls when copying from non-image to image content.\r\n const children = $el('div.comfy-modal-content', [\r\n self.createImgSettings(),\r\n ...self.createButtons()\r\n ])\r\n\r\n if (self.element) {\r\n // update\r\n self.element.removeChild(self.element.firstChild)\r\n self.element.appendChild(children)\r\n } else {\r\n // new\r\n self.element = $el('div.comfy-modal', { parent: document.body }, [\r\n children\r\n ])\r\n }\r\n\r\n if (self.element.children[0].children.length <= 1) {\r\n self.element.children[0].appendChild(\r\n $el('p', {}, [\r\n 'Unable to find the features to edit content of a format stored in the current Clipspace.'\r\n ])\r\n )\r\n }\r\n\r\n ClipspaceDialog.invalidatePreview()\r\n }\r\n }\r\n\r\n constructor() {\r\n super()\r\n }\r\n\r\n createButtons() {\r\n const buttons = []\r\n\r\n for (let idx in ClipspaceDialog.items) {\r\n const item = ClipspaceDialog.items[idx]\r\n if (!item.contextPredicate || item.contextPredicate())\r\n buttons.push(ClipspaceDialog.items[idx])\r\n }\r\n\r\n buttons.push(\r\n $el('button', {\r\n type: 'button',\r\n textContent: 'Close',\r\n onclick: () => {\r\n this.close()\r\n }\r\n })\r\n )\r\n\r\n return buttons\r\n }\r\n\r\n createImgSettings() {\r\n if (ComfyApp.clipspace.imgs) {\r\n const combo_items = []\r\n const imgs = ComfyApp.clipspace.imgs\r\n\r\n for (let i = 0; i < imgs.length; i++) {\r\n combo_items.push($el('option', { value: i }, [`${i}`]))\r\n }\r\n\r\n const combo1 = $el(\r\n 'select',\r\n {\r\n id: 'clipspace_img_selector',\r\n onchange: (event) => {\r\n ComfyApp.clipspace['selectedIndex'] = event.target.selectedIndex\r\n ClipspaceDialog.invalidatePreview()\r\n }\r\n },\r\n combo_items\r\n )\r\n\r\n const row1 = $el('tr', {}, [\r\n $el('td', {}, [$el('font', { color: 'white' }, ['Select Image'])]),\r\n $el('td', {}, [combo1])\r\n ])\r\n\r\n const combo2 = $el(\r\n 'select',\r\n {\r\n id: 'clipspace_img_paste_mode',\r\n onchange: (event) => {\r\n ComfyApp.clipspace['img_paste_mode'] = event.target.value\r\n }\r\n },\r\n [\r\n $el('option', { value: 'selected' }, 'selected'),\r\n $el('option', { value: 'all' }, 'all')\r\n ]\r\n ) as HTMLSelectElement\r\n combo2.value = ComfyApp.clipspace['img_paste_mode']\r\n\r\n const row2 = $el('tr', {}, [\r\n $el('td', {}, [$el('font', { color: 'white' }, ['Paste Mode'])]),\r\n $el('td', {}, [combo2])\r\n ])\r\n\r\n const td = $el(\r\n 'td',\r\n { align: 'center', width: '100px', height: '100px', colSpan: '2' },\r\n [$el('img', { id: 'clipspace_preview', ondragstart: () => false }, [])]\r\n )\r\n\r\n const row3 = $el('tr', {}, [td])\r\n\r\n return $el('table', {}, [row1, row2, row3])\r\n } else {\r\n return []\r\n }\r\n }\r\n\r\n createImgPreview() {\r\n if (ComfyApp.clipspace.imgs) {\r\n return $el('img', { id: 'clipspace_preview', ondragstart: () => false })\r\n } else return []\r\n }\r\n\r\n show() {\r\n const img_preview = document.getElementById('clipspace_preview')\r\n ClipspaceDialog.invalidate()\r\n\r\n this.element.style.display = 'block'\r\n }\r\n}\r\n\r\napp.registerExtension({\r\n name: 'Comfy.Clipspace',\r\n init(app) {\r\n app.openClipspace = function () {\r\n if (!ClipspaceDialog.instance) {\r\n ClipspaceDialog.instance = new ClipspaceDialog()\r\n ComfyApp.clipspace_invalidate_handler = ClipspaceDialog.invalidate\r\n }\r\n\r\n if (ComfyApp.clipspace) {\r\n ClipspaceDialog.instance.show()\r\n } else app.ui.dialog.show('Clipspace is Empty!')\r\n }\r\n }\r\n})\r\n","import { app } from '../../scripts/app'\r\nimport { $el } from '../../scripts/ui'\r\nimport type { ColorPalettes, Palette } from '@/types/colorPalette'\r\nimport { LGraphCanvas, LiteGraph } from '@comfyorg/litegraph'\r\n\r\n// Manage color palettes\r\n\r\nconst colorPalettes: ColorPalettes = {\r\n dark: {\r\n id: 'dark',\r\n name: 'Dark (Default)',\r\n colors: {\r\n node_slot: {\r\n CLIP: '#FFD500', // bright yellow\r\n CLIP_VISION: '#A8DADC', // light blue-gray\r\n CLIP_VISION_OUTPUT: '#ad7452', // rusty brown-orange\r\n CONDITIONING: '#FFA931', // vibrant orange-yellow\r\n CONTROL_NET: '#6EE7B7', // soft mint green\r\n IMAGE: '#64B5F6', // bright sky blue\r\n LATENT: '#FF9CF9', // light pink-purple\r\n MASK: '#81C784', // muted green\r\n MODEL: '#B39DDB', // light lavender-purple\r\n STYLE_MODEL: '#C2FFAE', // light green-yellow\r\n VAE: '#FF6E6E', // bright red\r\n NOISE: '#B0B0B0', // gray\r\n GUIDER: '#66FFFF', // cyan\r\n SAMPLER: '#ECB4B4', // very soft red\r\n SIGMAS: '#CDFFCD', // soft lime green\r\n TAESD: '#DCC274' // cheesecake\r\n },\r\n litegraph_base: {\r\n BACKGROUND_IMAGE:\r\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQBJREFUeNrs1rEKwjAUhlETUkj3vP9rdmr1Ysammk2w5wdxuLgcMHyptfawuZX4pJSWZTnfnu/lnIe/jNNxHHGNn//HNbbv+4dr6V+11uF527arU7+u63qfa/bnmh8sWLBgwYJlqRf8MEptXPBXJXa37BSl3ixYsGDBMliwFLyCV/DeLIMFCxYsWLBMwSt4Be/NggXLYMGCBUvBK3iNruC9WbBgwYJlsGApeAWv4L1ZBgsWLFiwYJmCV/AK3psFC5bBggULloJX8BpdwXuzYMGCBctgwVLwCl7Be7MMFixYsGDBsu8FH1FaSmExVfAxBa/gvVmwYMGCZbBg/W4vAQYA5tRF9QYlv/QAAAAASUVORK5CYII=',\r\n CLEAR_BACKGROUND_COLOR: '#222',\r\n NODE_TITLE_COLOR: '#999',\r\n NODE_SELECTED_TITLE_COLOR: '#FFF',\r\n NODE_TEXT_SIZE: 14,\r\n NODE_TEXT_COLOR: '#AAA',\r\n NODE_SUBTEXT_SIZE: 12,\r\n NODE_DEFAULT_COLOR: '#333',\r\n NODE_DEFAULT_BGCOLOR: '#353535',\r\n NODE_DEFAULT_BOXCOLOR: '#666',\r\n NODE_DEFAULT_SHAPE: 'box',\r\n NODE_BOX_OUTLINE_COLOR: '#FFF',\r\n DEFAULT_SHADOW_COLOR: 'rgba(0,0,0,0.5)',\r\n DEFAULT_GROUP_FONT: 24,\r\n\r\n WIDGET_BGCOLOR: '#222',\r\n WIDGET_OUTLINE_COLOR: '#666',\r\n WIDGET_TEXT_COLOR: '#DDD',\r\n WIDGET_SECONDARY_TEXT_COLOR: '#999',\r\n\r\n LINK_COLOR: '#9A9',\r\n EVENT_LINK_COLOR: '#A86',\r\n CONNECTING_LINK_COLOR: '#AFA'\r\n },\r\n comfy_base: {\r\n 'fg-color': '#fff',\r\n 'bg-color': '#202020',\r\n 'comfy-menu-bg': '#353535',\r\n 'comfy-input-bg': '#222',\r\n 'input-text': '#ddd',\r\n 'descrip-text': '#999',\r\n 'drag-text': '#ccc',\r\n 'error-text': '#ff4444',\r\n 'border-color': '#4e4e4e',\r\n 'tr-even-bg-color': '#222',\r\n 'tr-odd-bg-color': '#353535',\r\n 'content-bg': '#4e4e4e',\r\n 'content-fg': '#fff',\r\n 'content-hover-bg': '#222',\r\n 'content-hover-fg': '#fff'\r\n }\r\n }\r\n },\r\n light: {\r\n id: 'light',\r\n name: 'Light',\r\n colors: {\r\n node_slot: {\r\n CLIP: '#FFA726', // orange\r\n CLIP_VISION: '#5C6BC0', // indigo\r\n CLIP_VISION_OUTPUT: '#8D6E63', // brown\r\n CONDITIONING: '#EF5350', // red\r\n CONTROL_NET: '#66BB6A', // green\r\n IMAGE: '#42A5F5', // blue\r\n LATENT: '#AB47BC', // purple\r\n MASK: '#9CCC65', // light green\r\n MODEL: '#7E57C2', // deep purple\r\n STYLE_MODEL: '#D4E157', // lime\r\n VAE: '#FF7043' // deep orange\r\n },\r\n litegraph_base: {\r\n BACKGROUND_IMAGE:\r\n 'data:image/gif;base64,R0lGODlhZABkALMAAAAAAP///+vr6+rq6ujo6Ofn5+bm5uXl5d3d3f///wAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAkALAAAAABkAGQAAAT/UMhJq7046827HkcoHkYxjgZhnGG6si5LqnIM0/fL4qwwIMAg0CAsEovBIxKhRDaNy2GUOX0KfVFrssrNdpdaqTeKBX+dZ+jYvEaTf+y4W66mC8PUdrE879f9d2mBeoNLfH+IhYBbhIx2jkiHiomQlGKPl4uZe3CaeZifnnijgkESBqipqqusra6vsLGys62SlZO4t7qbuby7CLa+wqGWxL3Gv3jByMOkjc2lw8vOoNSi0czAncXW3Njdx9Pf48/Z4Kbbx+fQ5evZ4u3k1fKR6cn03vHlp7T9/v8A/8Gbp4+gwXoFryXMB2qgwoMMHyKEqA5fxX322FG8tzBcRnMW/zlulPbRncmQGidKjMjyYsOSKEF2FBlJQMCbOHP6c9iSZs+UnGYCdbnSo1CZI5F64kn0p1KnTH02nSoV3dGTV7FFHVqVq1dtWcMmVQZTbNGu72zqXMuW7danVL+6e4t1bEy6MeueBYLXrNO5Ze36jQtWsOG97wIj1vt3St/DjTEORss4nNq2mDP3e7w4r1bFkSET5hy6s2TRlD2/mSxXtSHQhCunXo26NevCpmvD/UU6tuullzULH76q92zdZG/Ltv1a+W+osI/nRmyc+fRi1Xdbh+68+0vv10dH3+77KD/i6IdnX669/frn5Zsjh4/2PXju8+8bzc9/6fj27LFnX11/+IUnXWl7BJfegm79FyB9JOl3oHgSklefgxAC+FmFGpqHIYcCfkhgfCohSKKJVo044YUMttggiBkmp6KFXw1oII24oYhjiDByaKOOHcp3Y5BD/njikSkO+eBREQAAOw==',\r\n CLEAR_BACKGROUND_COLOR: 'lightgray',\r\n NODE_TITLE_COLOR: '#222',\r\n NODE_SELECTED_TITLE_COLOR: '#000',\r\n NODE_TEXT_SIZE: 14,\r\n NODE_TEXT_COLOR: '#444',\r\n NODE_SUBTEXT_SIZE: 12,\r\n NODE_DEFAULT_COLOR: '#F7F7F7',\r\n NODE_DEFAULT_BGCOLOR: '#F5F5F5',\r\n NODE_DEFAULT_BOXCOLOR: '#CCC',\r\n NODE_DEFAULT_SHAPE: 'box',\r\n NODE_BOX_OUTLINE_COLOR: '#000',\r\n DEFAULT_SHADOW_COLOR: 'rgba(0,0,0,0.1)',\r\n DEFAULT_GROUP_FONT: 24,\r\n\r\n WIDGET_BGCOLOR: '#D4D4D4',\r\n WIDGET_OUTLINE_COLOR: '#999',\r\n WIDGET_TEXT_COLOR: '#222',\r\n WIDGET_SECONDARY_TEXT_COLOR: '#555',\r\n\r\n LINK_COLOR: '#4CAF50',\r\n EVENT_LINK_COLOR: '#FF9800',\r\n CONNECTING_LINK_COLOR: '#2196F3'\r\n },\r\n comfy_base: {\r\n 'fg-color': '#222',\r\n 'bg-color': '#DDD',\r\n 'comfy-menu-bg': '#F5F5F5',\r\n 'comfy-input-bg': '#C9C9C9',\r\n 'input-text': '#222',\r\n 'descrip-text': '#444',\r\n 'drag-text': '#555',\r\n 'error-text': '#F44336',\r\n 'border-color': '#888',\r\n 'tr-even-bg-color': '#f9f9f9',\r\n 'tr-odd-bg-color': '#fff',\r\n 'content-bg': '#e0e0e0',\r\n 'content-fg': '#222',\r\n 'content-hover-bg': '#adadad',\r\n 'content-hover-fg': '#222'\r\n }\r\n }\r\n },\r\n solarized: {\r\n id: 'solarized',\r\n name: 'Solarized',\r\n colors: {\r\n node_slot: {\r\n CLIP: '#2AB7CA', // light blue\r\n CLIP_VISION: '#6c71c4', // blue violet\r\n CLIP_VISION_OUTPUT: '#859900', // olive green\r\n CONDITIONING: '#d33682', // magenta\r\n CONTROL_NET: '#d1ffd7', // light mint green\r\n IMAGE: '#5940bb', // deep blue violet\r\n LATENT: '#268bd2', // blue\r\n MASK: '#CCC9E7', // light purple-gray\r\n MODEL: '#dc322f', // red\r\n STYLE_MODEL: '#1a998a', // teal\r\n UPSCALE_MODEL: '#054A29', // dark green\r\n VAE: '#facfad' // light pink-orange\r\n },\r\n litegraph_base: {\r\n NODE_TITLE_COLOR: '#fdf6e3', // Base3\r\n NODE_SELECTED_TITLE_COLOR: '#A9D400',\r\n NODE_TEXT_SIZE: 14,\r\n NODE_TEXT_COLOR: '#657b83', // Base00\r\n NODE_SUBTEXT_SIZE: 12,\r\n NODE_DEFAULT_COLOR: '#094656',\r\n NODE_DEFAULT_BGCOLOR: '#073642', // Base02\r\n NODE_DEFAULT_BOXCOLOR: '#839496', // Base0\r\n NODE_DEFAULT_SHAPE: 'box',\r\n NODE_BOX_OUTLINE_COLOR: '#fdf6e3', // Base3\r\n DEFAULT_SHADOW_COLOR: 'rgba(0,0,0,0.5)',\r\n DEFAULT_GROUP_FONT: 24,\r\n\r\n WIDGET_BGCOLOR: '#002b36', // Base03\r\n WIDGET_OUTLINE_COLOR: '#839496', // Base0\r\n WIDGET_TEXT_COLOR: '#fdf6e3', // Base3\r\n WIDGET_SECONDARY_TEXT_COLOR: '#93a1a1', // Base1\r\n\r\n LINK_COLOR: '#2aa198', // Solarized Cyan\r\n EVENT_LINK_COLOR: '#268bd2', // Solarized Blue\r\n CONNECTING_LINK_COLOR: '#859900' // Solarized Green\r\n },\r\n comfy_base: {\r\n 'fg-color': '#fdf6e3', // Base3\r\n 'bg-color': '#002b36', // Base03\r\n 'comfy-menu-bg': '#073642', // Base02\r\n 'comfy-input-bg': '#002b36', // Base03\r\n 'input-text': '#93a1a1', // Base1\r\n 'descrip-text': '#586e75', // Base01\r\n 'drag-text': '#839496', // Base0\r\n 'error-text': '#dc322f', // Solarized Red\r\n 'border-color': '#657b83', // Base00\r\n 'tr-even-bg-color': '#002b36',\r\n 'tr-odd-bg-color': '#073642',\r\n 'content-bg': '#657b83',\r\n 'content-fg': '#fdf6e3',\r\n 'content-hover-bg': '#002b36',\r\n 'content-hover-fg': '#fdf6e3'\r\n }\r\n }\r\n },\r\n arc: {\r\n id: 'arc',\r\n name: 'Arc',\r\n colors: {\r\n node_slot: {\r\n BOOLEAN: '',\r\n CLIP: '#eacb8b',\r\n CLIP_VISION: '#A8DADC',\r\n CLIP_VISION_OUTPUT: '#ad7452',\r\n CONDITIONING: '#cf876f',\r\n CONTROL_NET: '#00d78d',\r\n CONTROL_NET_WEIGHTS: '',\r\n FLOAT: '',\r\n GLIGEN: '',\r\n IMAGE: '#80a1c0',\r\n IMAGEUPLOAD: '',\r\n INT: '',\r\n LATENT: '#b38ead',\r\n LATENT_KEYFRAME: '',\r\n MASK: '#a3bd8d',\r\n MODEL: '#8978a7',\r\n SAMPLER: '',\r\n SIGMAS: '',\r\n STRING: '',\r\n STYLE_MODEL: '#C2FFAE',\r\n T2I_ADAPTER_WEIGHTS: '',\r\n TAESD: '#DCC274',\r\n TIMESTEP_KEYFRAME: '',\r\n UPSCALE_MODEL: '',\r\n VAE: '#be616b'\r\n },\r\n litegraph_base: {\r\n BACKGROUND_IMAGE:\r\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABcklEQVR4nO3YMUoDARgF4RfxBqZI6/0vZqFn0MYtrLIQMFN8U6V4LAtD+Jm9XG/v30OGl2e/AP7yevz4+vx45nvgF/+QGITEICQGITEIiUFIjNNC3q43u3/YnRJyPOzeQ+0e220nhRzReC8e7R7bbdvl+Jal1Bs46jEIiUFIDEJiEBKDkBhKPbZT6qHdptRTu02p53DUYxASg5AYhMQgJAYhMZR6bKfUQ7tNqad2m1LP4ajHICQGITEIiUFIDEJiKPXYTqmHdptST+02pZ7DUY9BSAxCYhASg5AYhMRQ6rGdUg/tNqWe2m1KPYejHoOQGITEICQGITEIiaHUYzulHtptSj2125R6Dkc9BiExCIlBSAxCYhASQ6nHdko9tNuUemq3KfUcjnoMQmIQEoOQGITEICSGUo/tlHpotyn11G5T6jkc9RiExCAkBiExCIlBSAylHtsp9dBuU+qp3abUczjqMQiJQUgMQmIQEoOQGITE+AHFISNQrFTGuwAAAABJRU5ErkJggg==',\r\n CLEAR_BACKGROUND_COLOR: '#2b2f38',\r\n NODE_TITLE_COLOR: '#b2b7bd',\r\n NODE_SELECTED_TITLE_COLOR: '#FFF',\r\n NODE_TEXT_SIZE: 14,\r\n NODE_TEXT_COLOR: '#AAA',\r\n NODE_SUBTEXT_SIZE: 12,\r\n NODE_DEFAULT_COLOR: '#2b2f38',\r\n NODE_DEFAULT_BGCOLOR: '#242730',\r\n NODE_DEFAULT_BOXCOLOR: '#6e7581',\r\n NODE_DEFAULT_SHAPE: 'box',\r\n NODE_BOX_OUTLINE_COLOR: '#FFF',\r\n DEFAULT_SHADOW_COLOR: 'rgba(0,0,0,0.5)',\r\n DEFAULT_GROUP_FONT: 22,\r\n WIDGET_BGCOLOR: '#2b2f38',\r\n WIDGET_OUTLINE_COLOR: '#6e7581',\r\n WIDGET_TEXT_COLOR: '#DDD',\r\n WIDGET_SECONDARY_TEXT_COLOR: '#b2b7bd',\r\n LINK_COLOR: '#9A9',\r\n EVENT_LINK_COLOR: '#A86',\r\n CONNECTING_LINK_COLOR: '#AFA'\r\n },\r\n comfy_base: {\r\n 'fg-color': '#fff',\r\n 'bg-color': '#2b2f38',\r\n 'comfy-menu-bg': '#242730',\r\n 'comfy-input-bg': '#2b2f38',\r\n 'input-text': '#ddd',\r\n 'descrip-text': '#b2b7bd',\r\n 'drag-text': '#ccc',\r\n 'error-text': '#ff4444',\r\n 'border-color': '#6e7581',\r\n 'tr-even-bg-color': '#2b2f38',\r\n 'tr-odd-bg-color': '#242730',\r\n 'content-bg': '#6e7581',\r\n 'content-fg': '#fff',\r\n 'content-hover-bg': '#2b2f38',\r\n 'content-hover-fg': '#fff'\r\n }\r\n }\r\n },\r\n nord: {\r\n id: 'nord',\r\n name: 'Nord',\r\n colors: {\r\n node_slot: {\r\n BOOLEAN: '',\r\n CLIP: '#eacb8b',\r\n CLIP_VISION: '#A8DADC',\r\n CLIP_VISION_OUTPUT: '#ad7452',\r\n CONDITIONING: '#cf876f',\r\n CONTROL_NET: '#00d78d',\r\n CONTROL_NET_WEIGHTS: '',\r\n FLOAT: '',\r\n GLIGEN: '',\r\n IMAGE: '#80a1c0',\r\n IMAGEUPLOAD: '',\r\n INT: '',\r\n LATENT: '#b38ead',\r\n LATENT_KEYFRAME: '',\r\n MASK: '#a3bd8d',\r\n MODEL: '#8978a7',\r\n SAMPLER: '',\r\n SIGMAS: '',\r\n STRING: '',\r\n STYLE_MODEL: '#C2FFAE',\r\n T2I_ADAPTER_WEIGHTS: '',\r\n TAESD: '#DCC274',\r\n TIMESTEP_KEYFRAME: '',\r\n UPSCALE_MODEL: '',\r\n VAE: '#be616b'\r\n },\r\n litegraph_base: {\r\n BACKGROUND_IMAGE:\r\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFu2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgOS4xLWMwMDEgNzkuMTQ2Mjg5OSwgMjAyMy8wNi8yNS0yMDowMTo1NSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDI1LjEgKFdpbmRvd3MpIiB4bXA6Q3JlYXRlRGF0ZT0iMjAyMy0xMS0xM1QwMDoxODowMiswMTowMCIgeG1wOk1vZGlmeURhdGU9IjIwMjMtMTEtMTVUMDE6MjA6NDUrMDE6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMjMtMTEtMTVUMDE6MjA6NDUrMDE6MDAiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjUwNDFhMmZjLTEzNzQtMTk0ZC1hZWY4LTYxMzM1MTVmNjUwMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoyMzFiMTBiMC1iNGZiLTAyNGUtYjEyZS0zMDUzMDNjZDA3YzgiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDoyMzFiMTBiMC1iNGZiLTAyNGUtYjEyZS0zMDUzMDNjZDA3YzgiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjIzMWIxMGIwLWI0ZmItMDI0ZS1iMTJlLTMwNTMwM2NkMDdjOCIgc3RFdnQ6d2hlbj0iMjAyMy0xMS0xM1QwMDoxODowMiswMTowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDI1LjEgKFdpbmRvd3MpIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo1MDQxYTJmYy0xMzc0LTE5NGQtYWVmOC02MTMzNTE1ZjY1MDAiIHN0RXZ0OndoZW49IjIwMjMtMTEtMTVUMDE6MjA6NDUrMDE6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyNS4xIChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz73jWg/AAAAyUlEQVR42u3WKwoAIBRFQRdiMb1idv9Lsxn9gEFw4Dbb8JCTojbbXEJwjJVL2HKwYMGCBQuWLbDmjr+9zrBGjHl1WVcvy2DBggULFizTWQpewSt4HzwsgwULFiwFr7MUvMtS8D54WLBgGSxYCl7BK3iXZbBgwYIFC5bpLAWv4BW8Dx6WwYIFC5aC11kK3mUpeB88LFiwDBYsBa/gFbzLMliwYMGCBct0loJX8AreBw/LYMGCBUvB6ywF77IUvA8eFixYBgsWrNfWAZPltufdad+1AAAAAElFTkSuQmCC',\r\n CLEAR_BACKGROUND_COLOR: '#212732',\r\n NODE_TITLE_COLOR: '#999',\r\n NODE_SELECTED_TITLE_COLOR: '#e5eaf0',\r\n NODE_TEXT_SIZE: 14,\r\n NODE_TEXT_COLOR: '#bcc2c8',\r\n NODE_SUBTEXT_SIZE: 12,\r\n NODE_DEFAULT_COLOR: '#2e3440',\r\n NODE_DEFAULT_BGCOLOR: '#161b22',\r\n NODE_DEFAULT_BOXCOLOR: '#545d70',\r\n NODE_DEFAULT_SHAPE: 'box',\r\n NODE_BOX_OUTLINE_COLOR: '#e5eaf0',\r\n DEFAULT_SHADOW_COLOR: 'rgba(0,0,0,0.5)',\r\n DEFAULT_GROUP_FONT: 24,\r\n WIDGET_BGCOLOR: '#2e3440',\r\n WIDGET_OUTLINE_COLOR: '#545d70',\r\n WIDGET_TEXT_COLOR: '#bcc2c8',\r\n WIDGET_SECONDARY_TEXT_COLOR: '#999',\r\n LINK_COLOR: '#9A9',\r\n EVENT_LINK_COLOR: '#A86',\r\n CONNECTING_LINK_COLOR: '#AFA'\r\n },\r\n comfy_base: {\r\n 'fg-color': '#e5eaf0',\r\n 'bg-color': '#2e3440',\r\n 'comfy-menu-bg': '#161b22',\r\n 'comfy-input-bg': '#2e3440',\r\n 'input-text': '#bcc2c8',\r\n 'descrip-text': '#999',\r\n 'drag-text': '#ccc',\r\n 'error-text': '#ff4444',\r\n 'border-color': '#545d70',\r\n 'tr-even-bg-color': '#2e3440',\r\n 'tr-odd-bg-color': '#161b22',\r\n 'content-bg': '#545d70',\r\n 'content-fg': '#e5eaf0',\r\n 'content-hover-bg': '#2e3440',\r\n 'content-hover-fg': '#e5eaf0'\r\n }\r\n }\r\n },\r\n github: {\r\n id: 'github',\r\n name: 'Github',\r\n colors: {\r\n node_slot: {\r\n BOOLEAN: '',\r\n CLIP: '#eacb8b',\r\n CLIP_VISION: '#A8DADC',\r\n CLIP_VISION_OUTPUT: '#ad7452',\r\n CONDITIONING: '#cf876f',\r\n CONTROL_NET: '#00d78d',\r\n CONTROL_NET_WEIGHTS: '',\r\n FLOAT: '',\r\n GLIGEN: '',\r\n IMAGE: '#80a1c0',\r\n IMAGEUPLOAD: '',\r\n INT: '',\r\n LATENT: '#b38ead',\r\n LATENT_KEYFRAME: '',\r\n MASK: '#a3bd8d',\r\n MODEL: '#8978a7',\r\n SAMPLER: '',\r\n SIGMAS: '',\r\n STRING: '',\r\n STYLE_MODEL: '#C2FFAE',\r\n T2I_ADAPTER_WEIGHTS: '',\r\n TAESD: '#DCC274',\r\n TIMESTEP_KEYFRAME: '',\r\n UPSCALE_MODEL: '',\r\n VAE: '#be616b'\r\n },\r\n litegraph_base: {\r\n BACKGROUND_IMAGE:\r\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAACXBIWXMAAAsTAAALEwEAmpwYAAAGlmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgOS4xLWMwMDEgNzkuMTQ2Mjg5OSwgMjAyMy8wNi8yNS0yMDowMTo1NSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDI1LjEgKFdpbmRvd3MpIiB4bXA6Q3JlYXRlRGF0ZT0iMjAyMy0xMS0xM1QwMDoxODowMiswMTowMCIgeG1wOk1vZGlmeURhdGU9IjIwMjMtMTEtMTVUMDI6MDQ6NTkrMDE6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMjMtMTEtMTVUMDI6MDQ6NTkrMDE6MDAiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOmIyYzRhNjA5LWJmYTctYTg0MC1iOGFlLTk3MzE2ZjM1ZGIyNyIgeG1wTU06RG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjk0ZmNlZGU4LTE1MTctZmQ0MC04ZGU3LWYzOTgxM2E3ODk5ZiIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjIzMWIxMGIwLWI0ZmItMDI0ZS1iMTJlLTMwNTMwM2NkMDdjOCI+IDx4bXBNTTpIaXN0b3J5PiA8cmRmOlNlcT4gPHJkZjpsaSBzdEV2dDphY3Rpb249ImNyZWF0ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6MjMxYjEwYjAtYjRmYi0wMjRlLWIxMmUtMzA1MzAzY2QwN2M4IiBzdEV2dDp3aGVuPSIyMDIzLTExLTEzVDAwOjE4OjAyKzAxOjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgMjUuMSAoV2luZG93cykiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjQ4OWY1NzlmLTJkNjUtZWQ0Zi04OTg0LTA4NGE2MGE1ZTMzNSIgc3RFdnQ6d2hlbj0iMjAyMy0xMS0xNVQwMjowNDo1OSswMTowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDI1LjEgKFdpbmRvd3MpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDpiMmM0YTYwOS1iZmE3LWE4NDAtYjhhZS05NzMxNmYzNWRiMjciIHN0RXZ0OndoZW49IjIwMjMtMTEtMTVUMDI6MDQ6NTkrMDE6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyNS4xIChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4OTe6GAAAAx0lEQVR42u3WMQoAIQxFwRzJys77X8vSLiRgITif7bYbgrwYc/mKXyBoY4VVBgsWLFiwYFmOlTv+9jfDOjHmr8u6eVkGCxYsWLBgmc5S8ApewXvgYRksWLBgKXidpeBdloL3wMOCBctgwVLwCl7BuyyDBQsWLFiwTGcpeAWv4D3wsAwWLFiwFLzOUvAuS8F74GHBgmWwYCl4Ba/gXZbBggULFixYprMUvIJX8B54WAYLFixYCl5nKXiXpeA98LBgwTJYsGC9tg1o8f4TTtqzNQAAAABJRU5ErkJggg==',\r\n CLEAR_BACKGROUND_COLOR: '#040506',\r\n NODE_TITLE_COLOR: '#999',\r\n NODE_SELECTED_TITLE_COLOR: '#e5eaf0',\r\n NODE_TEXT_SIZE: 14,\r\n NODE_TEXT_COLOR: '#bcc2c8',\r\n NODE_SUBTEXT_SIZE: 12,\r\n NODE_DEFAULT_COLOR: '#161b22',\r\n NODE_DEFAULT_BGCOLOR: '#13171d',\r\n NODE_DEFAULT_BOXCOLOR: '#30363d',\r\n NODE_DEFAULT_SHAPE: 'box',\r\n NODE_BOX_OUTLINE_COLOR: '#e5eaf0',\r\n DEFAULT_SHADOW_COLOR: 'rgba(0,0,0,0.5)',\r\n DEFAULT_GROUP_FONT: 24,\r\n WIDGET_BGCOLOR: '#161b22',\r\n WIDGET_OUTLINE_COLOR: '#30363d',\r\n WIDGET_TEXT_COLOR: '#bcc2c8',\r\n WIDGET_SECONDARY_TEXT_COLOR: '#999',\r\n LINK_COLOR: '#9A9',\r\n EVENT_LINK_COLOR: '#A86',\r\n CONNECTING_LINK_COLOR: '#AFA'\r\n },\r\n comfy_base: {\r\n 'fg-color': '#e5eaf0',\r\n 'bg-color': '#161b22',\r\n 'comfy-menu-bg': '#13171d',\r\n 'comfy-input-bg': '#161b22',\r\n 'input-text': '#bcc2c8',\r\n 'descrip-text': '#999',\r\n 'drag-text': '#ccc',\r\n 'error-text': '#ff4444',\r\n 'border-color': '#30363d',\r\n 'tr-even-bg-color': '#161b22',\r\n 'tr-odd-bg-color': '#13171d',\r\n 'content-bg': '#30363d',\r\n 'content-fg': '#e5eaf0',\r\n 'content-hover-bg': '#161b22',\r\n 'content-hover-fg': '#e5eaf0'\r\n }\r\n }\r\n }\r\n}\r\n\r\nconst id = 'Comfy.ColorPalette'\r\nconst idCustomColorPalettes = 'Comfy.CustomColorPalettes'\r\nconst defaultColorPaletteId = 'dark'\r\nconst els: { select: HTMLSelectElement | null } = {\r\n select: null\r\n}\r\n// const ctxMenu = LiteGraph.ContextMenu;\r\napp.registerExtension({\r\n name: id,\r\n init() {\r\n /**\r\n * Changes the background color of the canvas.\r\n *\r\n * @method updateBackground\r\n * @param {image} String\r\n * @param {clearBackgroundColor} String\r\n */\r\n // @ts-expect-error\r\n LGraphCanvas.prototype.updateBackground = function (\r\n image,\r\n clearBackgroundColor\r\n ) {\r\n this._bg_img = new Image()\r\n this._bg_img.name = image\r\n this._bg_img.src = image\r\n this._bg_img.onload = () => {\r\n this.draw(true, true)\r\n }\r\n this.background_image = image\r\n\r\n this.clear_background = true\r\n this.clear_background_color = clearBackgroundColor\r\n this._pattern = null\r\n }\r\n },\r\n addCustomNodeDefs(node_defs) {\r\n const sortObjectKeys = (unordered) => {\r\n return Object.keys(unordered)\r\n .sort()\r\n .reduce((obj, key) => {\r\n obj[key] = unordered[key]\r\n return obj\r\n }, {})\r\n }\r\n\r\n function getSlotTypes() {\r\n var types = []\r\n\r\n const defs = node_defs\r\n for (const nodeId in defs) {\r\n const nodeData = defs[nodeId]\r\n\r\n var inputs = nodeData['input']['required']\r\n if (nodeData['input']['optional'] !== undefined) {\r\n inputs = Object.assign(\r\n {},\r\n nodeData['input']['required'],\r\n nodeData['input']['optional']\r\n )\r\n }\r\n\r\n for (const inputName in inputs) {\r\n const inputData = inputs[inputName]\r\n const type = inputData[0]\r\n\r\n if (!Array.isArray(type)) {\r\n types.push(type)\r\n }\r\n }\r\n\r\n for (const o in nodeData['output']) {\r\n const output = nodeData['output'][o]\r\n types.push(output)\r\n }\r\n }\r\n\r\n return types\r\n }\r\n\r\n function completeColorPalette(colorPalette) {\r\n var types = getSlotTypes()\r\n\r\n for (const type of types) {\r\n if (!colorPalette.colors.node_slot[type]) {\r\n colorPalette.colors.node_slot[type] = ''\r\n }\r\n }\r\n\r\n colorPalette.colors.node_slot = sortObjectKeys(\r\n colorPalette.colors.node_slot\r\n )\r\n\r\n return colorPalette\r\n }\r\n\r\n const getColorPaletteTemplate = async () => {\r\n let colorPalette = {\r\n id: 'my_color_palette_unique_id',\r\n name: 'My Color Palette',\r\n colors: {\r\n node_slot: {},\r\n litegraph_base: {},\r\n comfy_base: {}\r\n }\r\n }\r\n\r\n // Copy over missing keys from default color palette\r\n const defaultColorPalette = colorPalettes[defaultColorPaletteId]\r\n for (const key in defaultColorPalette.colors.litegraph_base) {\r\n if (!colorPalette.colors.litegraph_base[key]) {\r\n colorPalette.colors.litegraph_base[key] = ''\r\n }\r\n }\r\n for (const key in defaultColorPalette.colors.comfy_base) {\r\n if (!colorPalette.colors.comfy_base[key]) {\r\n colorPalette.colors.comfy_base[key] = ''\r\n }\r\n }\r\n\r\n return completeColorPalette(colorPalette)\r\n }\r\n\r\n const getCustomColorPalettes = (): ColorPalettes => {\r\n return app.ui.settings.getSettingValue(idCustomColorPalettes, {})\r\n }\r\n\r\n const setCustomColorPalettes = (customColorPalettes: ColorPalettes) => {\r\n return app.ui.settings.setSettingValue(\r\n idCustomColorPalettes,\r\n customColorPalettes\r\n )\r\n }\r\n\r\n const addCustomColorPalette = async (colorPalette) => {\r\n if (typeof colorPalette !== 'object') {\r\n alert('Invalid color palette.')\r\n return\r\n }\r\n\r\n if (!colorPalette.id) {\r\n alert('Color palette missing id.')\r\n return\r\n }\r\n\r\n if (!colorPalette.name) {\r\n alert('Color palette missing name.')\r\n return\r\n }\r\n\r\n if (!colorPalette.colors) {\r\n alert('Color palette missing colors.')\r\n return\r\n }\r\n\r\n if (\r\n colorPalette.colors.node_slot &&\r\n typeof colorPalette.colors.node_slot !== 'object'\r\n ) {\r\n alert('Invalid color palette colors.node_slot.')\r\n return\r\n }\r\n\r\n const customColorPalettes = getCustomColorPalettes()\r\n customColorPalettes[colorPalette.id] = colorPalette\r\n setCustomColorPalettes(customColorPalettes)\r\n\r\n for (const option of els.select.childNodes) {\r\n if (\r\n (option as HTMLOptionElement).value ===\r\n 'custom_' + colorPalette.id\r\n ) {\r\n els.select.removeChild(option)\r\n }\r\n }\r\n\r\n els.select.append(\r\n $el('option', {\r\n textContent: colorPalette.name + ' (custom)',\r\n value: 'custom_' + colorPalette.id,\r\n selected: true\r\n })\r\n )\r\n\r\n setColorPalette('custom_' + colorPalette.id)\r\n await loadColorPalette(colorPalette)\r\n }\r\n\r\n const deleteCustomColorPalette = async (colorPaletteId) => {\r\n const customColorPalettes = getCustomColorPalettes()\r\n delete customColorPalettes[colorPaletteId]\r\n setCustomColorPalettes(customColorPalettes)\r\n\r\n for (const opt of els.select.childNodes) {\r\n const option = opt as HTMLOptionElement\r\n if (option.value === defaultColorPaletteId) {\r\n option.selected = true\r\n }\r\n\r\n if (option.value === 'custom_' + colorPaletteId) {\r\n els.select.removeChild(option)\r\n }\r\n }\r\n\r\n setColorPalette(defaultColorPaletteId)\r\n await loadColorPalette(getColorPalette())\r\n }\r\n\r\n const loadColorPalette = async (colorPalette: Palette) => {\r\n colorPalette = await completeColorPalette(colorPalette)\r\n if (colorPalette.colors) {\r\n // Sets the colors of node slots and links\r\n if (colorPalette.colors.node_slot) {\r\n Object.assign(\r\n // @ts-expect-error\r\n app.canvas.default_connection_color_byType,\r\n colorPalette.colors.node_slot\r\n )\r\n Object.assign(\r\n LGraphCanvas.link_type_colors,\r\n colorPalette.colors.node_slot\r\n )\r\n }\r\n // Sets the colors of the LiteGraph objects\r\n if (colorPalette.colors.litegraph_base) {\r\n // Everything updates correctly in the loop, except the Node Title and Link Color for some reason\r\n app.canvas.node_title_color =\r\n colorPalette.colors.litegraph_base.NODE_TITLE_COLOR\r\n app.canvas.default_link_color =\r\n colorPalette.colors.litegraph_base.LINK_COLOR\r\n\r\n for (const key in colorPalette.colors.litegraph_base) {\r\n if (\r\n colorPalette.colors.litegraph_base.hasOwnProperty(key) &&\r\n LiteGraph.hasOwnProperty(key)\r\n ) {\r\n LiteGraph[key] = colorPalette.colors.litegraph_base[key]\r\n }\r\n }\r\n }\r\n // Sets the color of ComfyUI elements\r\n if (colorPalette.colors.comfy_base) {\r\n const rootStyle = document.documentElement.style\r\n for (const key in colorPalette.colors.comfy_base) {\r\n rootStyle.setProperty(\r\n '--' + key,\r\n colorPalette.colors.comfy_base[key]\r\n )\r\n }\r\n }\r\n app.canvas.draw(true, true)\r\n }\r\n }\r\n\r\n const getColorPalette = (colorPaletteId?) => {\r\n if (!colorPaletteId) {\r\n colorPaletteId = app.ui.settings.getSettingValue(\r\n id,\r\n defaultColorPaletteId\r\n )\r\n }\r\n\r\n if (colorPaletteId.startsWith('custom_')) {\r\n colorPaletteId = colorPaletteId.substr(7)\r\n let customColorPalettes = getCustomColorPalettes()\r\n if (customColorPalettes[colorPaletteId]) {\r\n return customColorPalettes[colorPaletteId]\r\n }\r\n }\r\n\r\n return colorPalettes[colorPaletteId]\r\n }\r\n\r\n const setColorPalette = (colorPaletteId) => {\r\n app.ui.settings.setSettingValue(id, colorPaletteId)\r\n }\r\n\r\n const fileInput = $el('input', {\r\n type: 'file',\r\n accept: '.json',\r\n style: { display: 'none' },\r\n parent: document.body,\r\n onchange: () => {\r\n const file = fileInput.files[0]\r\n if (file.type === 'application/json' || file.name.endsWith('.json')) {\r\n const reader = new FileReader()\r\n reader.onload = async () => {\r\n await addCustomColorPalette(JSON.parse(reader.result as string))\r\n }\r\n reader.readAsText(file)\r\n }\r\n }\r\n }) as HTMLInputElement\r\n\r\n app.ui.settings.addSetting({\r\n id,\r\n category: ['Comfy', 'ColorPalette'],\r\n name: 'Color Palette',\r\n type: (name, setter, value) => {\r\n const options = [\r\n ...Object.values(colorPalettes).map((c) =>\r\n $el('option', {\r\n textContent: c.name,\r\n value: c.id,\r\n selected: c.id === value\r\n })\r\n ),\r\n ...Object.values(getCustomColorPalettes()).map((c) =>\r\n $el('option', {\r\n textContent: `${c.name} (custom)`,\r\n value: `custom_${c.id}`,\r\n selected: `custom_${c.id}` === value\r\n })\r\n )\r\n ]\r\n\r\n els.select = $el(\r\n 'select',\r\n {\r\n style: {\r\n marginBottom: '0.15rem',\r\n width: '100%'\r\n },\r\n onchange: (e) => {\r\n setter(e.target.value)\r\n }\r\n },\r\n options\r\n ) as HTMLSelectElement\r\n\r\n return $el('tr', [\r\n $el('td', [\r\n els.select,\r\n $el(\r\n 'div',\r\n {\r\n style: {\r\n display: 'grid',\r\n gap: '4px',\r\n gridAutoFlow: 'column'\r\n }\r\n },\r\n [\r\n $el('input', {\r\n type: 'button',\r\n value: 'Export',\r\n onclick: async () => {\r\n const colorPaletteId = app.ui.settings.getSettingValue(\r\n id,\r\n defaultColorPaletteId\r\n )\r\n const colorPalette = await completeColorPalette(\r\n getColorPalette(colorPaletteId)\r\n )\r\n const json = JSON.stringify(colorPalette, null, 2) // convert the data to a JSON string\r\n const blob = new Blob([json], { type: 'application/json' })\r\n const url = URL.createObjectURL(blob)\r\n const a = $el('a', {\r\n href: url,\r\n download: colorPaletteId + '.json',\r\n style: { display: 'none' },\r\n parent: document.body\r\n })\r\n a.click()\r\n setTimeout(function () {\r\n a.remove()\r\n window.URL.revokeObjectURL(url)\r\n }, 0)\r\n }\r\n }),\r\n $el('input', {\r\n type: 'button',\r\n value: 'Import',\r\n onclick: () => {\r\n fileInput.click()\r\n }\r\n }),\r\n $el('input', {\r\n type: 'button',\r\n value: 'Template',\r\n onclick: async () => {\r\n const colorPalette = await getColorPaletteTemplate()\r\n const json = JSON.stringify(colorPalette, null, 2) // convert the data to a JSON string\r\n const blob = new Blob([json], { type: 'application/json' })\r\n const url = URL.createObjectURL(blob)\r\n const a = $el('a', {\r\n href: url,\r\n download: 'color_palette.json',\r\n style: { display: 'none' },\r\n parent: document.body\r\n })\r\n a.click()\r\n setTimeout(function () {\r\n a.remove()\r\n window.URL.revokeObjectURL(url)\r\n }, 0)\r\n }\r\n }),\r\n $el('input', {\r\n type: 'button',\r\n value: 'Delete',\r\n onclick: async () => {\r\n let colorPaletteId = app.ui.settings.getSettingValue(\r\n id,\r\n defaultColorPaletteId\r\n )\r\n\r\n if (colorPalettes[colorPaletteId]) {\r\n alert('You cannot delete a built-in color palette.')\r\n return\r\n }\r\n\r\n if (colorPaletteId.startsWith('custom_')) {\r\n colorPaletteId = colorPaletteId.substr(7)\r\n }\r\n\r\n await deleteCustomColorPalette(colorPaletteId)\r\n }\r\n })\r\n ]\r\n )\r\n ])\r\n ])\r\n },\r\n defaultValue: defaultColorPaletteId,\r\n async onChange(value) {\r\n if (!value) {\r\n return\r\n }\r\n\r\n let palette = colorPalettes[value]\r\n if (palette) {\r\n await loadColorPalette(palette)\r\n } else if (value.startsWith('custom_')) {\r\n value = value.substr(7)\r\n let customColorPalettes = getCustomColorPalettes()\r\n if (customColorPalettes[value]) {\r\n palette = customColorPalettes[value]\r\n await loadColorPalette(customColorPalettes[value])\r\n }\r\n }\r\n\r\n let { BACKGROUND_IMAGE, CLEAR_BACKGROUND_COLOR } =\r\n palette.colors.litegraph_base\r\n if (\r\n BACKGROUND_IMAGE === undefined ||\r\n CLEAR_BACKGROUND_COLOR === undefined\r\n ) {\r\n const base = colorPalettes['dark'].colors.litegraph_base\r\n BACKGROUND_IMAGE = base.BACKGROUND_IMAGE\r\n CLEAR_BACKGROUND_COLOR = base.CLEAR_BACKGROUND_COLOR\r\n }\r\n // @ts-expect-error\r\n // litegraph.extensions.js\r\n app.canvas.updateBackground(BACKGROUND_IMAGE, CLEAR_BACKGROUND_COLOR)\r\n }\r\n })\r\n }\r\n})\r\n","import { LiteGraph, LGraphCanvas } from '@comfyorg/litegraph'\r\nimport { app } from '../../scripts/app'\r\n\r\n// Adds filtering to combo context menus\r\n\r\nconst ext = {\r\n name: 'Comfy.ContextMenuFilter',\r\n init() {\r\n const ctxMenu = LiteGraph.ContextMenu\r\n // @ts-expect-error\r\n // TODO Very hacky way to modify Litegraph behaviour. Fix this later.\r\n LiteGraph.ContextMenu = function (values, options) {\r\n const ctx = ctxMenu.call(this, values, options)\r\n\r\n // If we are a dark menu (only used for combo boxes) then add a filter input\r\n if (options?.className === 'dark' && values?.length > 10) {\r\n const filter = document.createElement('input')\r\n filter.classList.add('comfy-context-menu-filter')\r\n filter.placeholder = 'Filter list'\r\n this.root.prepend(filter)\r\n\r\n const items = Array.from(\r\n this.root.querySelectorAll('.litemenu-entry')\r\n ) as HTMLElement[]\r\n let displayedItems = [...items]\r\n let itemCount = displayedItems.length\r\n\r\n // We must request an animation frame for the current node of the active canvas to update.\r\n requestAnimationFrame(() => {\r\n // @ts-expect-error\r\n const currentNode = LGraphCanvas.active_canvas.current_node\r\n const clickedComboValue = currentNode.widgets\r\n ?.filter(\r\n (w) =>\r\n w.type === 'combo' && w.options.values.length === values.length\r\n )\r\n .find((w) =>\r\n w.options.values.every((v, i) => v === values[i])\r\n )?.value\r\n\r\n let selectedIndex = clickedComboValue\r\n ? values.findIndex((v) => v === clickedComboValue)\r\n : 0\r\n if (selectedIndex < 0) {\r\n selectedIndex = 0\r\n }\r\n let selectedItem = displayedItems[selectedIndex]\r\n updateSelected()\r\n\r\n // Apply highlighting to the selected item\r\n function updateSelected() {\r\n selectedItem?.style.setProperty('background-color', '')\r\n selectedItem?.style.setProperty('color', '')\r\n selectedItem = displayedItems[selectedIndex]\r\n selectedItem?.style.setProperty(\r\n 'background-color',\r\n '#ccc',\r\n 'important'\r\n )\r\n selectedItem?.style.setProperty('color', '#000', 'important')\r\n }\r\n\r\n const positionList = () => {\r\n const rect = this.root.getBoundingClientRect()\r\n\r\n // If the top is off-screen then shift the element with scaling applied\r\n if (rect.top < 0) {\r\n const scale =\r\n 1 -\r\n this.root.getBoundingClientRect().height /\r\n this.root.clientHeight\r\n const shift = (this.root.clientHeight * scale) / 2\r\n this.root.style.top = -shift + 'px'\r\n }\r\n }\r\n\r\n // Arrow up/down to select items\r\n filter.addEventListener('keydown', (event) => {\r\n switch (event.key) {\r\n case 'ArrowUp':\r\n event.preventDefault()\r\n if (selectedIndex === 0) {\r\n selectedIndex = itemCount - 1\r\n } else {\r\n selectedIndex--\r\n }\r\n updateSelected()\r\n break\r\n case 'ArrowRight':\r\n event.preventDefault()\r\n selectedIndex = itemCount - 1\r\n updateSelected()\r\n break\r\n case 'ArrowDown':\r\n event.preventDefault()\r\n if (selectedIndex === itemCount - 1) {\r\n selectedIndex = 0\r\n } else {\r\n selectedIndex++\r\n }\r\n updateSelected()\r\n break\r\n case 'ArrowLeft':\r\n event.preventDefault()\r\n selectedIndex = 0\r\n updateSelected()\r\n break\r\n case 'Enter':\r\n selectedItem?.click()\r\n break\r\n case 'Escape':\r\n this.close()\r\n break\r\n }\r\n })\r\n\r\n filter.addEventListener('input', () => {\r\n // Hide all items that don't match our filter\r\n const term = filter.value.toLocaleLowerCase()\r\n // When filtering, recompute which items are visible for arrow up/down and maintain selection.\r\n displayedItems = items.filter((item) => {\r\n const isVisible =\r\n !term || item.textContent.toLocaleLowerCase().includes(term)\r\n item.style.display = isVisible ? 'block' : 'none'\r\n return isVisible\r\n })\r\n\r\n selectedIndex = 0\r\n if (displayedItems.includes(selectedItem)) {\r\n selectedIndex = displayedItems.findIndex(\r\n (d) => d === selectedItem\r\n )\r\n }\r\n itemCount = displayedItems.length\r\n\r\n updateSelected()\r\n\r\n // If we have an event then we can try and position the list under the source\r\n if (options.event) {\r\n let top = options.event.clientY - 10\r\n\r\n const bodyRect = document.body.getBoundingClientRect()\r\n const rootRect = this.root.getBoundingClientRect()\r\n if (\r\n bodyRect.height &&\r\n top > bodyRect.height - rootRect.height - 10\r\n ) {\r\n top = Math.max(0, bodyRect.height - rootRect.height - 10)\r\n }\r\n\r\n this.root.style.top = top + 'px'\r\n positionList()\r\n }\r\n })\r\n\r\n requestAnimationFrame(() => {\r\n // Focus the filter box when opening\r\n filter.focus()\r\n\r\n positionList()\r\n })\r\n })\r\n }\r\n\r\n return ctx\r\n }\r\n\r\n LiteGraph.ContextMenu.prototype = ctxMenu.prototype\r\n }\r\n}\r\n\r\napp.registerExtension(ext)\r\n","import { app } from '../../scripts/app'\r\n\r\n// Allows for simple dynamic prompt replacement\r\n// Inputs in the format {a|b} will have a random value of a or b chosen when the prompt is queued.\r\n\r\n/*\r\n * Strips C-style line and block comments from a string\r\n */\r\nfunction stripComments(str) {\r\n return str.replace(/\\/\\*[\\s\\S]*?\\*\\/|\\/\\/.*/g, '')\r\n}\r\n\r\napp.registerExtension({\r\n name: 'Comfy.DynamicPrompts',\r\n nodeCreated(node) {\r\n if (node.widgets) {\r\n // Locate dynamic prompt text widgets\r\n // Include any widgets with dynamicPrompts set to true, and customtext\r\n const widgets = node.widgets.filter((n) => n.dynamicPrompts)\r\n for (const widget of widgets) {\r\n // Override the serialization of the value to resolve dynamic prompts for all widgets supporting it in this node\r\n widget.serializeValue = (workflowNode, widgetIndex) => {\r\n let prompt = stripComments(widget.value)\r\n while (\r\n prompt.replace('\\\\{', '').includes('{') &&\r\n prompt.replace('\\\\}', '').includes('}')\r\n ) {\r\n const startIndex = prompt.replace('\\\\{', '00').indexOf('{')\r\n const endIndex = prompt.replace('\\\\}', '00').indexOf('}')\r\n\r\n const optionsString = prompt.substring(startIndex + 1, endIndex)\r\n const options = optionsString.split('|')\r\n\r\n const randomIndex = Math.floor(Math.random() * options.length)\r\n const randomOption = options[randomIndex]\r\n\r\n prompt =\r\n prompt.substring(0, startIndex) +\r\n randomOption +\r\n prompt.substring(endIndex + 1)\r\n }\r\n\r\n // Overwrite the value in the serialized workflow pnginfo\r\n if (workflowNode?.widgets_values)\r\n workflowNode.widgets_values[widgetIndex] = prompt\r\n\r\n return prompt\r\n }\r\n }\r\n }\r\n }\r\n})\r\n","import { app } from '../../scripts/app'\r\n\r\n// Allows you to edit the attention weight by holding ctrl (or cmd) and using the up/down arrow keys\r\n\r\napp.registerExtension({\r\n name: 'Comfy.EditAttention',\r\n init() {\r\n const editAttentionDelta = app.ui.settings.addSetting({\r\n id: 'Comfy.EditAttention.Delta',\r\n name: 'Ctrl+up/down precision',\r\n type: 'slider',\r\n attrs: {\r\n min: 0.01,\r\n max: 0.5,\r\n step: 0.01\r\n },\r\n defaultValue: 0.05\r\n })\r\n\r\n function incrementWeight(weight, delta) {\r\n const floatWeight = parseFloat(weight)\r\n if (isNaN(floatWeight)) return weight\r\n const newWeight = floatWeight + delta\r\n return String(Number(newWeight.toFixed(10)))\r\n }\r\n\r\n function findNearestEnclosure(text, cursorPos) {\r\n let start = cursorPos,\r\n end = cursorPos\r\n let openCount = 0,\r\n closeCount = 0\r\n\r\n // Find opening parenthesis before cursor\r\n while (start >= 0) {\r\n start--\r\n if (text[start] === '(' && openCount === closeCount) break\r\n if (text[start] === '(') openCount++\r\n if (text[start] === ')') closeCount++\r\n }\r\n if (start < 0) return false\r\n\r\n openCount = 0\r\n closeCount = 0\r\n\r\n // Find closing parenthesis after cursor\r\n while (end < text.length) {\r\n if (text[end] === ')' && openCount === closeCount) break\r\n if (text[end] === '(') openCount++\r\n if (text[end] === ')') closeCount++\r\n end++\r\n }\r\n if (end === text.length) return false\r\n\r\n return { start: start + 1, end: end }\r\n }\r\n\r\n function addWeightToParentheses(text) {\r\n const parenRegex = /^\\((.*)\\)$/\r\n const parenMatch = text.match(parenRegex)\r\n\r\n const floatRegex = /:([+-]?(\\d*\\.)?\\d+([eE][+-]?\\d+)?)/\r\n const floatMatch = text.match(floatRegex)\r\n\r\n if (parenMatch && !floatMatch) {\r\n return `(${parenMatch[1]}:1.0)`\r\n } else {\r\n return text\r\n }\r\n }\r\n\r\n function editAttention(event) {\r\n const inputField = event.composedPath()[0]\r\n const delta = parseFloat(editAttentionDelta.value)\r\n\r\n if (inputField.tagName !== 'TEXTAREA') return\r\n if (!(event.key === 'ArrowUp' || event.key === 'ArrowDown')) return\r\n if (!event.ctrlKey && !event.metaKey) return\r\n\r\n event.preventDefault()\r\n\r\n let start = inputField.selectionStart\r\n let end = inputField.selectionEnd\r\n let selectedText = inputField.value.substring(start, end)\r\n\r\n // If there is no selection, attempt to find the nearest enclosure, or select the current word\r\n if (!selectedText) {\r\n const nearestEnclosure = findNearestEnclosure(inputField.value, start)\r\n if (nearestEnclosure) {\r\n start = nearestEnclosure.start\r\n end = nearestEnclosure.end\r\n selectedText = inputField.value.substring(start, end)\r\n } else {\r\n // Select the current word, find the start and end of the word\r\n const delimiters = ' .,\\\\/!?%^*;:{}=-_`~()\\r\\n\\t'\r\n\r\n while (\r\n !delimiters.includes(inputField.value[start - 1]) &&\r\n start > 0\r\n ) {\r\n start--\r\n }\r\n\r\n while (\r\n !delimiters.includes(inputField.value[end]) &&\r\n end < inputField.value.length\r\n ) {\r\n end++\r\n }\r\n\r\n selectedText = inputField.value.substring(start, end)\r\n if (!selectedText) return\r\n }\r\n }\r\n\r\n // If the selection ends with a space, remove it\r\n if (selectedText[selectedText.length - 1] === ' ') {\r\n selectedText = selectedText.substring(0, selectedText.length - 1)\r\n end -= 1\r\n }\r\n\r\n // If there are parentheses left and right of the selection, select them\r\n if (\r\n inputField.value[start - 1] === '(' &&\r\n inputField.value[end] === ')'\r\n ) {\r\n start -= 1\r\n end += 1\r\n selectedText = inputField.value.substring(start, end)\r\n }\r\n\r\n // If the selection is not enclosed in parentheses, add them\r\n if (\r\n selectedText[0] !== '(' ||\r\n selectedText[selectedText.length - 1] !== ')'\r\n ) {\r\n selectedText = `(${selectedText})`\r\n }\r\n\r\n // If the selection does not have a weight, add a weight of 1.0\r\n selectedText = addWeightToParentheses(selectedText)\r\n\r\n // Increment the weight\r\n const weightDelta = event.key === 'ArrowUp' ? delta : -delta\r\n const updatedText = selectedText.replace(\r\n /\\((.*):([+-]?\\d+(?:\\.\\d+)?)\\)/,\r\n (match, text, weight) => {\r\n weight = incrementWeight(weight, weightDelta)\r\n if (weight == 1) {\r\n return text\r\n } else {\r\n return `(${text}:${weight})`\r\n }\r\n }\r\n )\r\n\r\n inputField.setRangeText(updatedText, start, end, 'select')\r\n }\r\n window.addEventListener('keydown', editAttention)\r\n }\r\n})\r\n","import { ComfyWidgets, addValueControlWidgets } from '../../scripts/widgets'\r\nimport { app } from '../../scripts/app'\r\nimport { applyTextReplacements } from '../../scripts/utils'\r\nimport { LiteGraph } from '@comfyorg/litegraph'\r\nimport type { LGraphNode, INodeInputSlot, IWidget } from '@comfyorg/litegraph'\r\n\r\nconst CONVERTED_TYPE = 'converted-widget'\r\nconst VALID_TYPES = ['STRING', 'combo', 'number', 'toggle', 'BOOLEAN']\r\nconst CONFIG = Symbol()\r\nconst GET_CONFIG = Symbol()\r\nconst TARGET = Symbol() // Used for reroutes to specify the real target widget\r\n\r\ninterface PrimitiveNode extends LGraphNode {}\r\n\r\nconst replacePropertyName = 'Run widget replace on values'\r\nclass PrimitiveNode {\r\n controlValues: any[]\r\n lastType: string\r\n static category: string\r\n constructor() {\r\n this.addOutput('connect to widget input', '*')\r\n this.serialize_widgets = true\r\n this.isVirtualNode = true\r\n\r\n if (!this.properties || !(replacePropertyName in this.properties)) {\r\n this.addProperty(replacePropertyName, false, 'boolean')\r\n }\r\n }\r\n\r\n applyToGraph(extraLinks = []) {\r\n if (!this.outputs[0].links?.length) return\r\n\r\n function get_links(node) {\r\n let links = []\r\n for (const l of node.outputs[0].links) {\r\n const linkInfo = app.graph.links[l]\r\n const n = node.graph.getNodeById(linkInfo.target_id)\r\n if (n.type == 'Reroute') {\r\n links = links.concat(get_links(n))\r\n } else {\r\n links.push(l)\r\n }\r\n }\r\n return links\r\n }\r\n\r\n let links = [\r\n ...get_links(this).map((l) => app.graph.links[l]),\r\n ...extraLinks\r\n ]\r\n let v = this.widgets?.[0].value\r\n if (v && this.properties[replacePropertyName]) {\r\n v = applyTextReplacements(app, v)\r\n }\r\n\r\n // For each output link copy our value over the original widget value\r\n for (const linkInfo of links) {\r\n const node = this.graph.getNodeById(linkInfo.target_id)\r\n const input = node.inputs[linkInfo.target_slot]\r\n let widget\r\n if (input.widget[TARGET]) {\r\n widget = input.widget[TARGET]\r\n } else {\r\n const widgetName = (input.widget as { name: string }).name\r\n if (widgetName) {\r\n widget = node.widgets.find((w) => w.name === widgetName)\r\n }\r\n }\r\n\r\n if (widget) {\r\n widget.value = v\r\n if (widget.callback) {\r\n widget.callback(\r\n widget.value,\r\n app.canvas,\r\n node,\r\n app.canvas.graph_mouse,\r\n {}\r\n )\r\n }\r\n }\r\n }\r\n }\r\n\r\n refreshComboInNode() {\r\n const widget = this.widgets?.[0]\r\n if (widget?.type === 'combo') {\r\n widget.options.values = this.outputs[0].widget[GET_CONFIG]()[0]\r\n\r\n if (!widget.options.values.includes(widget.value)) {\r\n widget.value = widget.options.values[0]\r\n ;(widget.callback as Function)(widget.value)\r\n }\r\n }\r\n }\r\n\r\n onAfterGraphConfigured() {\r\n if (this.outputs[0].links?.length && !this.widgets?.length) {\r\n // TODO: Review this check\r\n // @ts-expect-error\r\n if (!this.#onFirstConnection()) return\r\n\r\n // Populate widget values from config data\r\n if (this.widgets) {\r\n for (let i = 0; i < this.widgets_values.length; i++) {\r\n const w = this.widgets[i]\r\n if (w) {\r\n w.value = this.widgets_values[i]\r\n }\r\n }\r\n }\r\n\r\n // Merge values if required\r\n this.#mergeWidgetConfig()\r\n }\r\n }\r\n\r\n onConnectionsChange(_, index, connected) {\r\n if (app.configuringGraph) {\r\n // Dont run while the graph is still setting up\r\n return\r\n }\r\n\r\n const links = this.outputs[0].links\r\n if (connected) {\r\n if (links?.length && !this.widgets?.length) {\r\n this.#onFirstConnection()\r\n }\r\n } else {\r\n // We may have removed a link that caused the constraints to change\r\n this.#mergeWidgetConfig()\r\n\r\n if (!links?.length) {\r\n this.onLastDisconnect()\r\n }\r\n }\r\n }\r\n\r\n onConnectOutput(slot, type, input, target_node, target_slot) {\r\n // Fires before the link is made allowing us to reject it if it isn't valid\r\n // No widget, we cant connect\r\n if (!input.widget) {\r\n if (!(input.type in ComfyWidgets)) return false\r\n }\r\n\r\n if (this.outputs[slot].links?.length) {\r\n const valid = this.#isValidConnection(input)\r\n if (valid) {\r\n // On connect of additional outputs, copy our value to their widget\r\n this.applyToGraph([{ target_id: target_node.id, target_slot }])\r\n }\r\n return valid\r\n }\r\n }\r\n\r\n #onFirstConnection(recreating?: boolean) {\r\n // First connection can fire before the graph is ready on initial load so random things can be missing\r\n if (!this.outputs[0].links) {\r\n this.onLastDisconnect()\r\n return\r\n }\r\n const linkId = this.outputs[0].links[0]\r\n const link = this.graph.links[linkId]\r\n if (!link) return\r\n\r\n const theirNode = this.graph.getNodeById(link.target_id)\r\n if (!theirNode || !theirNode.inputs) return\r\n\r\n const input = theirNode.inputs[link.target_slot]\r\n if (!input) return\r\n\r\n let widget\r\n if (!input.widget) {\r\n if (!(input.type in ComfyWidgets)) return\r\n widget = { name: input.name, [GET_CONFIG]: () => [input.type, {}] } //fake widget\r\n } else {\r\n widget = input.widget\r\n }\r\n\r\n const config = widget[GET_CONFIG]?.()\r\n if (!config) return\r\n\r\n const { type } = getWidgetType(config)\r\n // Update our output to restrict to the widget type\r\n this.outputs[0].type = type\r\n this.outputs[0].name = type\r\n this.outputs[0].widget = widget\r\n\r\n this.#createWidget(\r\n widget[CONFIG] ?? config,\r\n theirNode,\r\n widget.name,\r\n recreating,\r\n widget[TARGET]\r\n )\r\n }\r\n\r\n #createWidget(inputData, node, widgetName, recreating, targetWidget) {\r\n let type = inputData[0]\r\n\r\n if (type instanceof Array) {\r\n type = 'COMBO'\r\n }\r\n\r\n let widget\r\n if (type in ComfyWidgets) {\r\n widget = (ComfyWidgets[type](this, 'value', inputData, app) || {}).widget\r\n } else {\r\n widget = this.addWidget(type, 'value', null, () => {}, {})\r\n }\r\n\r\n if (targetWidget) {\r\n widget.value = targetWidget.value\r\n } else if (node?.widgets && widget) {\r\n const theirWidget = node.widgets.find((w) => w.name === widgetName)\r\n if (theirWidget) {\r\n widget.value = theirWidget.value\r\n }\r\n }\r\n\r\n if (\r\n !inputData?.[1]?.control_after_generate &&\r\n (widget.type === 'number' || widget.type === 'combo')\r\n ) {\r\n let control_value = this.widgets_values?.[1]\r\n if (!control_value) {\r\n control_value = 'fixed'\r\n }\r\n addValueControlWidgets(\r\n this,\r\n widget,\r\n control_value as string,\r\n undefined,\r\n inputData\r\n )\r\n let filter = this.widgets_values?.[2]\r\n if (filter && this.widgets.length === 3) {\r\n this.widgets[2].value = filter\r\n }\r\n }\r\n\r\n // Restore any saved control values\r\n const controlValues = this.controlValues\r\n if (\r\n this.lastType === this.widgets[0].type &&\r\n controlValues?.length === this.widgets.length - 1\r\n ) {\r\n for (let i = 0; i < controlValues.length; i++) {\r\n this.widgets[i + 1].value = controlValues[i]\r\n }\r\n }\r\n\r\n // When our value changes, update other widgets to reflect our changes\r\n // e.g. so LoadImage shows correct image\r\n const callback = widget.callback\r\n const self = this\r\n widget.callback = function () {\r\n const r = callback ? callback.apply(this, arguments) : undefined\r\n self.applyToGraph()\r\n return r\r\n }\r\n\r\n if (!recreating) {\r\n // Grow our node if required\r\n const sz = this.computeSize()\r\n if (this.size[0] < sz[0]) {\r\n this.size[0] = sz[0]\r\n }\r\n if (this.size[1] < sz[1]) {\r\n this.size[1] = sz[1]\r\n }\r\n\r\n requestAnimationFrame(() => {\r\n if (this.onResize) {\r\n this.onResize(this.size)\r\n }\r\n })\r\n }\r\n }\r\n\r\n recreateWidget() {\r\n const values = this.widgets?.map((w) => w.value)\r\n this.#removeWidgets()\r\n this.#onFirstConnection(true)\r\n if (values?.length) {\r\n for (let i = 0; i < this.widgets?.length; i++)\r\n this.widgets[i].value = values[i]\r\n }\r\n return this.widgets?.[0]\r\n }\r\n\r\n #mergeWidgetConfig() {\r\n // Merge widget configs if the node has multiple outputs\r\n const output = this.outputs[0]\r\n const links = output.links\r\n\r\n const hasConfig = !!output.widget[CONFIG]\r\n if (hasConfig) {\r\n delete output.widget[CONFIG]\r\n }\r\n\r\n if (links?.length < 2 && hasConfig) {\r\n // Copy the widget options from the source\r\n if (links.length) {\r\n this.recreateWidget()\r\n }\r\n\r\n return\r\n }\r\n\r\n const config1 = output.widget[GET_CONFIG]()\r\n const isNumber = config1[0] === 'INT' || config1[0] === 'FLOAT'\r\n if (!isNumber) return\r\n\r\n for (const linkId of links) {\r\n const link = app.graph.links[linkId]\r\n if (!link) continue // Can be null when removing a node\r\n\r\n const theirNode = app.graph.getNodeById(link.target_id)\r\n const theirInput = theirNode.inputs[link.target_slot]\r\n\r\n // Call is valid connection so it can merge the configs when validating\r\n this.#isValidConnection(theirInput, hasConfig)\r\n }\r\n }\r\n\r\n #isValidConnection(input: INodeInputSlot, forceUpdate?: boolean) {\r\n // Only allow connections where the configs match\r\n const output = this.outputs[0]\r\n const config2 = input.widget[GET_CONFIG]()\r\n return !!mergeIfValid.call(\r\n this,\r\n output,\r\n config2,\r\n forceUpdate,\r\n this.recreateWidget\r\n )\r\n }\r\n\r\n #removeWidgets() {\r\n if (this.widgets) {\r\n // Allow widgets to cleanup\r\n for (const w of this.widgets) {\r\n if (w.onRemove) {\r\n w.onRemove()\r\n }\r\n }\r\n\r\n // Temporarily store the current values in case the node is being recreated\r\n // e.g. by group node conversion\r\n this.controlValues = []\r\n this.lastType = this.widgets[0]?.type\r\n for (let i = 1; i < this.widgets.length; i++) {\r\n this.controlValues.push(this.widgets[i].value)\r\n }\r\n setTimeout(() => {\r\n delete this.lastType\r\n delete this.controlValues\r\n }, 15)\r\n this.widgets.length = 0\r\n }\r\n }\r\n\r\n onLastDisconnect() {\r\n // We cant remove + re-add the output here as if you drag a link over the same link\r\n // it removes, then re-adds, causing it to break\r\n this.outputs[0].type = '*'\r\n this.outputs[0].name = 'connect to widget input'\r\n delete this.outputs[0].widget\r\n\r\n this.#removeWidgets()\r\n }\r\n}\r\n\r\nexport function getWidgetConfig(slot) {\r\n return slot.widget[CONFIG] ?? slot.widget[GET_CONFIG]()\r\n}\r\n\r\nfunction getConfig(widgetName) {\r\n const { nodeData } = this.constructor\r\n return (\r\n nodeData?.input?.required?.[widgetName] ??\r\n nodeData?.input?.optional?.[widgetName]\r\n )\r\n}\r\n\r\nfunction isConvertibleWidget(widget, config) {\r\n return (\r\n (VALID_TYPES.includes(widget.type) || VALID_TYPES.includes(config[0])) &&\r\n !widget.options?.forceInput\r\n )\r\n}\r\n\r\nfunction hideWidget(node, widget, suffix = '') {\r\n if (widget.type?.startsWith(CONVERTED_TYPE)) return\r\n widget.origType = widget.type\r\n widget.origComputeSize = widget.computeSize\r\n widget.origSerializeValue = widget.serializeValue\r\n widget.computeSize = () => [0, -4] // -4 is due to the gap litegraph adds between widgets automatically\r\n widget.type = CONVERTED_TYPE + suffix\r\n widget.serializeValue = () => {\r\n // Prevent serializing the widget if we have no input linked\r\n if (!node.inputs) {\r\n return undefined\r\n }\r\n let node_input = node.inputs.find((i) => i.widget?.name === widget.name)\r\n\r\n if (!node_input || !node_input.link) {\r\n return undefined\r\n }\r\n return widget.origSerializeValue\r\n ? widget.origSerializeValue()\r\n : widget.value\r\n }\r\n\r\n // Hide any linked widgets, e.g. seed+seedControl\r\n if (widget.linkedWidgets) {\r\n for (const w of widget.linkedWidgets) {\r\n hideWidget(node, w, ':' + widget.name)\r\n }\r\n }\r\n}\r\n\r\nfunction showWidget(widget) {\r\n widget.type = widget.origType\r\n widget.computeSize = widget.origComputeSize\r\n widget.serializeValue = widget.origSerializeValue\r\n\r\n delete widget.origType\r\n delete widget.origComputeSize\r\n delete widget.origSerializeValue\r\n\r\n // Hide any linked widgets, e.g. seed+seedControl\r\n if (widget.linkedWidgets) {\r\n for (const w of widget.linkedWidgets) {\r\n showWidget(w)\r\n }\r\n }\r\n}\r\n\r\nfunction convertToInput(node, widget, config) {\r\n hideWidget(node, widget)\r\n\r\n const { type } = getWidgetType(config)\r\n\r\n // Add input and store widget config for creating on primitive node\r\n const sz = node.size\r\n node.addInput(widget.name, type, {\r\n widget: { name: widget.name, [GET_CONFIG]: () => config }\r\n })\r\n\r\n for (const widget of node.widgets) {\r\n widget.last_y += LiteGraph.NODE_SLOT_HEIGHT\r\n }\r\n\r\n // Restore original size but grow if needed\r\n node.setSize([Math.max(sz[0], node.size[0]), Math.max(sz[1], node.size[1])])\r\n}\r\n\r\nfunction convertToWidget(node, widget) {\r\n showWidget(widget)\r\n const sz = node.size\r\n node.removeInput(node.inputs.findIndex((i) => i.widget?.name === widget.name))\r\n\r\n for (const widget of node.widgets) {\r\n widget.last_y -= LiteGraph.NODE_SLOT_HEIGHT\r\n }\r\n\r\n // Restore original size but grow if needed\r\n node.setSize([Math.max(sz[0], node.size[0]), Math.max(sz[1], node.size[1])])\r\n}\r\n\r\nfunction getWidgetType(config) {\r\n // Special handling for COMBO so we restrict links based on the entries\r\n let type = config[0]\r\n if (type instanceof Array) {\r\n type = 'COMBO'\r\n }\r\n return { type }\r\n}\r\n\r\nfunction isValidCombo(combo, obj) {\r\n // New input isnt a combo\r\n if (!(obj instanceof Array)) {\r\n console.log(`connection rejected: tried to connect combo to ${obj}`)\r\n return false\r\n }\r\n // New input combo has a different size\r\n if (combo.length !== obj.length) {\r\n console.log(`connection rejected: combo lists dont match`)\r\n return false\r\n }\r\n // New input combo has different elements\r\n if (combo.find((v, i) => obj[i] !== v)) {\r\n console.log(`connection rejected: combo lists dont match`)\r\n return false\r\n }\r\n\r\n return true\r\n}\r\n\r\nfunction isPrimitiveNode(node: LGraphNode): node is PrimitiveNode {\r\n return node.type === 'PrimitiveNode'\r\n}\r\n\r\nexport function setWidgetConfig(slot, config, target?: IWidget) {\r\n if (!slot.widget) return\r\n if (config) {\r\n slot.widget[GET_CONFIG] = () => config\r\n slot.widget[TARGET] = target\r\n } else {\r\n delete slot.widget\r\n }\r\n\r\n if (slot.link) {\r\n const link = app.graph.links[slot.link]\r\n if (link) {\r\n const originNode = app.graph.getNodeById(link.origin_id)\r\n if (isPrimitiveNode(originNode)) {\r\n if (config) {\r\n originNode.recreateWidget()\r\n } else if (!app.configuringGraph) {\r\n originNode.disconnectOutput(0)\r\n originNode.onLastDisconnect()\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport function mergeIfValid(\r\n output,\r\n config2,\r\n forceUpdate?: boolean,\r\n recreateWidget?: () => void,\r\n config1?: unknown\r\n) {\r\n if (!config1) {\r\n config1 = output.widget[CONFIG] ?? output.widget[GET_CONFIG]()\r\n }\r\n\r\n if (config1[0] instanceof Array) {\r\n if (!isValidCombo(config1[0], config2[0])) return\r\n } else if (config1[0] !== config2[0]) {\r\n // Types dont match\r\n console.log(`connection rejected: types dont match`, config1[0], config2[0])\r\n return\r\n }\r\n\r\n const keys = new Set([\r\n ...Object.keys(config1[1] ?? {}),\r\n ...Object.keys(config2[1] ?? {})\r\n ])\r\n\r\n let customConfig\r\n const getCustomConfig = () => {\r\n if (!customConfig) {\r\n if (typeof structuredClone === 'undefined') {\r\n customConfig = JSON.parse(JSON.stringify(config1[1] ?? {}))\r\n } else {\r\n customConfig = structuredClone(config1[1] ?? {})\r\n }\r\n }\r\n return customConfig\r\n }\r\n\r\n const isNumber = config1[0] === 'INT' || config1[0] === 'FLOAT'\r\n for (const k of keys.values()) {\r\n if (\r\n k !== 'default' &&\r\n k !== 'forceInput' &&\r\n k !== 'defaultInput' &&\r\n k !== 'control_after_generate' &&\r\n k !== 'multiline' &&\r\n k !== 'tooltip'\r\n ) {\r\n let v1 = config1[1][k]\r\n let v2 = config2[1]?.[k]\r\n\r\n if (v1 === v2 || (!v1 && !v2)) continue\r\n\r\n if (isNumber) {\r\n if (k === 'min') {\r\n const theirMax = config2[1]?.['max']\r\n if (theirMax != null && v1 > theirMax) {\r\n console.log('connection rejected: min > max', v1, theirMax)\r\n return\r\n }\r\n getCustomConfig()[k] =\r\n v1 == null ? v2 : v2 == null ? v1 : Math.max(v1, v2)\r\n continue\r\n } else if (k === 'max') {\r\n const theirMin = config2[1]?.['min']\r\n if (theirMin != null && v1 < theirMin) {\r\n console.log('connection rejected: max < min', v1, theirMin)\r\n return\r\n }\r\n getCustomConfig()[k] =\r\n v1 == null ? v2 : v2 == null ? v1 : Math.min(v1, v2)\r\n continue\r\n } else if (k === 'step') {\r\n let step\r\n if (v1 == null) {\r\n // No current step\r\n step = v2\r\n } else if (v2 == null) {\r\n // No new step\r\n step = v1\r\n } else {\r\n if (v1 < v2) {\r\n // Ensure v1 is larger for the mod\r\n const a = v2\r\n v2 = v1\r\n v1 = a\r\n }\r\n if (v1 % v2) {\r\n console.log(\r\n 'connection rejected: steps not divisible',\r\n 'current:',\r\n v1,\r\n 'new:',\r\n v2\r\n )\r\n return\r\n }\r\n\r\n step = v1\r\n }\r\n\r\n getCustomConfig()[k] = step\r\n continue\r\n }\r\n }\r\n\r\n console.log(`connection rejected: config ${k} values dont match`, v1, v2)\r\n return\r\n }\r\n }\r\n\r\n if (customConfig || forceUpdate) {\r\n if (customConfig) {\r\n output.widget[CONFIG] = [config1[0], customConfig]\r\n }\r\n\r\n const widget = recreateWidget?.call(this)\r\n // When deleting a node this can be null\r\n if (widget) {\r\n const min = widget.options.min\r\n const max = widget.options.max\r\n if (min != null && widget.value < min) widget.value = min\r\n if (max != null && widget.value > max) widget.value = max\r\n widget.callback(widget.value)\r\n }\r\n }\r\n\r\n return { customConfig }\r\n}\r\n\r\nlet useConversionSubmenusSetting\r\napp.registerExtension({\r\n name: 'Comfy.WidgetInputs',\r\n init() {\r\n useConversionSubmenusSetting = app.ui.settings.addSetting({\r\n id: 'Comfy.NodeInputConversionSubmenus',\r\n name: 'In the node context menu, place the entries that convert between input/widget in sub-menus.',\r\n type: 'boolean',\r\n defaultValue: true\r\n })\r\n },\r\n async beforeRegisterNodeDef(nodeType, nodeData, app) {\r\n // Add menu options to convert to/from widgets\r\n const origGetExtraMenuOptions = nodeType.prototype.getExtraMenuOptions\r\n nodeType.prototype.convertWidgetToInput = function (widget) {\r\n const config = getConfig.call(this, widget.name) ?? [\r\n widget.type,\r\n widget.options || {}\r\n ]\r\n if (!isConvertibleWidget(widget, config)) return false\r\n convertToInput(this, widget, config)\r\n return true\r\n }\r\n nodeType.prototype.getExtraMenuOptions = function (_, options) {\r\n const r = origGetExtraMenuOptions\r\n ? origGetExtraMenuOptions.apply(this, arguments)\r\n : undefined\r\n\r\n if (this.widgets) {\r\n let toInput = []\r\n let toWidget = []\r\n for (const w of this.widgets) {\r\n if (w.options?.forceInput) {\r\n continue\r\n }\r\n if (w.type === CONVERTED_TYPE) {\r\n toWidget.push({\r\n content: `Convert ${w.name} to widget`,\r\n callback: () => convertToWidget(this, w)\r\n })\r\n } else {\r\n const config = getConfig.call(this, w.name) ?? [\r\n w.type,\r\n w.options || {}\r\n ]\r\n if (isConvertibleWidget(w, config)) {\r\n toInput.push({\r\n content: `Convert ${w.name} to input`,\r\n callback: () => convertToInput(this, w, config)\r\n })\r\n }\r\n }\r\n }\r\n\r\n //Convert.. main menu\r\n if (toInput.length) {\r\n if (useConversionSubmenusSetting.value) {\r\n options.push({\r\n content: 'Convert Widget to Input',\r\n submenu: {\r\n options: toInput\r\n }\r\n })\r\n } else {\r\n options.push(...toInput, null)\r\n }\r\n }\r\n if (toWidget.length) {\r\n if (useConversionSubmenusSetting.value) {\r\n options.push({\r\n content: 'Convert Input to Widget',\r\n submenu: {\r\n options: toWidget\r\n }\r\n })\r\n } else {\r\n options.push(...toWidget, null)\r\n }\r\n }\r\n }\r\n\r\n return r\r\n }\r\n\r\n nodeType.prototype.onGraphConfigured = function () {\r\n if (!this.inputs) return\r\n\r\n for (const input of this.inputs) {\r\n if (input.widget) {\r\n if (!input.widget[GET_CONFIG]) {\r\n input.widget[GET_CONFIG] = () =>\r\n getConfig.call(this, input.widget.name)\r\n }\r\n\r\n // Cleanup old widget config\r\n if (input.widget.config) {\r\n if (input.widget.config[0] instanceof Array) {\r\n // If we are an old converted combo then replace the input type and the stored link data\r\n input.type = 'COMBO'\r\n\r\n const link = app.graph.links[input.link]\r\n if (link) {\r\n link.type = input.type\r\n }\r\n }\r\n delete input.widget.config\r\n }\r\n\r\n const w = this.widgets.find((w) => w.name === input.widget.name)\r\n if (w) {\r\n hideWidget(this, w)\r\n } else {\r\n convertToWidget(this, input)\r\n }\r\n }\r\n }\r\n }\r\n\r\n const origOnNodeCreated = nodeType.prototype.onNodeCreated\r\n nodeType.prototype.onNodeCreated = function () {\r\n const r = origOnNodeCreated ? origOnNodeCreated.apply(this) : undefined\r\n\r\n // When node is created, convert any force/default inputs\r\n if (!app.configuringGraph && this.widgets) {\r\n for (const w of this.widgets) {\r\n if (w?.options?.forceInput || w?.options?.defaultInput) {\r\n const config = getConfig.call(this, w.name) ?? [\r\n w.type,\r\n w.options || {}\r\n ]\r\n convertToInput(this, w, config)\r\n }\r\n }\r\n }\r\n\r\n return r\r\n }\r\n\r\n const origOnConfigure = nodeType.prototype.onConfigure\r\n nodeType.prototype.onConfigure = function () {\r\n const r = origOnConfigure\r\n ? origOnConfigure.apply(this, arguments)\r\n : undefined\r\n if (!app.configuringGraph && this.inputs) {\r\n // On copy + paste of nodes, ensure that widget configs are set up\r\n for (const input of this.inputs) {\r\n if (input.widget && !input.widget[GET_CONFIG]) {\r\n input.widget[GET_CONFIG] = () =>\r\n getConfig.call(this, input.widget.name)\r\n const w = this.widgets.find((w) => w.name === input.widget.name)\r\n if (w) {\r\n hideWidget(this, w)\r\n }\r\n }\r\n }\r\n }\r\n\r\n return r\r\n }\r\n\r\n function isNodeAtPos(pos) {\r\n for (const n of app.graph._nodes) {\r\n if (n.pos[0] === pos[0] && n.pos[1] === pos[1]) {\r\n return true\r\n }\r\n }\r\n return false\r\n }\r\n\r\n // Double click a widget input to automatically attach a primitive\r\n const origOnInputDblClick = nodeType.prototype.onInputDblClick\r\n const ignoreDblClick = Symbol()\r\n nodeType.prototype.onInputDblClick = function (slot) {\r\n const r = origOnInputDblClick\r\n ? origOnInputDblClick.apply(this, arguments)\r\n : undefined\r\n\r\n const input = this.inputs[slot]\r\n if (!input.widget || !input[ignoreDblClick]) {\r\n // Not a widget input or already handled input\r\n if (\r\n !(input.type in ComfyWidgets) &&\r\n !(input.widget[GET_CONFIG]?.()?.[0] instanceof Array)\r\n ) {\r\n return r //also Not a ComfyWidgets input or combo (do nothing)\r\n }\r\n }\r\n\r\n // Create a primitive node\r\n const node = LiteGraph.createNode('PrimitiveNode')\r\n app.graph.add(node)\r\n\r\n // Calculate a position that wont directly overlap another node\r\n const pos: [number, number] = [\r\n this.pos[0] - node.size[0] - 30,\r\n this.pos[1]\r\n ]\r\n while (isNodeAtPos(pos)) {\r\n pos[1] += LiteGraph.NODE_TITLE_HEIGHT\r\n }\r\n\r\n node.pos = pos\r\n node.connect(0, this, slot)\r\n node.title = input.name\r\n\r\n // Prevent adding duplicates due to triple clicking\r\n input[ignoreDblClick] = true\r\n setTimeout(() => {\r\n delete input[ignoreDblClick]\r\n }, 300)\r\n\r\n return r\r\n }\r\n\r\n // Prevent connecting COMBO lists to converted inputs that dont match types\r\n const onConnectInput = nodeType.prototype.onConnectInput\r\n nodeType.prototype.onConnectInput = function (\r\n targetSlot,\r\n type,\r\n output,\r\n originNode,\r\n originSlot\r\n ) {\r\n const v = onConnectInput?.(this, arguments)\r\n // Not a combo, ignore\r\n if (type !== 'COMBO') return v\r\n // Primitive output, allow that to handle\r\n if (originNode.outputs[originSlot].widget) return v\r\n\r\n // Ensure target is also a combo\r\n const targetCombo = this.inputs[targetSlot].widget?.[GET_CONFIG]?.()?.[0]\r\n if (!targetCombo || !(targetCombo instanceof Array)) return v\r\n\r\n // Check they match\r\n const originConfig =\r\n originNode.constructor?.nodeData?.output?.[originSlot]\r\n if (!originConfig || !isValidCombo(targetCombo, originConfig)) {\r\n return false\r\n }\r\n\r\n return v\r\n }\r\n },\r\n registerCustomNodes() {\r\n LiteGraph.registerNodeType(\r\n 'PrimitiveNode',\r\n Object.assign(PrimitiveNode, {\r\n title: 'Primitive'\r\n })\r\n )\r\n PrimitiveNode.category = 'utils'\r\n }\r\n})\r\n","import { $el, ComfyDialog } from '../../scripts/ui'\r\nimport { DraggableList } from '../../scripts/ui/draggableList'\r\nimport { GroupNodeConfig, GroupNodeHandler } from './groupNode'\r\nimport './groupNodeManage.css'\r\nimport { app, type ComfyApp } from '../../scripts/app'\r\nimport {\r\n LiteGraph,\r\n type LGraphNode,\r\n type LGraphNodeConstructor\r\n} from '@comfyorg/litegraph'\r\n\r\nconst ORDER: symbol = Symbol()\r\n\r\nfunction merge(target, source) {\r\n if (typeof target === 'object' && typeof source === 'object') {\r\n for (const key in source) {\r\n const sv = source[key]\r\n if (typeof sv === 'object') {\r\n let tv = target[key]\r\n if (!tv) tv = target[key] = {}\r\n merge(tv, source[key])\r\n } else {\r\n target[key] = sv\r\n }\r\n }\r\n }\r\n\r\n return target\r\n}\r\n\r\nexport class ManageGroupDialog extends ComfyDialog {\r\n tabs: Record<\r\n 'Inputs' | 'Outputs' | 'Widgets',\r\n { tab: HTMLAnchorElement; page: HTMLElement }\r\n >\r\n selectedNodeIndex: number | null | undefined\r\n selectedTab: keyof ManageGroupDialog['tabs'] = 'Inputs'\r\n selectedGroup: string | undefined\r\n modifications: Record<\r\n string,\r\n Record<\r\n string,\r\n Record<\r\n string,\r\n { name?: string | undefined; visible?: boolean | undefined }\r\n >\r\n >\r\n > = {}\r\n nodeItems: any[]\r\n app: ComfyApp\r\n groupNodeType: LGraphNodeConstructor\r\n groupNodeDef: any\r\n groupData: any\r\n\r\n innerNodesList: HTMLUListElement\r\n widgetsPage: HTMLElement\r\n inputsPage: HTMLElement\r\n outputsPage: HTMLElement\r\n draggable: any\r\n\r\n get selectedNodeInnerIndex() {\r\n return +this.nodeItems[this.selectedNodeIndex].dataset.nodeindex\r\n }\r\n\r\n constructor(app) {\r\n super()\r\n this.app = app\r\n this.element = $el('dialog.comfy-group-manage', {\r\n parent: document.body\r\n }) as HTMLDialogElement\r\n }\r\n\r\n changeTab(tab) {\r\n this.tabs[this.selectedTab].tab.classList.remove('active')\r\n this.tabs[this.selectedTab].page.classList.remove('active')\r\n this.tabs[tab].tab.classList.add('active')\r\n this.tabs[tab].page.classList.add('active')\r\n this.selectedTab = tab\r\n }\r\n\r\n changeNode(index, force?) {\r\n if (!force && this.selectedNodeIndex === index) return\r\n\r\n if (this.selectedNodeIndex != null) {\r\n this.nodeItems[this.selectedNodeIndex].classList.remove('selected')\r\n }\r\n this.nodeItems[index].classList.add('selected')\r\n this.selectedNodeIndex = index\r\n\r\n if (!this.buildInputsPage() && this.selectedTab === 'Inputs') {\r\n this.changeTab('Widgets')\r\n }\r\n if (!this.buildWidgetsPage() && this.selectedTab === 'Widgets') {\r\n this.changeTab('Outputs')\r\n }\r\n if (!this.buildOutputsPage() && this.selectedTab === 'Outputs') {\r\n this.changeTab('Inputs')\r\n }\r\n\r\n this.changeTab(this.selectedTab)\r\n }\r\n\r\n getGroupData() {\r\n this.groupNodeType =\r\n LiteGraph.registered_node_types['workflow/' + this.selectedGroup]\r\n this.groupNodeDef = this.groupNodeType.nodeData\r\n this.groupData = GroupNodeHandler.getGroupData(this.groupNodeType)\r\n }\r\n\r\n changeGroup(group, reset = true) {\r\n this.selectedGroup = group\r\n this.getGroupData()\r\n\r\n const nodes = this.groupData.nodeData.nodes\r\n this.nodeItems = nodes.map((n, i) =>\r\n $el(\r\n 'li.draggable-item',\r\n {\r\n dataset: {\r\n nodeindex: n.index + ''\r\n },\r\n onclick: () => {\r\n this.changeNode(i)\r\n }\r\n },\r\n [\r\n $el('span.drag-handle'),\r\n $el(\r\n 'div',\r\n {\r\n textContent: n.title ?? n.type\r\n },\r\n n.title\r\n ? $el('span', {\r\n textContent: n.type\r\n })\r\n : []\r\n )\r\n ]\r\n )\r\n )\r\n\r\n this.innerNodesList.replaceChildren(...this.nodeItems)\r\n\r\n if (reset) {\r\n this.selectedNodeIndex = null\r\n this.changeNode(0)\r\n } else {\r\n const items = this.draggable.getAllItems()\r\n let index = items.findIndex((item) => item.classList.contains('selected'))\r\n if (index === -1) index = this.selectedNodeIndex\r\n this.changeNode(index, true)\r\n }\r\n\r\n const ordered = [...nodes]\r\n this.draggable?.dispose()\r\n this.draggable = new DraggableList(this.innerNodesList, 'li')\r\n this.draggable.addEventListener(\r\n 'dragend',\r\n ({ detail: { oldPosition, newPosition } }) => {\r\n if (oldPosition === newPosition) return\r\n ordered.splice(newPosition, 0, ordered.splice(oldPosition, 1)[0])\r\n for (let i = 0; i < ordered.length; i++) {\r\n this.storeModification({\r\n nodeIndex: ordered[i].index,\r\n section: ORDER,\r\n prop: 'order',\r\n value: i\r\n })\r\n }\r\n }\r\n )\r\n }\r\n\r\n storeModification(props: {\r\n nodeIndex?: number\r\n section: symbol\r\n prop: string\r\n value: any\r\n }) {\r\n const { nodeIndex, section, prop, value } = props\r\n const groupMod = (this.modifications[this.selectedGroup] ??= {})\r\n const nodesMod = (groupMod.nodes ??= {})\r\n const nodeMod = (nodesMod[nodeIndex ?? this.selectedNodeInnerIndex] ??= {})\r\n const typeMod = (nodeMod[section] ??= {})\r\n if (typeof value === 'object') {\r\n const objMod = (typeMod[prop] ??= {})\r\n Object.assign(objMod, value)\r\n } else {\r\n typeMod[prop] = value\r\n }\r\n }\r\n\r\n getEditElement(section, prop, value, placeholder, checked, checkable = true) {\r\n if (value === placeholder) value = ''\r\n\r\n const mods =\r\n this.modifications[this.selectedGroup]?.nodes?.[\r\n this.selectedNodeInnerIndex\r\n ]?.[section]?.[prop]\r\n if (mods) {\r\n if (mods.name != null) {\r\n value = mods.name\r\n }\r\n if (mods.visible != null) {\r\n checked = mods.visible\r\n }\r\n }\r\n\r\n return $el('div', [\r\n $el('input', {\r\n value,\r\n placeholder,\r\n type: 'text',\r\n onchange: (e) => {\r\n this.storeModification({\r\n section,\r\n prop,\r\n value: { name: e.target.value }\r\n })\r\n }\r\n }),\r\n $el('label', { textContent: 'Visible' }, [\r\n $el('input', {\r\n type: 'checkbox',\r\n checked,\r\n disabled: !checkable,\r\n onchange: (e) => {\r\n this.storeModification({\r\n section,\r\n prop,\r\n value: { visible: !!e.target.checked }\r\n })\r\n }\r\n })\r\n ])\r\n ])\r\n }\r\n\r\n buildWidgetsPage() {\r\n const widgets =\r\n this.groupData.oldToNewWidgetMap[this.selectedNodeInnerIndex]\r\n const items = Object.keys(widgets ?? {})\r\n const type = app.graph.extra.groupNodes[this.selectedGroup]\r\n const config = type.config?.[this.selectedNodeInnerIndex]?.input\r\n this.widgetsPage.replaceChildren(\r\n ...items.map((oldName) => {\r\n return this.getEditElement(\r\n 'input',\r\n oldName,\r\n widgets[oldName],\r\n oldName,\r\n config?.[oldName]?.visible !== false\r\n )\r\n })\r\n )\r\n return !!items.length\r\n }\r\n\r\n buildInputsPage() {\r\n const inputs = this.groupData.nodeInputs[this.selectedNodeInnerIndex]\r\n const items = Object.keys(inputs ?? {})\r\n const type = app.graph.extra.groupNodes[this.selectedGroup]\r\n const config = type.config?.[this.selectedNodeInnerIndex]?.input\r\n this.inputsPage.replaceChildren(\r\n ...items\r\n .map((oldName) => {\r\n let value = inputs[oldName]\r\n if (!value) {\r\n return\r\n }\r\n\r\n return this.getEditElement(\r\n 'input',\r\n oldName,\r\n value,\r\n oldName,\r\n config?.[oldName]?.visible !== false\r\n )\r\n })\r\n .filter(Boolean)\r\n )\r\n return !!items.length\r\n }\r\n\r\n buildOutputsPage() {\r\n const nodes = this.groupData.nodeData.nodes\r\n const innerNodeDef = this.groupData.getNodeDef(\r\n nodes[this.selectedNodeInnerIndex]\r\n )\r\n const outputs = innerNodeDef?.output ?? []\r\n const groupOutputs =\r\n this.groupData.oldToNewOutputMap[this.selectedNodeInnerIndex]\r\n\r\n const type = app.graph.extra.groupNodes[this.selectedGroup]\r\n const config = type.config?.[this.selectedNodeInnerIndex]?.output\r\n const node = this.groupData.nodeData.nodes[this.selectedNodeInnerIndex]\r\n const checkable = node.type !== 'PrimitiveNode'\r\n this.outputsPage.replaceChildren(\r\n ...outputs\r\n .map((type, slot) => {\r\n const groupOutputIndex = groupOutputs?.[slot]\r\n const oldName = innerNodeDef.output_name?.[slot] ?? type\r\n let value = config?.[slot]?.name\r\n const visible = config?.[slot]?.visible || groupOutputIndex != null\r\n if (!value || value === oldName) {\r\n value = ''\r\n }\r\n return this.getEditElement(\r\n 'output',\r\n slot,\r\n value,\r\n oldName,\r\n visible,\r\n checkable\r\n )\r\n })\r\n .filter(Boolean)\r\n )\r\n return !!outputs.length\r\n }\r\n\r\n show(type?) {\r\n const groupNodes = Object.keys(app.graph.extra?.groupNodes ?? {}).sort(\r\n (a, b) => a.localeCompare(b)\r\n )\r\n\r\n this.innerNodesList = $el(\r\n 'ul.comfy-group-manage-list-items'\r\n ) as HTMLUListElement\r\n this.widgetsPage = $el('section.comfy-group-manage-node-page')\r\n this.inputsPage = $el('section.comfy-group-manage-node-page')\r\n this.outputsPage = $el('section.comfy-group-manage-node-page')\r\n const pages = $el('div', [\r\n this.widgetsPage,\r\n this.inputsPage,\r\n this.outputsPage\r\n ])\r\n\r\n this.tabs = [\r\n ['Inputs', this.inputsPage],\r\n ['Widgets', this.widgetsPage],\r\n ['Outputs', this.outputsPage]\r\n ].reduce((p, [name, page]: [string, HTMLElement]) => {\r\n p[name] = {\r\n tab: $el('a', {\r\n onclick: () => {\r\n this.changeTab(name)\r\n },\r\n textContent: name\r\n }),\r\n page\r\n }\r\n return p\r\n }, {}) as any\r\n\r\n const outer = $el('div.comfy-group-manage-outer', [\r\n $el('header', [\r\n $el('h2', 'Group Nodes'),\r\n $el(\r\n 'select',\r\n {\r\n onchange: (e) => {\r\n this.changeGroup(e.target.value)\r\n }\r\n },\r\n groupNodes.map((g) =>\r\n $el('option', {\r\n textContent: g,\r\n selected: 'workflow/' + g === type,\r\n value: g\r\n })\r\n )\r\n )\r\n ]),\r\n $el('main', [\r\n $el('section.comfy-group-manage-list', this.innerNodesList),\r\n $el('section.comfy-group-manage-node', [\r\n $el(\r\n 'header',\r\n Object.values(this.tabs).map((t) => t.tab)\r\n ),\r\n pages\r\n ])\r\n ]),\r\n $el('footer', [\r\n $el(\r\n 'button.comfy-btn',\r\n {\r\n onclick: (e) => {\r\n // @ts-expect-error\r\n const node = app.graph._nodes.find(\r\n (n) => n.type === 'workflow/' + this.selectedGroup\r\n )\r\n if (node) {\r\n alert(\r\n 'This group node is in use in the current workflow, please first remove these.'\r\n )\r\n return\r\n }\r\n if (\r\n confirm(\r\n `Are you sure you want to remove the node: \"${this.selectedGroup}\"`\r\n )\r\n ) {\r\n delete app.graph.extra.groupNodes[this.selectedGroup]\r\n LiteGraph.unregisterNodeType('workflow/' + this.selectedGroup)\r\n }\r\n this.show()\r\n }\r\n },\r\n 'Delete Group Node'\r\n ),\r\n $el(\r\n 'button.comfy-btn',\r\n {\r\n onclick: async () => {\r\n let nodesByType\r\n let recreateNodes = []\r\n const types = {}\r\n for (const g in this.modifications) {\r\n const type = app.graph.extra.groupNodes[g]\r\n let config = (type.config ??= {})\r\n\r\n let nodeMods = this.modifications[g]?.nodes\r\n if (nodeMods) {\r\n const keys = Object.keys(nodeMods)\r\n if (nodeMods[keys[0]][ORDER]) {\r\n // If any node is reordered, they will all need sequencing\r\n const orderedNodes = []\r\n const orderedMods = {}\r\n const orderedConfig = {}\r\n\r\n for (const n of keys) {\r\n const order = nodeMods[n][ORDER].order\r\n orderedNodes[order] = type.nodes[+n]\r\n orderedMods[order] = nodeMods[n]\r\n orderedNodes[order].index = order\r\n }\r\n\r\n // Rewrite links\r\n for (const l of type.links) {\r\n if (l[0] != null) l[0] = type.nodes[l[0]].index\r\n if (l[2] != null) l[2] = type.nodes[l[2]].index\r\n }\r\n\r\n // Rewrite externals\r\n if (type.external) {\r\n for (const ext of type.external) {\r\n ext[0] = type.nodes[ext[0]]\r\n }\r\n }\r\n\r\n // Rewrite modifications\r\n for (const id of keys) {\r\n if (config[id]) {\r\n orderedConfig[type.nodes[id].index] = config[id]\r\n }\r\n delete config[id]\r\n }\r\n\r\n type.nodes = orderedNodes\r\n nodeMods = orderedMods\r\n type.config = config = orderedConfig\r\n }\r\n\r\n merge(config, nodeMods)\r\n }\r\n\r\n types[g] = type\r\n\r\n if (!nodesByType) {\r\n // @ts-expect-error\r\n nodesByType = app.graph._nodes.reduce((p, n) => {\r\n p[n.type] ??= []\r\n p[n.type].push(n)\r\n return p\r\n }, {})\r\n }\r\n\r\n const nodes = nodesByType['workflow/' + g]\r\n if (nodes) recreateNodes.push(...nodes)\r\n }\r\n\r\n await GroupNodeConfig.registerFromWorkflow(types, {})\r\n\r\n for (const node of recreateNodes) {\r\n node.recreate()\r\n }\r\n\r\n this.modifications = {}\r\n this.app.graph.setDirtyCanvas(true, true)\r\n this.changeGroup(this.selectedGroup, false)\r\n }\r\n },\r\n 'Save'\r\n ),\r\n $el(\r\n 'button.comfy-btn',\r\n { onclick: () => this.element.close() },\r\n 'Close'\r\n )\r\n ])\r\n ])\r\n\r\n this.element.replaceChildren(outer)\r\n this.changeGroup(\r\n type ? groupNodes.find((g) => 'workflow/' + g === type) : groupNodes[0]\r\n )\r\n this.element.showModal()\r\n\r\n this.element.addEventListener('close', () => {\r\n this.draggable?.dispose()\r\n })\r\n }\r\n}\r\n","import { app } from '../../scripts/app'\r\nimport { api } from '../../scripts/api'\r\nimport { mergeIfValid } from './widgetInputs'\r\nimport { ManageGroupDialog } from './groupNodeManage'\r\nimport type { LGraphNode } from '@comfyorg/litegraph'\r\nimport { LGraphCanvas, LiteGraph } from '@comfyorg/litegraph'\r\n\r\nconst GROUP = Symbol()\r\n\r\nconst Workflow = {\r\n InUse: {\r\n Free: 0,\r\n Registered: 1,\r\n InWorkflow: 2\r\n },\r\n isInUseGroupNode(name) {\r\n const id = `workflow/${name}`\r\n // Check if lready registered/in use in this workflow\r\n if (app.graph.extra?.groupNodes?.[name]) {\r\n // @ts-expect-error\r\n if (app.graph._nodes.find((n) => n.type === id)) {\r\n return Workflow.InUse.InWorkflow\r\n } else {\r\n return Workflow.InUse.Registered\r\n }\r\n }\r\n return Workflow.InUse.Free\r\n },\r\n storeGroupNode(name, data) {\r\n let extra = app.graph.extra\r\n if (!extra) app.graph.extra = extra = {}\r\n let groupNodes = extra.groupNodes\r\n if (!groupNodes) extra.groupNodes = groupNodes = {}\r\n groupNodes[name] = data\r\n }\r\n}\r\n\r\nclass GroupNodeBuilder {\r\n nodes: LGraphNode[]\r\n nodeData: any\r\n\r\n constructor(nodes) {\r\n this.nodes = nodes\r\n }\r\n\r\n build() {\r\n const name = this.getName()\r\n if (!name) return\r\n\r\n // Sort the nodes so they are in execution order\r\n // this allows for widgets to be in the correct order when reconstructing\r\n this.sortNodes()\r\n\r\n this.nodeData = this.getNodeData()\r\n Workflow.storeGroupNode(name, this.nodeData)\r\n\r\n return { name, nodeData: this.nodeData }\r\n }\r\n\r\n getName() {\r\n const name = prompt('Enter group name')\r\n if (!name) return\r\n const used = Workflow.isInUseGroupNode(name)\r\n switch (used) {\r\n case Workflow.InUse.InWorkflow:\r\n alert(\r\n 'An in use group node with this name already exists embedded in this workflow, please remove any instances or use a new name.'\r\n )\r\n return\r\n case Workflow.InUse.Registered:\r\n if (\r\n !confirm(\r\n 'A group node with this name already exists embedded in this workflow, are you sure you want to overwrite it?'\r\n )\r\n ) {\r\n return\r\n }\r\n break\r\n }\r\n return name\r\n }\r\n\r\n sortNodes() {\r\n // Gets the builders nodes in graph execution order\r\n const nodesInOrder = app.graph.computeExecutionOrder(false)\r\n this.nodes = this.nodes\r\n .map((node) => ({ index: nodesInOrder.indexOf(node), node }))\r\n .sort((a, b) => a.index - b.index || a.node.id - b.node.id)\r\n .map(({ node }) => node)\r\n }\r\n\r\n getNodeData() {\r\n const storeLinkTypes = (config) => {\r\n // Store link types for dynamically typed nodes e.g. reroutes\r\n for (const link of config.links) {\r\n const origin = app.graph.getNodeById(link[4])\r\n const type = origin.outputs[link[1]].type\r\n link.push(type)\r\n }\r\n }\r\n\r\n const storeExternalLinks = (config) => {\r\n // Store any external links to the group in the config so when rebuilding we add extra slots\r\n config.external = []\r\n for (let i = 0; i < this.nodes.length; i++) {\r\n const node = this.nodes[i]\r\n if (!node.outputs?.length) continue\r\n for (let slot = 0; slot < node.outputs.length; slot++) {\r\n let hasExternal = false\r\n const output = node.outputs[slot]\r\n let type = output.type\r\n if (!output.links?.length) continue\r\n for (const l of output.links) {\r\n const link = app.graph.links[l]\r\n if (!link) continue\r\n if (type === '*') type = link.type\r\n\r\n if (!app.canvas.selected_nodes[link.target_id]) {\r\n hasExternal = true\r\n break\r\n }\r\n }\r\n if (hasExternal) {\r\n config.external.push([i, slot, type])\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Use the built in copyToClipboard function to generate the node data we need\r\n const backup = localStorage.getItem('litegrapheditor_clipboard')\r\n try {\r\n // @ts-expect-error\r\n // TODO Figure out if copyToClipboard is really taking this param\r\n app.canvas.copyToClipboard(this.nodes)\r\n const config = JSON.parse(\r\n localStorage.getItem('litegrapheditor_clipboard')\r\n )\r\n\r\n storeLinkTypes(config)\r\n storeExternalLinks(config)\r\n\r\n return config\r\n } finally {\r\n localStorage.setItem('litegrapheditor_clipboard', backup)\r\n }\r\n }\r\n}\r\n\r\nexport class GroupNodeConfig {\r\n name: string\r\n nodeData: any\r\n inputCount: number\r\n oldToNewOutputMap: {}\r\n newToOldOutputMap: {}\r\n oldToNewInputMap: {}\r\n oldToNewWidgetMap: {}\r\n newToOldWidgetMap: {}\r\n primitiveDefs: {}\r\n widgetToPrimitive: {}\r\n primitiveToWidget: {}\r\n nodeInputs: {}\r\n outputVisibility: any[]\r\n nodeDef: any\r\n inputs: any[]\r\n linksFrom: {}\r\n linksTo: {}\r\n externalFrom: {}\r\n\r\n constructor(name, nodeData) {\r\n this.name = name\r\n this.nodeData = nodeData\r\n this.getLinks()\r\n\r\n this.inputCount = 0\r\n this.oldToNewOutputMap = {}\r\n this.newToOldOutputMap = {}\r\n this.oldToNewInputMap = {}\r\n this.oldToNewWidgetMap = {}\r\n this.newToOldWidgetMap = {}\r\n this.primitiveDefs = {}\r\n this.widgetToPrimitive = {}\r\n this.primitiveToWidget = {}\r\n this.nodeInputs = {}\r\n this.outputVisibility = []\r\n }\r\n\r\n async registerType(source = 'workflow') {\r\n this.nodeDef = {\r\n output: [],\r\n output_name: [],\r\n output_is_list: [],\r\n output_is_hidden: [],\r\n name: source + '/' + this.name,\r\n display_name: this.name,\r\n category: 'group nodes' + ('/' + source),\r\n input: { required: {} },\r\n\r\n [GROUP]: this\r\n }\r\n\r\n this.inputs = []\r\n const seenInputs = {}\r\n const seenOutputs = {}\r\n for (let i = 0; i < this.nodeData.nodes.length; i++) {\r\n const node = this.nodeData.nodes[i]\r\n node.index = i\r\n this.processNode(node, seenInputs, seenOutputs)\r\n }\r\n\r\n for (const p of this.#convertedToProcess) {\r\n p()\r\n }\r\n this.#convertedToProcess = null\r\n await app.registerNodeDef('workflow/' + this.name, this.nodeDef)\r\n }\r\n\r\n getLinks() {\r\n this.linksFrom = {}\r\n this.linksTo = {}\r\n this.externalFrom = {}\r\n\r\n // Extract links for easy lookup\r\n for (const l of this.nodeData.links) {\r\n const [sourceNodeId, sourceNodeSlot, targetNodeId, targetNodeSlot] = l\r\n\r\n // Skip links outside the copy config\r\n if (sourceNodeId == null) continue\r\n\r\n if (!this.linksFrom[sourceNodeId]) {\r\n this.linksFrom[sourceNodeId] = {}\r\n }\r\n if (!this.linksFrom[sourceNodeId][sourceNodeSlot]) {\r\n this.linksFrom[sourceNodeId][sourceNodeSlot] = []\r\n }\r\n this.linksFrom[sourceNodeId][sourceNodeSlot].push(l)\r\n\r\n if (!this.linksTo[targetNodeId]) {\r\n this.linksTo[targetNodeId] = {}\r\n }\r\n this.linksTo[targetNodeId][targetNodeSlot] = l\r\n }\r\n\r\n if (this.nodeData.external) {\r\n for (const ext of this.nodeData.external) {\r\n if (!this.externalFrom[ext[0]]) {\r\n this.externalFrom[ext[0]] = { [ext[1]]: ext[2] }\r\n } else {\r\n this.externalFrom[ext[0]][ext[1]] = ext[2]\r\n }\r\n }\r\n }\r\n }\r\n\r\n processNode(node, seenInputs, seenOutputs) {\r\n const def = this.getNodeDef(node)\r\n if (!def) return\r\n\r\n const inputs = { ...def.input?.required, ...def.input?.optional }\r\n\r\n this.inputs.push(this.processNodeInputs(node, seenInputs, inputs))\r\n if (def.output?.length) this.processNodeOutputs(node, seenOutputs, def)\r\n }\r\n\r\n getNodeDef(node) {\r\n const def = globalDefs[node.type]\r\n if (def) return def\r\n\r\n const linksFrom = this.linksFrom[node.index]\r\n if (node.type === 'PrimitiveNode') {\r\n // Skip as its not linked\r\n if (!linksFrom) return\r\n\r\n let type = linksFrom['0'][0][5]\r\n if (type === 'COMBO') {\r\n // Use the array items\r\n const source = node.outputs[0].widget.name\r\n const fromTypeName = this.nodeData.nodes[linksFrom['0'][0][2]].type\r\n const fromType = globalDefs[fromTypeName]\r\n const input =\r\n fromType.input.required[source] ?? fromType.input.optional[source]\r\n type = input[0]\r\n }\r\n\r\n const def = (this.primitiveDefs[node.index] = {\r\n input: {\r\n required: {\r\n value: [type, {}]\r\n }\r\n },\r\n output: [type],\r\n output_name: [],\r\n output_is_list: []\r\n })\r\n return def\r\n } else if (node.type === 'Reroute') {\r\n const linksTo = this.linksTo[node.index]\r\n if (linksTo && linksFrom && !this.externalFrom[node.index]?.[0]) {\r\n // Being used internally\r\n return null\r\n }\r\n\r\n let config = {}\r\n let rerouteType = '*'\r\n if (linksFrom) {\r\n for (const [, , id, slot] of linksFrom['0']) {\r\n const node = this.nodeData.nodes[id]\r\n const input = node.inputs[slot]\r\n if (rerouteType === '*') {\r\n rerouteType = input.type\r\n }\r\n if (input.widget) {\r\n const targetDef = globalDefs[node.type]\r\n const targetWidget =\r\n targetDef.input.required[input.widget.name] ??\r\n targetDef.input.optional[input.widget.name]\r\n\r\n const widget = [targetWidget[0], config]\r\n const res = mergeIfValid(\r\n {\r\n widget\r\n },\r\n targetWidget,\r\n false,\r\n null,\r\n widget\r\n )\r\n config = res?.customConfig ?? config\r\n }\r\n }\r\n } else if (linksTo) {\r\n const [id, slot] = linksTo['0']\r\n rerouteType = this.nodeData.nodes[id].outputs[slot].type\r\n } else {\r\n // Reroute used as a pipe\r\n for (const l of this.nodeData.links) {\r\n if (l[2] === node.index) {\r\n rerouteType = l[5]\r\n break\r\n }\r\n }\r\n if (rerouteType === '*') {\r\n // Check for an external link\r\n const t = this.externalFrom[node.index]?.[0]\r\n if (t) {\r\n rerouteType = t\r\n }\r\n }\r\n }\r\n\r\n // @ts-expect-error\r\n config.forceInput = true\r\n return {\r\n input: {\r\n required: {\r\n [rerouteType]: [rerouteType, config]\r\n }\r\n },\r\n output: [rerouteType],\r\n output_name: [],\r\n output_is_list: []\r\n }\r\n }\r\n\r\n console.warn(\r\n 'Skipping virtual node ' +\r\n node.type +\r\n ' when building group node ' +\r\n this.name\r\n )\r\n }\r\n\r\n getInputConfig(node, inputName, seenInputs, config, extra?) {\r\n const customConfig = this.nodeData.config?.[node.index]?.input?.[inputName]\r\n let name =\r\n customConfig?.name ??\r\n node.inputs?.find((inp) => inp.name === inputName)?.label ??\r\n inputName\r\n let key = name\r\n let prefix = ''\r\n // Special handling for primitive to include the title if it is set rather than just \"value\"\r\n if ((node.type === 'PrimitiveNode' && node.title) || name in seenInputs) {\r\n prefix = `${node.title ?? node.type} `\r\n key = name = `${prefix}${inputName}`\r\n if (name in seenInputs) {\r\n name = `${prefix}${seenInputs[name]} ${inputName}`\r\n }\r\n }\r\n seenInputs[key] = (seenInputs[key] ?? 1) + 1\r\n\r\n if (inputName === 'seed' || inputName === 'noise_seed') {\r\n if (!extra) extra = {}\r\n extra.control_after_generate = `${prefix}control_after_generate`\r\n }\r\n if (config[0] === 'IMAGEUPLOAD') {\r\n if (!extra) extra = {}\r\n extra.widget =\r\n this.oldToNewWidgetMap[node.index]?.[config[1]?.widget ?? 'image'] ??\r\n 'image'\r\n }\r\n\r\n if (extra) {\r\n config = [config[0], { ...config[1], ...extra }]\r\n }\r\n\r\n return { name, config, customConfig }\r\n }\r\n\r\n processWidgetInputs(inputs, node, inputNames, seenInputs) {\r\n const slots = []\r\n const converted = new Map()\r\n const widgetMap = (this.oldToNewWidgetMap[node.index] = {})\r\n for (const inputName of inputNames) {\r\n let widgetType = app.getWidgetType(inputs[inputName], inputName)\r\n if (widgetType) {\r\n const convertedIndex = node.inputs?.findIndex(\r\n (inp) => inp.name === inputName && inp.widget?.name === inputName\r\n )\r\n if (convertedIndex > -1) {\r\n // This widget has been converted to a widget\r\n // We need to store this in the correct position so link ids line up\r\n converted.set(convertedIndex, inputName)\r\n widgetMap[inputName] = null\r\n } else {\r\n // Normal widget\r\n const { name, config } = this.getInputConfig(\r\n node,\r\n inputName,\r\n seenInputs,\r\n inputs[inputName]\r\n )\r\n this.nodeDef.input.required[name] = config\r\n widgetMap[inputName] = name\r\n this.newToOldWidgetMap[name] = { node, inputName }\r\n }\r\n } else {\r\n // Normal input\r\n slots.push(inputName)\r\n }\r\n }\r\n return { converted, slots }\r\n }\r\n\r\n checkPrimitiveConnection(link, inputName, inputs) {\r\n const sourceNode = this.nodeData.nodes[link[0]]\r\n if (sourceNode.type === 'PrimitiveNode') {\r\n // Merge link configurations\r\n const [sourceNodeId, _, targetNodeId, __] = link\r\n const primitiveDef = this.primitiveDefs[sourceNodeId]\r\n const targetWidget = inputs[inputName]\r\n const primitiveConfig = primitiveDef.input.required.value\r\n const output = { widget: primitiveConfig }\r\n const config = mergeIfValid(\r\n output,\r\n targetWidget,\r\n false,\r\n null,\r\n primitiveConfig\r\n )\r\n primitiveConfig[1] =\r\n config?.customConfig ?? inputs[inputName][1]\r\n ? { ...inputs[inputName][1] }\r\n : {}\r\n\r\n let name = this.oldToNewWidgetMap[sourceNodeId]['value']\r\n name = name.substr(0, name.length - 6)\r\n primitiveConfig[1].control_after_generate = true\r\n primitiveConfig[1].control_prefix = name\r\n\r\n let toPrimitive = this.widgetToPrimitive[targetNodeId]\r\n if (!toPrimitive) {\r\n toPrimitive = this.widgetToPrimitive[targetNodeId] = {}\r\n }\r\n if (toPrimitive[inputName]) {\r\n toPrimitive[inputName].push(sourceNodeId)\r\n }\r\n toPrimitive[inputName] = sourceNodeId\r\n\r\n let toWidget = this.primitiveToWidget[sourceNodeId]\r\n if (!toWidget) {\r\n toWidget = this.primitiveToWidget[sourceNodeId] = []\r\n }\r\n toWidget.push({ nodeId: targetNodeId, inputName })\r\n }\r\n }\r\n\r\n processInputSlots(inputs, node, slots, linksTo, inputMap, seenInputs) {\r\n this.nodeInputs[node.index] = {}\r\n for (let i = 0; i < slots.length; i++) {\r\n const inputName = slots[i]\r\n if (linksTo[i]) {\r\n this.checkPrimitiveConnection(linksTo[i], inputName, inputs)\r\n // This input is linked so we can skip it\r\n continue\r\n }\r\n\r\n const { name, config, customConfig } = this.getInputConfig(\r\n node,\r\n inputName,\r\n seenInputs,\r\n inputs[inputName]\r\n )\r\n\r\n this.nodeInputs[node.index][inputName] = name\r\n if (customConfig?.visible === false) continue\r\n\r\n this.nodeDef.input.required[name] = config\r\n inputMap[i] = this.inputCount++\r\n }\r\n }\r\n\r\n processConvertedWidgets(\r\n inputs,\r\n node,\r\n slots,\r\n converted,\r\n linksTo,\r\n inputMap,\r\n seenInputs\r\n ) {\r\n // Add converted widgets sorted into their index order (ordered as they were converted) so link ids match up\r\n const convertedSlots = [...converted.keys()]\r\n .sort()\r\n .map((k) => converted.get(k))\r\n for (let i = 0; i < convertedSlots.length; i++) {\r\n const inputName = convertedSlots[i]\r\n if (linksTo[slots.length + i]) {\r\n this.checkPrimitiveConnection(\r\n linksTo[slots.length + i],\r\n inputName,\r\n inputs\r\n )\r\n // This input is linked so we can skip it\r\n continue\r\n }\r\n\r\n const { name, config } = this.getInputConfig(\r\n node,\r\n inputName,\r\n seenInputs,\r\n inputs[inputName],\r\n {\r\n defaultInput: true\r\n }\r\n )\r\n\r\n this.nodeDef.input.required[name] = config\r\n this.newToOldWidgetMap[name] = { node, inputName }\r\n\r\n if (!this.oldToNewWidgetMap[node.index]) {\r\n this.oldToNewWidgetMap[node.index] = {}\r\n }\r\n this.oldToNewWidgetMap[node.index][inputName] = name\r\n\r\n inputMap[slots.length + i] = this.inputCount++\r\n }\r\n }\r\n\r\n #convertedToProcess = []\r\n processNodeInputs(node, seenInputs, inputs) {\r\n const inputMapping = []\r\n\r\n const inputNames = Object.keys(inputs)\r\n if (!inputNames.length) return\r\n\r\n const { converted, slots } = this.processWidgetInputs(\r\n inputs,\r\n node,\r\n inputNames,\r\n seenInputs\r\n )\r\n const linksTo = this.linksTo[node.index] ?? {}\r\n const inputMap = (this.oldToNewInputMap[node.index] = {})\r\n this.processInputSlots(inputs, node, slots, linksTo, inputMap, seenInputs)\r\n\r\n // Converted inputs have to be processed after all other nodes as they'll be at the end of the list\r\n this.#convertedToProcess.push(() =>\r\n this.processConvertedWidgets(\r\n inputs,\r\n node,\r\n slots,\r\n converted,\r\n linksTo,\r\n inputMap,\r\n seenInputs\r\n )\r\n )\r\n\r\n return inputMapping\r\n }\r\n\r\n processNodeOutputs(node, seenOutputs, def) {\r\n const oldToNew = (this.oldToNewOutputMap[node.index] = {})\r\n\r\n // Add outputs\r\n for (let outputId = 0; outputId < def.output.length; outputId++) {\r\n const linksFrom = this.linksFrom[node.index]\r\n // If this output is linked internally we flag it to hide\r\n const hasLink =\r\n linksFrom?.[outputId] && !this.externalFrom[node.index]?.[outputId]\r\n const customConfig =\r\n this.nodeData.config?.[node.index]?.output?.[outputId]\r\n const visible = customConfig?.visible ?? !hasLink\r\n this.outputVisibility.push(visible)\r\n if (!visible) {\r\n continue\r\n }\r\n\r\n oldToNew[outputId] = this.nodeDef.output.length\r\n this.newToOldOutputMap[this.nodeDef.output.length] = {\r\n node,\r\n slot: outputId\r\n }\r\n this.nodeDef.output.push(def.output[outputId])\r\n this.nodeDef.output_is_list.push(def.output_is_list[outputId])\r\n\r\n let label = customConfig?.name\r\n if (!label) {\r\n label = def.output_name?.[outputId] ?? def.output[outputId]\r\n const output = node.outputs.find((o) => o.name === label)\r\n if (output?.label) {\r\n label = output.label\r\n }\r\n }\r\n\r\n let name = label\r\n if (name in seenOutputs) {\r\n const prefix = `${node.title ?? node.type} `\r\n name = `${prefix}${label}`\r\n if (name in seenOutputs) {\r\n name = `${prefix}${node.index} ${label}`\r\n }\r\n }\r\n seenOutputs[name] = 1\r\n\r\n this.nodeDef.output_name.push(name)\r\n }\r\n }\r\n\r\n static async registerFromWorkflow(groupNodes, missingNodeTypes) {\r\n const clean = app.clean\r\n app.clean = function () {\r\n for (const g in groupNodes) {\r\n try {\r\n LiteGraph.unregisterNodeType('workflow/' + g)\r\n } catch (error) {}\r\n }\r\n app.clean = clean\r\n }\r\n\r\n for (const g in groupNodes) {\r\n const groupData = groupNodes[g]\r\n\r\n let hasMissing = false\r\n for (const n of groupData.nodes) {\r\n // Find missing node types\r\n if (!(n.type in LiteGraph.registered_node_types)) {\r\n missingNodeTypes.push({\r\n type: n.type,\r\n hint: ` (In group node 'workflow/${g}')`\r\n })\r\n\r\n missingNodeTypes.push({\r\n type: 'workflow/' + g,\r\n action: {\r\n text: 'Remove from workflow',\r\n callback: (e) => {\r\n delete groupNodes[g]\r\n e.target.textContent = 'Removed'\r\n e.target.style.pointerEvents = 'none'\r\n e.target.style.opacity = 0.7\r\n }\r\n }\r\n })\r\n\r\n hasMissing = true\r\n }\r\n }\r\n\r\n if (hasMissing) continue\r\n\r\n const config = new GroupNodeConfig(g, groupData)\r\n await config.registerType()\r\n }\r\n }\r\n}\r\n\r\nexport class GroupNodeHandler {\r\n node\r\n groupData\r\n innerNodes: any\r\n\r\n constructor(node) {\r\n this.node = node\r\n this.groupData = node.constructor?.nodeData?.[GROUP]\r\n\r\n this.node.setInnerNodes = (innerNodes) => {\r\n this.innerNodes = innerNodes\r\n\r\n for (\r\n let innerNodeIndex = 0;\r\n innerNodeIndex < this.innerNodes.length;\r\n innerNodeIndex++\r\n ) {\r\n const innerNode = this.innerNodes[innerNodeIndex]\r\n\r\n for (const w of innerNode.widgets ?? []) {\r\n if (w.type === 'converted-widget') {\r\n w.serializeValue = w.origSerializeValue\r\n }\r\n }\r\n\r\n innerNode.index = innerNodeIndex\r\n innerNode.getInputNode = (slot) => {\r\n // Check if this input is internal or external\r\n const externalSlot =\r\n this.groupData.oldToNewInputMap[innerNode.index]?.[slot]\r\n if (externalSlot != null) {\r\n return this.node.getInputNode(externalSlot)\r\n }\r\n\r\n // Internal link\r\n const innerLink = this.groupData.linksTo[innerNode.index]?.[slot]\r\n if (!innerLink) return null\r\n\r\n const inputNode = innerNodes[innerLink[0]]\r\n // Primitives will already apply their values\r\n if (inputNode.type === 'PrimitiveNode') return null\r\n\r\n return inputNode\r\n }\r\n\r\n innerNode.getInputLink = (slot) => {\r\n const externalSlot =\r\n this.groupData.oldToNewInputMap[innerNode.index]?.[slot]\r\n if (externalSlot != null) {\r\n // The inner node is connected via the group node inputs\r\n const linkId = this.node.inputs[externalSlot].link\r\n let link = app.graph.links[linkId]\r\n\r\n // Use the outer link, but update the target to the inner node\r\n // @ts-expect-error\r\n // TODO: Fix this\r\n link = {\r\n ...link,\r\n target_id: innerNode.id,\r\n target_slot: +slot\r\n }\r\n return link\r\n }\r\n\r\n let link = this.groupData.linksTo[innerNode.index]?.[slot]\r\n if (!link) return null\r\n // Use the inner link, but update the origin node to be inner node id\r\n link = {\r\n origin_id: innerNodes[link[0]].id,\r\n origin_slot: link[1],\r\n target_id: innerNode.id,\r\n target_slot: +slot\r\n }\r\n return link\r\n }\r\n }\r\n }\r\n\r\n this.node.updateLink = (link) => {\r\n // Replace the group node reference with the internal node\r\n link = { ...link }\r\n const output = this.groupData.newToOldOutputMap[link.origin_slot]\r\n let innerNode = this.innerNodes[output.node.index]\r\n let l\r\n while (innerNode?.type === 'Reroute') {\r\n l = innerNode.getInputLink(0)\r\n innerNode = innerNode.getInputNode(0)\r\n }\r\n\r\n if (!innerNode) {\r\n return null\r\n }\r\n\r\n if (l && GroupNodeHandler.isGroupNode(innerNode)) {\r\n return innerNode.updateLink(l)\r\n }\r\n\r\n link.origin_id = innerNode.id\r\n link.origin_slot = l?.origin_slot ?? output.slot\r\n return link\r\n }\r\n\r\n this.node.getInnerNodes = () => {\r\n if (!this.innerNodes) {\r\n this.node.setInnerNodes(\r\n this.groupData.nodeData.nodes.map((n, i) => {\r\n const innerNode = LiteGraph.createNode(n.type)\r\n innerNode.configure(n)\r\n // @ts-expect-error\r\n innerNode.id = `${this.node.id}:${i}`\r\n return innerNode\r\n })\r\n )\r\n }\r\n\r\n this.updateInnerWidgets()\r\n\r\n return this.innerNodes\r\n }\r\n\r\n this.node.recreate = async () => {\r\n const id = this.node.id\r\n const sz = this.node.size\r\n const nodes = this.node.convertToNodes()\r\n\r\n const groupNode = LiteGraph.createNode(this.node.type)\r\n groupNode.id = id\r\n\r\n // Reuse the existing nodes for this instance\r\n groupNode.setInnerNodes(nodes)\r\n groupNode[GROUP].populateWidgets()\r\n app.graph.add(groupNode)\r\n groupNode.size = [\r\n Math.max(groupNode.size[0], sz[0]),\r\n Math.max(groupNode.size[1], sz[1])\r\n ]\r\n\r\n // Remove all converted nodes and relink them\r\n groupNode[GROUP].replaceNodes(nodes)\r\n return groupNode\r\n }\r\n\r\n this.node.convertToNodes = () => {\r\n const addInnerNodes = () => {\r\n const backup = localStorage.getItem('litegrapheditor_clipboard')\r\n // Clone the node data so we dont mutate it for other nodes\r\n const c = { ...this.groupData.nodeData }\r\n c.nodes = [...c.nodes]\r\n const innerNodes = this.node.getInnerNodes()\r\n let ids = []\r\n for (let i = 0; i < c.nodes.length; i++) {\r\n let id = innerNodes?.[i]?.id\r\n // Use existing IDs if they are set on the inner nodes\r\n if (id == null || isNaN(id)) {\r\n id = undefined\r\n } else {\r\n ids.push(id)\r\n }\r\n c.nodes[i] = { ...c.nodes[i], id }\r\n }\r\n localStorage.setItem('litegrapheditor_clipboard', JSON.stringify(c))\r\n app.canvas.pasteFromClipboard()\r\n localStorage.setItem('litegrapheditor_clipboard', backup)\r\n\r\n const [x, y] = this.node.pos\r\n let top\r\n let left\r\n // Configure nodes with current widget data\r\n const selectedIds = ids.length\r\n ? ids\r\n : Object.keys(app.canvas.selected_nodes)\r\n const newNodes = []\r\n for (let i = 0; i < selectedIds.length; i++) {\r\n const id = selectedIds[i]\r\n const newNode = app.graph.getNodeById(id)\r\n const innerNode = innerNodes[i]\r\n newNodes.push(newNode)\r\n\r\n if (left == null || newNode.pos[0] < left) {\r\n left = newNode.pos[0]\r\n }\r\n if (top == null || newNode.pos[1] < top) {\r\n top = newNode.pos[1]\r\n }\r\n\r\n if (!newNode.widgets) continue\r\n\r\n const map = this.groupData.oldToNewWidgetMap[innerNode.index]\r\n if (map) {\r\n const widgets = Object.keys(map)\r\n\r\n for (const oldName of widgets) {\r\n const newName = map[oldName]\r\n if (!newName) continue\r\n\r\n const widgetIndex = this.node.widgets.findIndex(\r\n (w) => w.name === newName\r\n )\r\n if (widgetIndex === -1) continue\r\n\r\n // Populate the main and any linked widgets\r\n if (innerNode.type === 'PrimitiveNode') {\r\n for (let i = 0; i < newNode.widgets.length; i++) {\r\n newNode.widgets[i].value =\r\n this.node.widgets[widgetIndex + i].value\r\n }\r\n } else {\r\n const outerWidget = this.node.widgets[widgetIndex]\r\n const newWidget = newNode.widgets.find(\r\n (w) => w.name === oldName\r\n )\r\n if (!newWidget) continue\r\n\r\n newWidget.value = outerWidget.value\r\n for (let w = 0; w < outerWidget.linkedWidgets?.length; w++) {\r\n newWidget.linkedWidgets[w].value =\r\n outerWidget.linkedWidgets[w].value\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Shift each node\r\n for (const newNode of newNodes) {\r\n newNode.pos = [\r\n newNode.pos[0] - (left - x),\r\n newNode.pos[1] - (top - y)\r\n ]\r\n }\r\n\r\n return { newNodes, selectedIds }\r\n }\r\n\r\n const reconnectInputs = (selectedIds) => {\r\n for (const innerNodeIndex in this.groupData.oldToNewInputMap) {\r\n const id = selectedIds[innerNodeIndex]\r\n const newNode = app.graph.getNodeById(id)\r\n const map = this.groupData.oldToNewInputMap[innerNodeIndex]\r\n for (const innerInputId in map) {\r\n const groupSlotId = map[innerInputId]\r\n if (groupSlotId == null) continue\r\n const slot = node.inputs[groupSlotId]\r\n if (slot.link == null) continue\r\n const link = app.graph.links[slot.link]\r\n if (!link) continue\r\n // connect this node output to the input of another node\r\n const originNode = app.graph.getNodeById(link.origin_id)\r\n originNode.connect(link.origin_slot, newNode, +innerInputId)\r\n }\r\n }\r\n }\r\n\r\n const reconnectOutputs = (selectedIds) => {\r\n for (\r\n let groupOutputId = 0;\r\n groupOutputId < node.outputs?.length;\r\n groupOutputId++\r\n ) {\r\n const output = node.outputs[groupOutputId]\r\n if (!output.links) continue\r\n const links = [...output.links]\r\n for (const l of links) {\r\n const slot = this.groupData.newToOldOutputMap[groupOutputId]\r\n const link = app.graph.links[l]\r\n const targetNode = app.graph.getNodeById(link.target_id)\r\n const newNode = app.graph.getNodeById(selectedIds[slot.node.index])\r\n newNode.connect(slot.slot, targetNode, link.target_slot)\r\n }\r\n }\r\n }\r\n\r\n const { newNodes, selectedIds } = addInnerNodes()\r\n reconnectInputs(selectedIds)\r\n reconnectOutputs(selectedIds)\r\n app.graph.remove(this.node)\r\n\r\n return newNodes\r\n }\r\n\r\n const getExtraMenuOptions = this.node.getExtraMenuOptions\r\n this.node.getExtraMenuOptions = function (_, options) {\r\n getExtraMenuOptions?.apply(this, arguments)\r\n\r\n let optionIndex = options.findIndex((o) => o.content === 'Outputs')\r\n if (optionIndex === -1) optionIndex = options.length\r\n else optionIndex++\r\n options.splice(\r\n optionIndex,\r\n 0,\r\n null,\r\n {\r\n content: 'Convert to nodes',\r\n callback: () => {\r\n return this.convertToNodes()\r\n }\r\n },\r\n {\r\n content: 'Manage Group Node',\r\n callback: () => {\r\n new ManageGroupDialog(app).show(this.type)\r\n }\r\n }\r\n )\r\n }\r\n\r\n // Draw custom collapse icon to identity this as a group\r\n const onDrawTitleBox = this.node.onDrawTitleBox\r\n this.node.onDrawTitleBox = function (ctx, height, size, scale) {\r\n onDrawTitleBox?.apply(this, arguments)\r\n\r\n const fill = ctx.fillStyle\r\n ctx.beginPath()\r\n ctx.rect(11, -height + 11, 2, 2)\r\n ctx.rect(14, -height + 11, 2, 2)\r\n ctx.rect(17, -height + 11, 2, 2)\r\n ctx.rect(11, -height + 14, 2, 2)\r\n ctx.rect(14, -height + 14, 2, 2)\r\n ctx.rect(17, -height + 14, 2, 2)\r\n ctx.rect(11, -height + 17, 2, 2)\r\n ctx.rect(14, -height + 17, 2, 2)\r\n ctx.rect(17, -height + 17, 2, 2)\r\n\r\n ctx.fillStyle = this.boxcolor || LiteGraph.NODE_DEFAULT_BOXCOLOR\r\n ctx.fill()\r\n ctx.fillStyle = fill\r\n }\r\n\r\n // Draw progress label\r\n const onDrawForeground = node.onDrawForeground\r\n const groupData = this.groupData.nodeData\r\n node.onDrawForeground = function (ctx) {\r\n const r = onDrawForeground?.apply?.(this, arguments)\r\n if (\r\n +app.runningNodeId === this.id &&\r\n this.runningInternalNodeId !== null\r\n ) {\r\n const n = groupData.nodes[this.runningInternalNodeId]\r\n if (!n) return\r\n const message = `Running ${n.title || n.type} (${this.runningInternalNodeId}/${groupData.nodes.length})`\r\n ctx.save()\r\n ctx.font = '12px sans-serif'\r\n const sz = ctx.measureText(message)\r\n ctx.fillStyle = node.boxcolor || LiteGraph.NODE_DEFAULT_BOXCOLOR\r\n ctx.beginPath()\r\n ctx.roundRect(\r\n 0,\r\n -LiteGraph.NODE_TITLE_HEIGHT - 20,\r\n sz.width + 12,\r\n 20,\r\n 5\r\n )\r\n ctx.fill()\r\n\r\n ctx.fillStyle = '#fff'\r\n ctx.fillText(message, 6, -LiteGraph.NODE_TITLE_HEIGHT - 6)\r\n ctx.restore()\r\n }\r\n }\r\n\r\n // Flag this node as needing to be reset\r\n const onExecutionStart = this.node.onExecutionStart\r\n this.node.onExecutionStart = function () {\r\n this.resetExecution = true\r\n return onExecutionStart?.apply(this, arguments)\r\n }\r\n\r\n const self = this\r\n const onNodeCreated = this.node.onNodeCreated\r\n this.node.onNodeCreated = function () {\r\n if (!this.widgets) {\r\n return\r\n }\r\n const config = self.groupData.nodeData.config\r\n if (config) {\r\n for (const n in config) {\r\n const inputs = config[n]?.input\r\n for (const w in inputs) {\r\n if (inputs[w].visible !== false) continue\r\n const widgetName = self.groupData.oldToNewWidgetMap[n][w]\r\n const widget = this.widgets.find((w) => w.name === widgetName)\r\n if (widget) {\r\n widget.type = 'hidden'\r\n widget.computeSize = () => [0, -4]\r\n }\r\n }\r\n }\r\n }\r\n\r\n return onNodeCreated?.apply(this, arguments)\r\n }\r\n\r\n function handleEvent(type, getId, getEvent) {\r\n const handler = ({ detail }) => {\r\n const id = getId(detail)\r\n if (!id) return\r\n const node = app.graph.getNodeById(id)\r\n if (node) return\r\n\r\n const innerNodeIndex = this.innerNodes?.findIndex((n) => n.id == id)\r\n if (innerNodeIndex > -1) {\r\n this.node.runningInternalNodeId = innerNodeIndex\r\n api.dispatchEvent(\r\n new CustomEvent(type, {\r\n detail: getEvent(detail, this.node.id + '', this.node)\r\n })\r\n )\r\n }\r\n }\r\n api.addEventListener(type, handler)\r\n return handler\r\n }\r\n\r\n const executing = handleEvent.call(\r\n this,\r\n 'executing',\r\n (d) => d,\r\n (d, id, node) => id\r\n )\r\n\r\n const executed = handleEvent.call(\r\n this,\r\n 'executed',\r\n (d) => d?.display_node || d?.node,\r\n (d, id, node) => ({\r\n ...d,\r\n node: id,\r\n display_node: id,\r\n merge: !node.resetExecution\r\n })\r\n )\r\n\r\n const onRemoved = node.onRemoved\r\n this.node.onRemoved = function () {\r\n onRemoved?.apply(this, arguments)\r\n api.removeEventListener('executing', executing)\r\n api.removeEventListener('executed', executed)\r\n }\r\n\r\n this.node.refreshComboInNode = (defs) => {\r\n // Update combo widget options\r\n for (const widgetName in this.groupData.newToOldWidgetMap) {\r\n const widget = this.node.widgets.find((w) => w.name === widgetName)\r\n if (widget?.type === 'combo') {\r\n const old = this.groupData.newToOldWidgetMap[widgetName]\r\n const def = defs[old.node.type]\r\n const input =\r\n def?.input?.required?.[old.inputName] ??\r\n def?.input?.optional?.[old.inputName]\r\n if (!input) continue\r\n\r\n widget.options.values = input[0]\r\n\r\n if (\r\n old.inputName !== 'image' &&\r\n !widget.options.values.includes(widget.value)\r\n ) {\r\n widget.value = widget.options.values[0]\r\n widget.callback(widget.value)\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n updateInnerWidgets() {\r\n for (const newWidgetName in this.groupData.newToOldWidgetMap) {\r\n const newWidget = this.node.widgets.find((w) => w.name === newWidgetName)\r\n if (!newWidget) continue\r\n\r\n const newValue = newWidget.value\r\n const old = this.groupData.newToOldWidgetMap[newWidgetName]\r\n let innerNode = this.innerNodes[old.node.index]\r\n\r\n if (innerNode.type === 'PrimitiveNode') {\r\n innerNode.primitiveValue = newValue\r\n const primitiveLinked = this.groupData.primitiveToWidget[old.node.index]\r\n for (const linked of primitiveLinked ?? []) {\r\n const node = this.innerNodes[linked.nodeId]\r\n const widget = node.widgets.find((w) => w.name === linked.inputName)\r\n\r\n if (widget) {\r\n widget.value = newValue\r\n }\r\n }\r\n continue\r\n } else if (innerNode.type === 'Reroute') {\r\n const rerouteLinks = this.groupData.linksFrom[old.node.index]\r\n if (rerouteLinks) {\r\n for (const [_, , targetNodeId, targetSlot] of rerouteLinks['0']) {\r\n const node = this.innerNodes[targetNodeId]\r\n const input = node.inputs[targetSlot]\r\n if (input.widget) {\r\n const widget = node.widgets?.find(\r\n (w) => w.name === input.widget.name\r\n )\r\n if (widget) {\r\n widget.value = newValue\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n const widget = innerNode.widgets?.find((w) => w.name === old.inputName)\r\n if (widget) {\r\n widget.value = newValue\r\n }\r\n }\r\n }\r\n\r\n populatePrimitive(node, nodeId, oldName, i, linkedShift) {\r\n // Converted widget, populate primitive if linked\r\n const primitiveId = this.groupData.widgetToPrimitive[nodeId]?.[oldName]\r\n if (primitiveId == null) return\r\n const targetWidgetName =\r\n this.groupData.oldToNewWidgetMap[primitiveId]['value']\r\n const targetWidgetIndex = this.node.widgets.findIndex(\r\n (w) => w.name === targetWidgetName\r\n )\r\n if (targetWidgetIndex > -1) {\r\n const primitiveNode = this.innerNodes[primitiveId]\r\n let len = primitiveNode.widgets.length\r\n if (\r\n len - 1 !==\r\n this.node.widgets[targetWidgetIndex].linkedWidgets?.length\r\n ) {\r\n // Fallback handling for if some reason the primitive has a different number of widgets\r\n // we dont want to overwrite random widgets, better to leave blank\r\n len = 1\r\n }\r\n for (let i = 0; i < len; i++) {\r\n this.node.widgets[targetWidgetIndex + i].value =\r\n primitiveNode.widgets[i].value\r\n }\r\n }\r\n return true\r\n }\r\n\r\n populateReroute(node, nodeId, map) {\r\n if (node.type !== 'Reroute') return\r\n\r\n const link = this.groupData.linksFrom[nodeId]?.[0]?.[0]\r\n if (!link) return\r\n const [, , targetNodeId, targetNodeSlot] = link\r\n const targetNode = this.groupData.nodeData.nodes[targetNodeId]\r\n const inputs = targetNode.inputs\r\n const targetWidget = inputs?.[targetNodeSlot]?.widget\r\n if (!targetWidget) return\r\n\r\n const offset = inputs.length - (targetNode.widgets_values?.length ?? 0)\r\n const v = targetNode.widgets_values?.[targetNodeSlot - offset]\r\n if (v == null) return\r\n\r\n const widgetName = Object.values(map)[0]\r\n const widget = this.node.widgets.find((w) => w.name === widgetName)\r\n if (widget) {\r\n widget.value = v\r\n }\r\n }\r\n\r\n populateWidgets() {\r\n if (!this.node.widgets) return\r\n\r\n for (\r\n let nodeId = 0;\r\n nodeId < this.groupData.nodeData.nodes.length;\r\n nodeId++\r\n ) {\r\n const node = this.groupData.nodeData.nodes[nodeId]\r\n const map = this.groupData.oldToNewWidgetMap[nodeId] ?? {}\r\n const widgets = Object.keys(map)\r\n\r\n if (!node.widgets_values?.length) {\r\n // special handling for populating values into reroutes\r\n // this allows primitives connect to them to pick up the correct value\r\n this.populateReroute(node, nodeId, map)\r\n continue\r\n }\r\n\r\n let linkedShift = 0\r\n for (let i = 0; i < widgets.length; i++) {\r\n const oldName = widgets[i]\r\n const newName = map[oldName]\r\n const widgetIndex = this.node.widgets.findIndex(\r\n (w) => w.name === newName\r\n )\r\n const mainWidget = this.node.widgets[widgetIndex]\r\n if (\r\n this.populatePrimitive(node, nodeId, oldName, i, linkedShift) ||\r\n widgetIndex === -1\r\n ) {\r\n // Find the inner widget and shift by the number of linked widgets as they will have been removed too\r\n const innerWidget = this.innerNodes[nodeId].widgets?.find(\r\n (w) => w.name === oldName\r\n )\r\n linkedShift += innerWidget?.linkedWidgets?.length ?? 0\r\n }\r\n if (widgetIndex === -1) {\r\n continue\r\n }\r\n\r\n // Populate the main and any linked widget\r\n mainWidget.value = node.widgets_values[i + linkedShift]\r\n for (let w = 0; w < mainWidget.linkedWidgets?.length; w++) {\r\n this.node.widgets[widgetIndex + w + 1].value =\r\n node.widgets_values[i + ++linkedShift]\r\n }\r\n }\r\n }\r\n }\r\n\r\n replaceNodes(nodes) {\r\n let top\r\n let left\r\n\r\n for (let i = 0; i < nodes.length; i++) {\r\n const node = nodes[i]\r\n if (left == null || node.pos[0] < left) {\r\n left = node.pos[0]\r\n }\r\n if (top == null || node.pos[1] < top) {\r\n top = node.pos[1]\r\n }\r\n\r\n this.linkOutputs(node, i)\r\n app.graph.remove(node)\r\n }\r\n\r\n this.linkInputs()\r\n this.node.pos = [left, top]\r\n }\r\n\r\n linkOutputs(originalNode, nodeId) {\r\n if (!originalNode.outputs) return\r\n\r\n for (const output of originalNode.outputs) {\r\n if (!output.links) continue\r\n // Clone the links as they'll be changed if we reconnect\r\n const links = [...output.links]\r\n for (const l of links) {\r\n const link = app.graph.links[l]\r\n if (!link) continue\r\n\r\n const targetNode = app.graph.getNodeById(link.target_id)\r\n const newSlot =\r\n this.groupData.oldToNewOutputMap[nodeId]?.[link.origin_slot]\r\n if (newSlot != null) {\r\n this.node.connect(newSlot, targetNode, link.target_slot)\r\n }\r\n }\r\n }\r\n }\r\n\r\n linkInputs() {\r\n for (const link of this.groupData.nodeData.links ?? []) {\r\n const [, originSlot, targetId, targetSlot, actualOriginId] = link\r\n const originNode = app.graph.getNodeById(actualOriginId)\r\n if (!originNode) continue // this node is in the group\r\n originNode.connect(\r\n originSlot,\r\n this.node.id,\r\n this.groupData.oldToNewInputMap[targetId][targetSlot]\r\n )\r\n }\r\n }\r\n\r\n static getGroupData(node) {\r\n return (node.nodeData ?? node.constructor?.nodeData)?.[GROUP]\r\n }\r\n\r\n static isGroupNode(node) {\r\n return !!node.constructor?.nodeData?.[GROUP]\r\n }\r\n\r\n static async fromNodes(nodes) {\r\n // Process the nodes into the stored workflow group node data\r\n const builder = new GroupNodeBuilder(nodes)\r\n const res = builder.build()\r\n if (!res) return\r\n\r\n const { name, nodeData } = res\r\n\r\n // Convert this data into a LG node definition and register it\r\n const config = new GroupNodeConfig(name, nodeData)\r\n await config.registerType()\r\n\r\n const groupNode = LiteGraph.createNode(`workflow/${name}`)\r\n // Reuse the existing nodes for this instance\r\n groupNode.setInnerNodes(builder.nodes)\r\n groupNode[GROUP].populateWidgets()\r\n app.graph.add(groupNode)\r\n\r\n // Remove all converted nodes and relink them\r\n groupNode[GROUP].replaceNodes(builder.nodes)\r\n return groupNode\r\n }\r\n}\r\n\r\nfunction addConvertToGroupOptions() {\r\n function addConvertOption(options, index) {\r\n const selected = Object.values(app.canvas.selected_nodes ?? {})\r\n const disabled =\r\n selected.length < 2 ||\r\n selected.find((n) => GroupNodeHandler.isGroupNode(n))\r\n options.splice(index + 1, null, {\r\n content: `Convert to Group Node`,\r\n disabled,\r\n callback: async () => {\r\n return await GroupNodeHandler.fromNodes(selected)\r\n }\r\n })\r\n }\r\n\r\n function addManageOption(options, index) {\r\n const groups = app.graph.extra?.groupNodes\r\n const disabled = !groups || !Object.keys(groups).length\r\n options.splice(index + 1, null, {\r\n content: `Manage Group Nodes`,\r\n disabled,\r\n callback: () => {\r\n new ManageGroupDialog(app).show()\r\n }\r\n })\r\n }\r\n\r\n // Add to canvas\r\n const getCanvasMenuOptions = LGraphCanvas.prototype.getCanvasMenuOptions\r\n LGraphCanvas.prototype.getCanvasMenuOptions = function () {\r\n const options = getCanvasMenuOptions.apply(this, arguments)\r\n const index =\r\n options.findIndex((o) => o?.content === 'Add Group') + 1 || options.length\r\n addConvertOption(options, index)\r\n addManageOption(options, index + 1)\r\n return options\r\n }\r\n\r\n // Add to nodes\r\n const getNodeMenuOptions = LGraphCanvas.prototype.getNodeMenuOptions\r\n LGraphCanvas.prototype.getNodeMenuOptions = function (node) {\r\n const options = getNodeMenuOptions.apply(this, arguments)\r\n if (!GroupNodeHandler.isGroupNode(node)) {\r\n const index =\r\n options.findIndex((o) => o?.content === 'Outputs') + 1 ||\r\n options.length - 1\r\n addConvertOption(options, index)\r\n }\r\n return options\r\n }\r\n}\r\n\r\nconst id = 'Comfy.GroupNode'\r\nlet globalDefs\r\nconst ext = {\r\n name: id,\r\n setup() {\r\n addConvertToGroupOptions()\r\n },\r\n async beforeConfigureGraph(graphData, missingNodeTypes) {\r\n const nodes = graphData?.extra?.groupNodes\r\n if (nodes) {\r\n await GroupNodeConfig.registerFromWorkflow(nodes, missingNodeTypes)\r\n }\r\n },\r\n addCustomNodeDefs(defs) {\r\n // Store this so we can mutate it later with group nodes\r\n globalDefs = defs\r\n },\r\n nodeCreated(node) {\r\n if (GroupNodeHandler.isGroupNode(node)) {\r\n node[GROUP] = new GroupNodeHandler(node)\r\n }\r\n },\r\n async refreshComboInNodes(defs) {\r\n // Re-register group nodes so new ones are created with the correct options\r\n Object.assign(globalDefs, defs)\r\n const nodes = app.graph.extra?.groupNodes\r\n if (nodes) {\r\n await GroupNodeConfig.registerFromWorkflow(nodes, {})\r\n }\r\n }\r\n}\r\n\r\napp.registerExtension(ext)\r\n","import { app } from '../../scripts/app'\r\nimport { LGraphCanvas, LiteGraph } from '@comfyorg/litegraph'\r\n\r\nfunction setNodeMode(node, mode) {\r\n node.mode = mode\r\n node.graph.change()\r\n}\r\n\r\nfunction addNodesToGroup(group, nodes = []) {\r\n var x1, y1, x2, y2\r\n var nx1, ny1, nx2, ny2\r\n var node\r\n\r\n x1 = y1 = x2 = y2 = -1\r\n nx1 = ny1 = nx2 = ny2 = -1\r\n\r\n for (var n of [group._nodes, nodes]) {\r\n for (var i in n) {\r\n node = n[i]\r\n\r\n nx1 = node.pos[0]\r\n ny1 = node.pos[1]\r\n nx2 = node.pos[0] + node.size[0]\r\n ny2 = node.pos[1] + node.size[1]\r\n\r\n if (node.type != 'Reroute') {\r\n ny1 -= LiteGraph.NODE_TITLE_HEIGHT\r\n }\r\n\r\n if (node.flags?.collapsed) {\r\n ny2 = ny1 + LiteGraph.NODE_TITLE_HEIGHT\r\n\r\n if (node?._collapsed_width) {\r\n nx2 = nx1 + Math.round(node._collapsed_width)\r\n }\r\n }\r\n\r\n if (x1 == -1 || nx1 < x1) {\r\n x1 = nx1\r\n }\r\n\r\n if (y1 == -1 || ny1 < y1) {\r\n y1 = ny1\r\n }\r\n\r\n if (x2 == -1 || nx2 > x2) {\r\n x2 = nx2\r\n }\r\n\r\n if (y2 == -1 || ny2 > y2) {\r\n y2 = ny2\r\n }\r\n }\r\n }\r\n\r\n var padding = 10\r\n\r\n y1 = y1 - Math.round(group.font_size * 1.4)\r\n\r\n group.pos = [x1 - padding, y1 - padding]\r\n group.size = [x2 - x1 + padding * 2, y2 - y1 + padding * 2]\r\n}\r\n\r\napp.registerExtension({\r\n name: 'Comfy.GroupOptions',\r\n setup() {\r\n const orig = LGraphCanvas.prototype.getCanvasMenuOptions\r\n // graph_mouse\r\n LGraphCanvas.prototype.getCanvasMenuOptions = function () {\r\n const options = orig.apply(this, arguments)\r\n const group = this.graph.getGroupOnPos(\r\n this.graph_mouse[0],\r\n this.graph_mouse[1]\r\n )\r\n if (!group) {\r\n options.push({\r\n content: 'Add Group For Selected Nodes',\r\n disabled: !Object.keys(app.canvas.selected_nodes || {}).length,\r\n callback: () => {\r\n // @ts-expect-error\r\n var group = new LiteGraph.LGraphGroup()\r\n addNodesToGroup(group, this.selected_nodes)\r\n app.canvas.graph.add(group)\r\n this.graph.change()\r\n }\r\n })\r\n\r\n return options\r\n }\r\n\r\n // Group nodes aren't recomputed until the group is moved, this ensures the nodes are up-to-date\r\n group.recomputeInsideNodes()\r\n const nodesInGroup = group._nodes\r\n\r\n options.push({\r\n content: 'Add Selected Nodes To Group',\r\n disabled: !Object.keys(app.canvas.selected_nodes || {}).length,\r\n callback: () => {\r\n addNodesToGroup(group, this.selected_nodes)\r\n this.graph.change()\r\n }\r\n })\r\n\r\n // No nodes in group, return default options\r\n if (nodesInGroup.length === 0) {\r\n return options\r\n } else {\r\n // Add a separator between the default options and the group options\r\n options.push(null)\r\n }\r\n\r\n // Check if all nodes are the same mode\r\n let allNodesAreSameMode = true\r\n for (let i = 1; i < nodesInGroup.length; i++) {\r\n if (nodesInGroup[i].mode !== nodesInGroup[0].mode) {\r\n allNodesAreSameMode = false\r\n break\r\n }\r\n }\r\n\r\n options.push({\r\n content: 'Fit Group To Nodes',\r\n callback: () => {\r\n addNodesToGroup(group)\r\n this.graph.change()\r\n }\r\n })\r\n\r\n options.push({\r\n content: 'Select Nodes',\r\n callback: () => {\r\n this.selectNodes(nodesInGroup)\r\n this.graph.change()\r\n this.canvas.focus()\r\n }\r\n })\r\n\r\n // Modes\r\n // 0: Always\r\n // 1: On Event\r\n // 2: Never\r\n // 3: On Trigger\r\n // 4: Bypass\r\n // If all nodes are the same mode, add a menu option to change the mode\r\n if (allNodesAreSameMode) {\r\n const mode = nodesInGroup[0].mode\r\n switch (mode) {\r\n case 0:\r\n // All nodes are always, option to disable, and bypass\r\n options.push({\r\n content: 'Set Group Nodes to Never',\r\n callback: () => {\r\n for (const node of nodesInGroup) {\r\n setNodeMode(node, 2)\r\n }\r\n }\r\n })\r\n options.push({\r\n content: 'Bypass Group Nodes',\r\n callback: () => {\r\n for (const node of nodesInGroup) {\r\n setNodeMode(node, 4)\r\n }\r\n }\r\n })\r\n break\r\n case 2:\r\n // All nodes are never, option to enable, and bypass\r\n options.push({\r\n content: 'Set Group Nodes to Always',\r\n callback: () => {\r\n for (const node of nodesInGroup) {\r\n setNodeMode(node, 0)\r\n }\r\n }\r\n })\r\n options.push({\r\n content: 'Bypass Group Nodes',\r\n callback: () => {\r\n for (const node of nodesInGroup) {\r\n setNodeMode(node, 4)\r\n }\r\n }\r\n })\r\n break\r\n case 4:\r\n // All nodes are bypass, option to enable, and disable\r\n options.push({\r\n content: 'Set Group Nodes to Always',\r\n callback: () => {\r\n for (const node of nodesInGroup) {\r\n setNodeMode(node, 0)\r\n }\r\n }\r\n })\r\n options.push({\r\n content: 'Set Group Nodes to Never',\r\n callback: () => {\r\n for (const node of nodesInGroup) {\r\n setNodeMode(node, 2)\r\n }\r\n }\r\n })\r\n break\r\n default:\r\n // All nodes are On Trigger or On Event(Or other?), option to disable, set to always, or bypass\r\n options.push({\r\n content: 'Set Group Nodes to Always',\r\n callback: () => {\r\n for (const node of nodesInGroup) {\r\n setNodeMode(node, 0)\r\n }\r\n }\r\n })\r\n options.push({\r\n content: 'Set Group Nodes to Never',\r\n callback: () => {\r\n for (const node of nodesInGroup) {\r\n setNodeMode(node, 2)\r\n }\r\n }\r\n })\r\n options.push({\r\n content: 'Bypass Group Nodes',\r\n callback: () => {\r\n for (const node of nodesInGroup) {\r\n setNodeMode(node, 4)\r\n }\r\n }\r\n })\r\n break\r\n }\r\n } else {\r\n // Nodes are not all the same mode, add a menu option to change the mode to always, never, or bypass\r\n options.push({\r\n content: 'Set Group Nodes to Always',\r\n callback: () => {\r\n for (const node of nodesInGroup) {\r\n setNodeMode(node, 0)\r\n }\r\n }\r\n })\r\n options.push({\r\n content: 'Set Group Nodes to Never',\r\n callback: () => {\r\n for (const node of nodesInGroup) {\r\n setNodeMode(node, 2)\r\n }\r\n }\r\n })\r\n options.push({\r\n content: 'Bypass Group Nodes',\r\n callback: () => {\r\n for (const node of nodesInGroup) {\r\n setNodeMode(node, 4)\r\n }\r\n }\r\n })\r\n }\r\n\r\n return options\r\n }\r\n }\r\n})\r\n","import { LiteGraph } from '@comfyorg/litegraph'\r\nimport { app } from '../../scripts/app'\r\n\r\n// Inverts the scrolling of context menus\r\n\r\nconst id = 'Comfy.InvertMenuScrolling'\r\napp.registerExtension({\r\n name: id,\r\n init() {\r\n const ctxMenu = LiteGraph.ContextMenu\r\n const replace = () => {\r\n // @ts-expect-error\r\n LiteGraph.ContextMenu = function (values, options) {\r\n options = options || {}\r\n if (options.scroll_speed) {\r\n options.scroll_speed *= -1\r\n } else {\r\n options.scroll_speed = -0.1\r\n }\r\n return ctxMenu.call(this, values, options)\r\n }\r\n LiteGraph.ContextMenu.prototype = ctxMenu.prototype\r\n }\r\n app.ui.settings.addSetting({\r\n id,\r\n category: ['Comfy', 'Graph', 'InvertMenuScrolling'],\r\n name: 'Invert Context Menu Scrolling',\r\n type: 'boolean',\r\n defaultValue: false,\r\n onChange(value) {\r\n if (value) {\r\n replace()\r\n } else {\r\n LiteGraph.ContextMenu = ctxMenu\r\n }\r\n }\r\n })\r\n }\r\n})\r\n","import { app } from '../../scripts/app'\r\nimport { api } from '../../scripts/api'\r\nimport { useToastStore } from '@/stores/toastStore'\r\n\r\napp.registerExtension({\r\n name: 'Comfy.Keybinds',\r\n init() {\r\n const keybindListener = async function (event) {\r\n const modifierPressed = event.ctrlKey || event.metaKey\r\n\r\n // Queue prompt using (ctrl or command) + enter\r\n if (modifierPressed && event.key === 'Enter') {\r\n // Cancel current prompt using (ctrl or command) + alt + enter\r\n if (event.altKey) {\r\n await api.interrupt()\r\n useToastStore().add({\r\n severity: 'info',\r\n summary: 'Interrupted',\r\n detail: 'Execution has been interrupted',\r\n life: 1000\r\n })\r\n return\r\n }\r\n // Queue prompt as first for generation using (ctrl or command) + shift + enter\r\n app.queuePrompt(event.shiftKey ? -1 : 0).then()\r\n return\r\n }\r\n\r\n const target = event.composedPath()[0]\r\n if (['INPUT', 'TEXTAREA'].includes(target.tagName)) {\r\n return\r\n }\r\n\r\n const modifierKeyIdMap = {\r\n s: '#comfy-save-button',\r\n o: '#comfy-file-input',\r\n Backspace: '#comfy-clear-button',\r\n d: '#comfy-load-default-button'\r\n }\r\n\r\n const modifierKeybindId = modifierKeyIdMap[event.key]\r\n if (modifierPressed && modifierKeybindId) {\r\n event.preventDefault()\r\n\r\n const elem = document.querySelector(modifierKeybindId)\r\n elem.click()\r\n return\r\n }\r\n\r\n // Finished Handling all modifier keybinds, now handle the rest\r\n if (event.ctrlKey || event.altKey || event.metaKey) {\r\n return\r\n }\r\n\r\n // Close out of modals using escape\r\n if (event.key === 'Escape') {\r\n const modals = document.querySelectorAll('.comfy-modal')\r\n const modal = Array.from(modals).find(\r\n (modal) =>\r\n window.getComputedStyle(modal).getPropertyValue('display') !==\r\n 'none'\r\n )\r\n if (modal) {\r\n modal.style.display = 'none'\r\n }\r\n\r\n ;[...document.querySelectorAll('dialog')].forEach((d) => {\r\n d.close()\r\n })\r\n }\r\n\r\n const keyIdMap = {\r\n q: '.queue-tab-button.side-bar-button',\r\n h: '.queue-tab-button.side-bar-button',\r\n r: '#comfy-refresh-button'\r\n }\r\n\r\n const buttonId = keyIdMap[event.key]\r\n if (buttonId) {\r\n const button = document.querySelector(buttonId)\r\n button.click()\r\n }\r\n }\r\n\r\n window.addEventListener('keydown', keybindListener, true)\r\n }\r\n})\r\n","import { app } from '../../scripts/app'\r\nimport { LiteGraph } from '@comfyorg/litegraph'\r\nconst id = 'Comfy.LinkRenderMode'\r\nconst ext = {\r\n name: id,\r\n async setup(app) {\r\n app.ui.settings.addSetting({\r\n id,\r\n category: ['Comfy', 'Graph', 'LinkRenderMode'],\r\n name: 'Link Render Mode',\r\n defaultValue: 2,\r\n type: 'combo',\r\n // @ts-expect-error\r\n options: [...LiteGraph.LINK_RENDER_MODES, 'Hidden'].map((m, i) => ({\r\n value: i,\r\n text: m,\r\n selected: i == app.canvas.links_render_mode\r\n })),\r\n onChange(value) {\r\n app.canvas.links_render_mode = +value\r\n app.graph.setDirtyCanvas(true)\r\n }\r\n })\r\n }\r\n}\r\n\r\napp.registerExtension(ext)\r\n","import { app } from '../../scripts/app'\r\nimport { ComfyDialog, $el } from '../../scripts/ui'\r\nimport { ComfyApp } from '../../scripts/app'\r\nimport { api } from '../../scripts/api'\r\nimport { ClipspaceDialog } from './clipspace'\r\n\r\n// Helper function to convert a data URL to a Blob object\r\nfunction dataURLToBlob(dataURL) {\r\n const parts = dataURL.split(';base64,')\r\n const contentType = parts[0].split(':')[1]\r\n const byteString = atob(parts[1])\r\n const arrayBuffer = new ArrayBuffer(byteString.length)\r\n const uint8Array = new Uint8Array(arrayBuffer)\r\n for (let i = 0; i < byteString.length; i++) {\r\n uint8Array[i] = byteString.charCodeAt(i)\r\n }\r\n return new Blob([arrayBuffer], { type: contentType })\r\n}\r\n\r\nfunction loadedImageToBlob(image) {\r\n const canvas = document.createElement('canvas')\r\n\r\n canvas.width = image.width\r\n canvas.height = image.height\r\n\r\n const ctx = canvas.getContext('2d')\r\n\r\n ctx.drawImage(image, 0, 0)\r\n\r\n const dataURL = canvas.toDataURL('image/png', 1)\r\n const blob = dataURLToBlob(dataURL)\r\n\r\n return blob\r\n}\r\n\r\nfunction loadImage(imagePath) {\r\n return new Promise((resolve, reject) => {\r\n const image = new Image()\r\n\r\n image.onload = function () {\r\n resolve(image)\r\n }\r\n\r\n image.src = imagePath\r\n })\r\n}\r\n\r\nasync function uploadMask(filepath, formData) {\r\n await api\r\n .fetchApi('/upload/mask', {\r\n method: 'POST',\r\n body: formData\r\n })\r\n .then((response) => {})\r\n .catch((error) => {\r\n console.error('Error:', error)\r\n })\r\n\r\n ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']] = new Image()\r\n ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']].src = api.apiURL(\r\n '/view?' +\r\n new URLSearchParams(filepath).toString() +\r\n app.getPreviewFormatParam() +\r\n app.getRandParam()\r\n )\r\n\r\n if (ComfyApp.clipspace.images)\r\n ComfyApp.clipspace.images[ComfyApp.clipspace['selectedIndex']] = filepath\r\n\r\n ClipspaceDialog.invalidatePreview()\r\n}\r\n\r\nfunction prepare_mask(image, maskCanvas, maskCtx, maskColor) {\r\n // paste mask data into alpha channel\r\n maskCtx.drawImage(image, 0, 0, maskCanvas.width, maskCanvas.height)\r\n const maskData = maskCtx.getImageData(\r\n 0,\r\n 0,\r\n maskCanvas.width,\r\n maskCanvas.height\r\n )\r\n\r\n // invert mask\r\n for (let i = 0; i < maskData.data.length; i += 4) {\r\n if (maskData.data[i + 3] == 255) maskData.data[i + 3] = 0\r\n else maskData.data[i + 3] = 255\r\n\r\n maskData.data[i] = maskColor.r\r\n maskData.data[i + 1] = maskColor.g\r\n maskData.data[i + 2] = maskColor.b\r\n }\r\n\r\n maskCtx.globalCompositeOperation = 'source-over'\r\n maskCtx.putImageData(maskData, 0, 0)\r\n}\r\n\r\nclass MaskEditorDialog extends ComfyDialog {\r\n static instance = null\r\n static mousedown_x: number | null = null\r\n static mousedown_y: number | null = null\r\n\r\n brush: HTMLDivElement\r\n maskCtx: any\r\n maskCanvas: HTMLCanvasElement\r\n brush_size_slider: HTMLDivElement\r\n brush_opacity_slider: HTMLDivElement\r\n colorButton: HTMLButtonElement\r\n saveButton: HTMLButtonElement\r\n zoom_ratio: number\r\n pan_x: number\r\n pan_y: number\r\n imgCanvas: HTMLCanvasElement\r\n last_display_style: string\r\n is_visible: boolean\r\n image: HTMLImageElement\r\n handler_registered: boolean\r\n brush_slider_input: HTMLInputElement\r\n cursorX: number\r\n cursorY: number\r\n mousedown_pan_x: number\r\n mousedown_pan_y: number\r\n last_pressure: number\r\n\r\n static getInstance() {\r\n if (!MaskEditorDialog.instance) {\r\n MaskEditorDialog.instance = new MaskEditorDialog()\r\n }\r\n\r\n return MaskEditorDialog.instance\r\n }\r\n\r\n is_layout_created = false\r\n\r\n constructor() {\r\n super()\r\n this.element = $el('div.comfy-modal', { parent: document.body }, [\r\n $el('div.comfy-modal-content', [...this.createButtons()])\r\n ])\r\n }\r\n\r\n createButtons() {\r\n return []\r\n }\r\n\r\n createButton(name, callback): HTMLButtonElement {\r\n var button = document.createElement('button')\r\n button.style.pointerEvents = 'auto'\r\n button.innerText = name\r\n button.addEventListener('click', callback)\r\n return button\r\n }\r\n\r\n createLeftButton(name, callback) {\r\n var button = this.createButton(name, callback)\r\n button.style.cssFloat = 'left'\r\n button.style.marginRight = '4px'\r\n return button\r\n }\r\n\r\n createRightButton(name, callback) {\r\n var button = this.createButton(name, callback)\r\n button.style.cssFloat = 'right'\r\n button.style.marginLeft = '4px'\r\n return button\r\n }\r\n\r\n createLeftSlider(self, name, callback): HTMLDivElement {\r\n const divElement = document.createElement('div')\r\n divElement.id = 'maskeditor-slider'\r\n divElement.style.cssFloat = 'left'\r\n divElement.style.fontFamily = 'sans-serif'\r\n divElement.style.marginRight = '4px'\r\n divElement.style.color = 'var(--input-text)'\r\n divElement.style.backgroundColor = 'var(--comfy-input-bg)'\r\n divElement.style.borderRadius = '8px'\r\n divElement.style.borderColor = 'var(--border-color)'\r\n divElement.style.borderStyle = 'solid'\r\n divElement.style.fontSize = '15px'\r\n divElement.style.height = '21px'\r\n divElement.style.padding = '1px 6px'\r\n divElement.style.display = 'flex'\r\n divElement.style.position = 'relative'\r\n divElement.style.top = '2px'\r\n divElement.style.pointerEvents = 'auto'\r\n self.brush_slider_input = document.createElement('input')\r\n self.brush_slider_input.setAttribute('type', 'range')\r\n self.brush_slider_input.setAttribute('min', '1')\r\n self.brush_slider_input.setAttribute('max', '100')\r\n self.brush_slider_input.setAttribute('value', '10')\r\n const labelElement = document.createElement('label')\r\n labelElement.textContent = name\r\n\r\n divElement.appendChild(labelElement)\r\n divElement.appendChild(self.brush_slider_input)\r\n\r\n self.brush_slider_input.addEventListener('change', callback)\r\n\r\n return divElement\r\n }\r\n\r\n createOpacitySlider(self, name, callback): HTMLDivElement {\r\n const divElement = document.createElement('div')\r\n divElement.id = 'maskeditor-opacity-slider'\r\n divElement.style.cssFloat = 'left'\r\n divElement.style.fontFamily = 'sans-serif'\r\n divElement.style.marginRight = '4px'\r\n divElement.style.color = 'var(--input-text)'\r\n divElement.style.backgroundColor = 'var(--comfy-input-bg)'\r\n divElement.style.borderRadius = '8px'\r\n divElement.style.borderColor = 'var(--border-color)'\r\n divElement.style.borderStyle = 'solid'\r\n divElement.style.fontSize = '15px'\r\n divElement.style.height = '21px'\r\n divElement.style.padding = '1px 6px'\r\n divElement.style.display = 'flex'\r\n divElement.style.position = 'relative'\r\n divElement.style.top = '2px'\r\n divElement.style.pointerEvents = 'auto'\r\n self.opacity_slider_input = document.createElement('input')\r\n self.opacity_slider_input.setAttribute('type', 'range')\r\n self.opacity_slider_input.setAttribute('min', '0.1')\r\n self.opacity_slider_input.setAttribute('max', '1.0')\r\n self.opacity_slider_input.setAttribute('step', '0.01')\r\n self.opacity_slider_input.setAttribute('value', '0.7')\r\n const labelElement = document.createElement('label')\r\n labelElement.textContent = name\r\n\r\n divElement.appendChild(labelElement)\r\n divElement.appendChild(self.opacity_slider_input)\r\n\r\n self.opacity_slider_input.addEventListener('input', callback)\r\n\r\n return divElement\r\n }\r\n\r\n setlayout(imgCanvas: HTMLCanvasElement, maskCanvas: HTMLCanvasElement) {\r\n const self = this\r\n\r\n // If it is specified as relative, using it only as a hidden placeholder for padding is recommended\r\n // to prevent anomalies where it exceeds a certain size and goes outside of the window.\r\n var bottom_panel = document.createElement('div')\r\n bottom_panel.style.position = 'absolute'\r\n bottom_panel.style.bottom = '0px'\r\n bottom_panel.style.left = '20px'\r\n bottom_panel.style.right = '20px'\r\n bottom_panel.style.height = '50px'\r\n bottom_panel.style.pointerEvents = 'none'\r\n\r\n var brush = document.createElement('div')\r\n brush.id = 'brush'\r\n brush.style.backgroundColor = 'transparent'\r\n brush.style.outline = '1px dashed black'\r\n brush.style.boxShadow = '0 0 0 1px white'\r\n brush.style.borderRadius = '50%'\r\n // @ts-expect-error\r\n brush.style.MozBorderRadius = '50%'\r\n // @ts-expect-error\r\n brush.style.WebkitBorderRadius = '50%'\r\n brush.style.position = 'absolute'\r\n brush.style.zIndex = '8889'\r\n brush.style.pointerEvents = 'none'\r\n this.brush = brush\r\n this.element.appendChild(imgCanvas)\r\n this.element.appendChild(maskCanvas)\r\n this.element.appendChild(bottom_panel)\r\n document.body.appendChild(brush)\r\n\r\n var clearButton = this.createLeftButton('Clear', () => {\r\n self.maskCtx.clearRect(\r\n 0,\r\n 0,\r\n self.maskCanvas.width,\r\n self.maskCanvas.height\r\n )\r\n })\r\n\r\n this.brush_size_slider = this.createLeftSlider(\r\n self,\r\n 'Thickness',\r\n (event) => {\r\n self.brush_size = event.target.value\r\n self.updateBrushPreview(self)\r\n }\r\n )\r\n\r\n this.brush_opacity_slider = this.createOpacitySlider(\r\n self,\r\n 'Opacity',\r\n (event) => {\r\n self.brush_opacity = event.target.value\r\n if (self.brush_color_mode !== 'negative') {\r\n self.maskCanvas.style.opacity = self.brush_opacity.toString()\r\n }\r\n }\r\n )\r\n\r\n this.colorButton = this.createLeftButton(this.getColorButtonText(), () => {\r\n if (self.brush_color_mode === 'black') {\r\n self.brush_color_mode = 'white'\r\n } else if (self.brush_color_mode === 'white') {\r\n self.brush_color_mode = 'negative'\r\n } else {\r\n self.brush_color_mode = 'black'\r\n }\r\n\r\n self.updateWhenBrushColorModeChanged()\r\n })\r\n\r\n var cancelButton = this.createRightButton('Cancel', () => {\r\n document.removeEventListener('keydown', MaskEditorDialog.handleKeyDown)\r\n self.close()\r\n })\r\n\r\n this.saveButton = this.createRightButton('Save', () => {\r\n document.removeEventListener('keydown', MaskEditorDialog.handleKeyDown)\r\n self.save()\r\n })\r\n\r\n this.element.appendChild(imgCanvas)\r\n this.element.appendChild(maskCanvas)\r\n this.element.appendChild(bottom_panel)\r\n\r\n bottom_panel.appendChild(clearButton)\r\n bottom_panel.appendChild(this.saveButton)\r\n bottom_panel.appendChild(cancelButton)\r\n bottom_panel.appendChild(this.brush_size_slider)\r\n bottom_panel.appendChild(this.brush_opacity_slider)\r\n bottom_panel.appendChild(this.colorButton)\r\n\r\n imgCanvas.style.position = 'absolute'\r\n maskCanvas.style.position = 'absolute'\r\n\r\n imgCanvas.style.top = '200'\r\n imgCanvas.style.left = '0'\r\n\r\n maskCanvas.style.top = imgCanvas.style.top\r\n maskCanvas.style.left = imgCanvas.style.left\r\n\r\n const maskCanvasStyle = this.getMaskCanvasStyle()\r\n maskCanvas.style.mixBlendMode = maskCanvasStyle.mixBlendMode\r\n maskCanvas.style.opacity = maskCanvasStyle.opacity.toString()\r\n }\r\n\r\n async show() {\r\n this.zoom_ratio = 1.0\r\n this.pan_x = 0\r\n this.pan_y = 0\r\n\r\n if (!this.is_layout_created) {\r\n // layout\r\n const imgCanvas = document.createElement('canvas')\r\n const maskCanvas = document.createElement('canvas')\r\n\r\n imgCanvas.id = 'imageCanvas'\r\n maskCanvas.id = 'maskCanvas'\r\n\r\n this.setlayout(imgCanvas, maskCanvas)\r\n\r\n // prepare content\r\n this.imgCanvas = imgCanvas\r\n this.maskCanvas = maskCanvas\r\n this.maskCtx = maskCanvas.getContext('2d', { willReadFrequently: true })\r\n\r\n this.setEventHandler(maskCanvas)\r\n\r\n this.is_layout_created = true\r\n\r\n // replacement of onClose hook since close is not real close\r\n const self = this\r\n const observer = new MutationObserver(function (mutations) {\r\n mutations.forEach(function (mutation) {\r\n if (\r\n mutation.type === 'attributes' &&\r\n mutation.attributeName === 'style'\r\n ) {\r\n if (\r\n self.last_display_style &&\r\n self.last_display_style != 'none' &&\r\n self.element.style.display == 'none'\r\n ) {\r\n self.brush.style.display = 'none'\r\n ComfyApp.onClipspaceEditorClosed()\r\n }\r\n\r\n self.last_display_style = self.element.style.display\r\n }\r\n })\r\n })\r\n\r\n const config = { attributes: true }\r\n observer.observe(this.element, config)\r\n }\r\n\r\n // The keydown event needs to be reconfigured when closing the dialog as it gets removed.\r\n document.addEventListener('keydown', MaskEditorDialog.handleKeyDown)\r\n\r\n if (ComfyApp.clipspace_return_node) {\r\n this.saveButton.innerText = 'Save to node'\r\n } else {\r\n this.saveButton.innerText = 'Save'\r\n }\r\n this.saveButton.disabled = false\r\n\r\n this.element.style.display = 'block'\r\n this.element.style.width = '85%'\r\n this.element.style.margin = '0 7.5%'\r\n this.element.style.height = '100vh'\r\n this.element.style.top = '50%'\r\n this.element.style.left = '42%'\r\n this.element.style.zIndex = '8888' // NOTE: alert dialog must be high priority.\r\n\r\n await this.setImages(this.imgCanvas)\r\n\r\n this.is_visible = true\r\n }\r\n\r\n isOpened() {\r\n return this.element.style.display == 'block'\r\n }\r\n\r\n invalidateCanvas(orig_image, mask_image) {\r\n this.imgCanvas.width = orig_image.width\r\n this.imgCanvas.height = orig_image.height\r\n\r\n this.maskCanvas.width = orig_image.width\r\n this.maskCanvas.height = orig_image.height\r\n\r\n let imgCtx = this.imgCanvas.getContext('2d', { willReadFrequently: true })\r\n let maskCtx = this.maskCanvas.getContext('2d', {\r\n willReadFrequently: true\r\n })\r\n\r\n imgCtx.drawImage(orig_image, 0, 0, orig_image.width, orig_image.height)\r\n prepare_mask(mask_image, this.maskCanvas, maskCtx, this.getMaskColor())\r\n }\r\n\r\n async setImages(imgCanvas) {\r\n let self = this\r\n\r\n const imgCtx = imgCanvas.getContext('2d', { willReadFrequently: true })\r\n const maskCtx = this.maskCtx\r\n const maskCanvas = this.maskCanvas\r\n\r\n imgCtx.clearRect(0, 0, this.imgCanvas.width, this.imgCanvas.height)\r\n maskCtx.clearRect(0, 0, this.maskCanvas.width, this.maskCanvas.height)\r\n\r\n // image load\r\n const filepath = ComfyApp.clipspace.images\r\n\r\n const alpha_url = new URL(\r\n ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']].src\r\n )\r\n alpha_url.searchParams.delete('channel')\r\n alpha_url.searchParams.delete('preview')\r\n alpha_url.searchParams.set('channel', 'a')\r\n let mask_image = await loadImage(alpha_url)\r\n\r\n // original image load\r\n const rgb_url = new URL(\r\n ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']].src\r\n )\r\n rgb_url.searchParams.delete('channel')\r\n rgb_url.searchParams.set('channel', 'rgb')\r\n this.image = new Image()\r\n this.image.onload = function () {\r\n maskCanvas.width = self.image.width\r\n maskCanvas.height = self.image.height\r\n\r\n self.invalidateCanvas(self.image, mask_image)\r\n self.initializeCanvasPanZoom()\r\n }\r\n this.image.src = rgb_url.toString()\r\n }\r\n\r\n initializeCanvasPanZoom() {\r\n // set initialize\r\n let drawWidth = this.image.width\r\n let drawHeight = this.image.height\r\n\r\n let width = this.element.clientWidth\r\n let height = this.element.clientHeight\r\n\r\n if (this.image.width > width) {\r\n drawWidth = width\r\n drawHeight = (drawWidth / this.image.width) * this.image.height\r\n }\r\n\r\n if (drawHeight > height) {\r\n drawHeight = height\r\n drawWidth = (drawHeight / this.image.height) * this.image.width\r\n }\r\n\r\n this.zoom_ratio = drawWidth / this.image.width\r\n\r\n const canvasX = (width - drawWidth) / 2\r\n const canvasY = (height - drawHeight) / 2\r\n this.pan_x = canvasX\r\n this.pan_y = canvasY\r\n\r\n this.invalidatePanZoom()\r\n }\r\n\r\n invalidatePanZoom() {\r\n let raw_width = this.image.width * this.zoom_ratio\r\n let raw_height = this.image.height * this.zoom_ratio\r\n\r\n if (this.pan_x + raw_width < 10) {\r\n this.pan_x = 10 - raw_width\r\n }\r\n\r\n if (this.pan_y + raw_height < 10) {\r\n this.pan_y = 10 - raw_height\r\n }\r\n\r\n let width = `${raw_width}px`\r\n let height = `${raw_height}px`\r\n\r\n let left = `${this.pan_x}px`\r\n let top = `${this.pan_y}px`\r\n\r\n this.maskCanvas.style.width = width\r\n this.maskCanvas.style.height = height\r\n this.maskCanvas.style.left = left\r\n this.maskCanvas.style.top = top\r\n\r\n this.imgCanvas.style.width = width\r\n this.imgCanvas.style.height = height\r\n this.imgCanvas.style.left = left\r\n this.imgCanvas.style.top = top\r\n }\r\n\r\n setEventHandler(maskCanvas) {\r\n const self = this\r\n\r\n if (!this.handler_registered) {\r\n maskCanvas.addEventListener('contextmenu', (event) => {\r\n event.preventDefault()\r\n })\r\n\r\n this.element.addEventListener('wheel', (event) =>\r\n this.handleWheelEvent(self, event)\r\n )\r\n this.element.addEventListener('pointermove', (event) =>\r\n this.pointMoveEvent(self, event)\r\n )\r\n this.element.addEventListener('touchmove', (event) =>\r\n this.pointMoveEvent(self, event)\r\n )\r\n\r\n this.element.addEventListener('dragstart', (event) => {\r\n if (event.ctrlKey) {\r\n event.preventDefault()\r\n }\r\n })\r\n\r\n maskCanvas.addEventListener('pointerdown', (event) =>\r\n this.handlePointerDown(self, event)\r\n )\r\n maskCanvas.addEventListener('pointermove', (event) =>\r\n this.draw_move(self, event)\r\n )\r\n maskCanvas.addEventListener('touchmove', (event) =>\r\n this.draw_move(self, event)\r\n )\r\n maskCanvas.addEventListener('pointerover', (event) => {\r\n this.brush.style.display = 'block'\r\n })\r\n maskCanvas.addEventListener('pointerleave', (event) => {\r\n this.brush.style.display = 'none'\r\n })\r\n\r\n document.addEventListener('pointerup', MaskEditorDialog.handlePointerUp)\r\n\r\n this.handler_registered = true\r\n }\r\n }\r\n\r\n getMaskCanvasStyle() {\r\n if (this.brush_color_mode === 'negative') {\r\n return {\r\n mixBlendMode: 'difference',\r\n opacity: '1'\r\n }\r\n } else {\r\n return {\r\n mixBlendMode: 'initial',\r\n opacity: this.brush_opacity\r\n }\r\n }\r\n }\r\n\r\n getMaskColor() {\r\n if (this.brush_color_mode === 'black') {\r\n return { r: 0, g: 0, b: 0 }\r\n }\r\n if (this.brush_color_mode === 'white') {\r\n return { r: 255, g: 255, b: 255 }\r\n }\r\n if (this.brush_color_mode === 'negative') {\r\n // negative effect only works with white color\r\n return { r: 255, g: 255, b: 255 }\r\n }\r\n\r\n return { r: 0, g: 0, b: 0 }\r\n }\r\n\r\n getMaskFillStyle() {\r\n const maskColor = this.getMaskColor()\r\n\r\n return 'rgb(' + maskColor.r + ',' + maskColor.g + ',' + maskColor.b + ')'\r\n }\r\n\r\n getColorButtonText() {\r\n let colorCaption = 'unknown'\r\n\r\n if (this.brush_color_mode === 'black') {\r\n colorCaption = 'black'\r\n } else if (this.brush_color_mode === 'white') {\r\n colorCaption = 'white'\r\n } else if (this.brush_color_mode === 'negative') {\r\n colorCaption = 'negative'\r\n }\r\n\r\n return 'Color: ' + colorCaption\r\n }\r\n\r\n updateWhenBrushColorModeChanged() {\r\n this.colorButton.innerText = this.getColorButtonText()\r\n\r\n // update mask canvas css styles\r\n\r\n const maskCanvasStyle = this.getMaskCanvasStyle()\r\n this.maskCanvas.style.mixBlendMode = maskCanvasStyle.mixBlendMode\r\n this.maskCanvas.style.opacity = maskCanvasStyle.opacity.toString()\r\n\r\n // update mask canvas rgb colors\r\n\r\n const maskColor = this.getMaskColor()\r\n\r\n const maskData = this.maskCtx.getImageData(\r\n 0,\r\n 0,\r\n this.maskCanvas.width,\r\n this.maskCanvas.height\r\n )\r\n\r\n for (let i = 0; i < maskData.data.length; i += 4) {\r\n maskData.data[i] = maskColor.r\r\n maskData.data[i + 1] = maskColor.g\r\n maskData.data[i + 2] = maskColor.b\r\n }\r\n\r\n this.maskCtx.putImageData(maskData, 0, 0)\r\n }\r\n\r\n brush_opacity = 0.7\r\n brush_size = 10\r\n brush_color_mode = 'black'\r\n drawing_mode = false\r\n lastx = -1\r\n lasty = -1\r\n lasttime = 0\r\n\r\n static handleKeyDown(event) {\r\n const self = MaskEditorDialog.instance\r\n if (event.key === ']') {\r\n self.brush_size = Math.min(self.brush_size + 2, 100)\r\n self.brush_slider_input.value = self.brush_size\r\n } else if (event.key === '[') {\r\n self.brush_size = Math.max(self.brush_size - 2, 1)\r\n self.brush_slider_input.value = self.brush_size\r\n } else if (event.key === 'Enter') {\r\n self.save()\r\n }\r\n\r\n self.updateBrushPreview(self)\r\n }\r\n\r\n static handlePointerUp(event) {\r\n event.preventDefault()\r\n\r\n this.mousedown_x = null\r\n this.mousedown_y = null\r\n\r\n MaskEditorDialog.instance.drawing_mode = false\r\n }\r\n\r\n updateBrushPreview(self) {\r\n const brush = self.brush\r\n\r\n var centerX = self.cursorX\r\n var centerY = self.cursorY\r\n\r\n brush.style.width = self.brush_size * 2 * this.zoom_ratio + 'px'\r\n brush.style.height = self.brush_size * 2 * this.zoom_ratio + 'px'\r\n brush.style.left = centerX - self.brush_size * this.zoom_ratio + 'px'\r\n brush.style.top = centerY - self.brush_size * this.zoom_ratio + 'px'\r\n }\r\n\r\n handleWheelEvent(self, event) {\r\n event.preventDefault()\r\n\r\n if (event.ctrlKey) {\r\n // zoom canvas\r\n if (event.deltaY < 0) {\r\n this.zoom_ratio = Math.min(10.0, this.zoom_ratio + 0.2)\r\n } else {\r\n this.zoom_ratio = Math.max(0.2, this.zoom_ratio - 0.2)\r\n }\r\n\r\n this.invalidatePanZoom()\r\n } else {\r\n // adjust brush size\r\n if (event.deltaY < 0) this.brush_size = Math.min(this.brush_size + 2, 100)\r\n else this.brush_size = Math.max(this.brush_size - 2, 1)\r\n\r\n this.brush_slider_input.value = this.brush_size.toString()\r\n\r\n this.updateBrushPreview(this)\r\n }\r\n }\r\n\r\n pointMoveEvent(self, event) {\r\n this.cursorX = event.pageX\r\n this.cursorY = event.pageY\r\n\r\n self.updateBrushPreview(self)\r\n\r\n if (event.ctrlKey) {\r\n event.preventDefault()\r\n self.pan_move(self, event)\r\n }\r\n\r\n let left_button_down =\r\n (window.TouchEvent && event instanceof TouchEvent) || event.buttons == 1\r\n\r\n if (event.shiftKey && left_button_down) {\r\n self.drawing_mode = false\r\n\r\n const y = event.clientY\r\n let delta = (self.zoom_lasty - y) * 0.005\r\n self.zoom_ratio = Math.max(\r\n Math.min(10.0, self.last_zoom_ratio - delta),\r\n 0.2\r\n )\r\n\r\n this.invalidatePanZoom()\r\n return\r\n }\r\n }\r\n\r\n pan_move(self, event) {\r\n if (event.buttons == 1) {\r\n if (MaskEditorDialog.mousedown_x) {\r\n let deltaX = MaskEditorDialog.mousedown_x - event.clientX\r\n let deltaY = MaskEditorDialog.mousedown_y - event.clientY\r\n\r\n self.pan_x = this.mousedown_pan_x - deltaX\r\n self.pan_y = this.mousedown_pan_y - deltaY\r\n\r\n self.invalidatePanZoom()\r\n }\r\n }\r\n }\r\n\r\n draw_move(self, event) {\r\n if (event.ctrlKey || event.shiftKey) {\r\n return\r\n }\r\n\r\n event.preventDefault()\r\n\r\n this.cursorX = event.pageX\r\n this.cursorY = event.pageY\r\n\r\n self.updateBrushPreview(self)\r\n\r\n let left_button_down =\r\n (window.TouchEvent && event instanceof TouchEvent) || event.buttons == 1\r\n let right_button_down = [2, 5, 32].includes(event.buttons)\r\n\r\n if (!event.altKey && left_button_down) {\r\n var diff = performance.now() - self.lasttime\r\n\r\n const maskRect = self.maskCanvas.getBoundingClientRect()\r\n\r\n var x = event.offsetX\r\n var y = event.offsetY\r\n\r\n if (event.offsetX == null) {\r\n x = event.targetTouches[0].clientX - maskRect.left\r\n }\r\n\r\n if (event.offsetY == null) {\r\n y = event.targetTouches[0].clientY - maskRect.top\r\n }\r\n\r\n x /= self.zoom_ratio\r\n y /= self.zoom_ratio\r\n\r\n var brush_size = this.brush_size\r\n if (event instanceof PointerEvent && event.pointerType == 'pen') {\r\n brush_size *= event.pressure\r\n this.last_pressure = event.pressure\r\n } else if (\r\n window.TouchEvent &&\r\n event instanceof TouchEvent &&\r\n diff < 20\r\n ) {\r\n // The firing interval of PointerEvents in Pen is unreliable, so it is supplemented by TouchEvents.\r\n brush_size *= this.last_pressure\r\n } else {\r\n brush_size = this.brush_size\r\n }\r\n\r\n if (diff > 20 && !this.drawing_mode)\r\n requestAnimationFrame(() => {\r\n self.maskCtx.beginPath()\r\n self.maskCtx.fillStyle = this.getMaskFillStyle()\r\n self.maskCtx.globalCompositeOperation = 'source-over'\r\n self.maskCtx.arc(x, y, brush_size, 0, Math.PI * 2, false)\r\n self.maskCtx.fill()\r\n self.lastx = x\r\n self.lasty = y\r\n })\r\n else\r\n requestAnimationFrame(() => {\r\n self.maskCtx.beginPath()\r\n self.maskCtx.fillStyle = this.getMaskFillStyle()\r\n self.maskCtx.globalCompositeOperation = 'source-over'\r\n\r\n var dx = x - self.lastx\r\n var dy = y - self.lasty\r\n\r\n var distance = Math.sqrt(dx * dx + dy * dy)\r\n var directionX = dx / distance\r\n var directionY = dy / distance\r\n\r\n for (var i = 0; i < distance; i += 5) {\r\n var px = self.lastx + directionX * i\r\n var py = self.lasty + directionY * i\r\n self.maskCtx.arc(px, py, brush_size, 0, Math.PI * 2, false)\r\n self.maskCtx.fill()\r\n }\r\n self.lastx = x\r\n self.lasty = y\r\n })\r\n\r\n self.lasttime = performance.now()\r\n } else if ((event.altKey && left_button_down) || right_button_down) {\r\n const maskRect = self.maskCanvas.getBoundingClientRect()\r\n const x =\r\n (event.offsetX || event.targetTouches[0].clientX - maskRect.left) /\r\n self.zoom_ratio\r\n const y =\r\n (event.offsetY || event.targetTouches[0].clientY - maskRect.top) /\r\n self.zoom_ratio\r\n\r\n var brush_size = this.brush_size\r\n if (event instanceof PointerEvent && event.pointerType == 'pen') {\r\n brush_size *= event.pressure\r\n this.last_pressure = event.pressure\r\n } else if (\r\n window.TouchEvent &&\r\n event instanceof TouchEvent &&\r\n diff < 20\r\n ) {\r\n brush_size *= this.last_pressure\r\n } else {\r\n brush_size = this.brush_size\r\n }\r\n\r\n if (diff > 20 && !this.drawing_mode)\r\n // cannot tracking drawing_mode for touch event\r\n requestAnimationFrame(() => {\r\n self.maskCtx.beginPath()\r\n self.maskCtx.globalCompositeOperation = 'destination-out'\r\n self.maskCtx.arc(x, y, brush_size, 0, Math.PI * 2, false)\r\n self.maskCtx.fill()\r\n self.lastx = x\r\n self.lasty = y\r\n })\r\n else\r\n requestAnimationFrame(() => {\r\n self.maskCtx.beginPath()\r\n self.maskCtx.globalCompositeOperation = 'destination-out'\r\n\r\n var dx = x - self.lastx\r\n var dy = y - self.lasty\r\n\r\n var distance = Math.sqrt(dx * dx + dy * dy)\r\n var directionX = dx / distance\r\n var directionY = dy / distance\r\n\r\n for (var i = 0; i < distance; i += 5) {\r\n var px = self.lastx + directionX * i\r\n var py = self.lasty + directionY * i\r\n self.maskCtx.arc(px, py, brush_size, 0, Math.PI * 2, false)\r\n self.maskCtx.fill()\r\n }\r\n self.lastx = x\r\n self.lasty = y\r\n })\r\n\r\n self.lasttime = performance.now()\r\n }\r\n }\r\n\r\n handlePointerDown(self, event) {\r\n if (event.ctrlKey) {\r\n if (event.buttons == 1) {\r\n MaskEditorDialog.mousedown_x = event.clientX\r\n MaskEditorDialog.mousedown_y = event.clientY\r\n\r\n this.mousedown_pan_x = this.pan_x\r\n this.mousedown_pan_y = this.pan_y\r\n }\r\n return\r\n }\r\n\r\n var brush_size = this.brush_size\r\n if (event instanceof PointerEvent && event.pointerType == 'pen') {\r\n brush_size *= event.pressure\r\n this.last_pressure = event.pressure\r\n }\r\n\r\n if ([0, 2, 5].includes(event.button)) {\r\n self.drawing_mode = true\r\n\r\n event.preventDefault()\r\n\r\n if (event.shiftKey) {\r\n self.zoom_lasty = event.clientY\r\n self.last_zoom_ratio = self.zoom_ratio\r\n return\r\n }\r\n\r\n const maskRect = self.maskCanvas.getBoundingClientRect()\r\n const x =\r\n (event.offsetX || event.targetTouches[0].clientX - maskRect.left) /\r\n self.zoom_ratio\r\n const y =\r\n (event.offsetY || event.targetTouches[0].clientY - maskRect.top) /\r\n self.zoom_ratio\r\n\r\n self.maskCtx.beginPath()\r\n if (!event.altKey && event.button == 0) {\r\n self.maskCtx.fillStyle = this.getMaskFillStyle()\r\n self.maskCtx.globalCompositeOperation = 'source-over'\r\n } else {\r\n self.maskCtx.globalCompositeOperation = 'destination-out'\r\n }\r\n self.maskCtx.arc(x, y, brush_size, 0, Math.PI * 2, false)\r\n self.maskCtx.fill()\r\n self.lastx = x\r\n self.lasty = y\r\n self.lasttime = performance.now()\r\n }\r\n }\r\n\r\n async save() {\r\n const backupCanvas = document.createElement('canvas')\r\n const backupCtx = backupCanvas.getContext('2d', {\r\n willReadFrequently: true\r\n })\r\n backupCanvas.width = this.image.width\r\n backupCanvas.height = this.image.height\r\n\r\n backupCtx.clearRect(0, 0, backupCanvas.width, backupCanvas.height)\r\n backupCtx.drawImage(\r\n this.maskCanvas,\r\n 0,\r\n 0,\r\n this.maskCanvas.width,\r\n this.maskCanvas.height,\r\n 0,\r\n 0,\r\n backupCanvas.width,\r\n backupCanvas.height\r\n )\r\n\r\n // paste mask data into alpha channel\r\n const backupData = backupCtx.getImageData(\r\n 0,\r\n 0,\r\n backupCanvas.width,\r\n backupCanvas.height\r\n )\r\n\r\n // refine mask image\r\n for (let i = 0; i < backupData.data.length; i += 4) {\r\n if (backupData.data[i + 3] == 255) backupData.data[i + 3] = 0\r\n else backupData.data[i + 3] = 255\r\n\r\n backupData.data[i] = 0\r\n backupData.data[i + 1] = 0\r\n backupData.data[i + 2] = 0\r\n }\r\n\r\n backupCtx.globalCompositeOperation = 'source-over'\r\n backupCtx.putImageData(backupData, 0, 0)\r\n\r\n const formData = new FormData()\r\n const filename = 'clipspace-mask-' + performance.now() + '.png'\r\n\r\n const item = {\r\n filename: filename,\r\n subfolder: 'clipspace',\r\n type: 'input'\r\n }\r\n\r\n if (ComfyApp.clipspace.images) ComfyApp.clipspace.images[0] = item\r\n\r\n if (ComfyApp.clipspace.widgets) {\r\n const index = ComfyApp.clipspace.widgets.findIndex(\r\n (obj) => obj.name === 'image'\r\n )\r\n\r\n if (index >= 0) ComfyApp.clipspace.widgets[index].value = item\r\n }\r\n\r\n const dataURL = backupCanvas.toDataURL()\r\n const blob = dataURLToBlob(dataURL)\r\n\r\n let original_url = new URL(this.image.src)\r\n\r\n type Ref = { filename: string; subfolder?: string; type?: string }\r\n\r\n const original_ref: Ref = {\r\n filename: original_url.searchParams.get('filename')\r\n }\r\n\r\n let original_subfolder = original_url.searchParams.get('subfolder')\r\n if (original_subfolder) original_ref.subfolder = original_subfolder\r\n\r\n let original_type = original_url.searchParams.get('type')\r\n if (original_type) original_ref.type = original_type\r\n\r\n formData.append('image', blob, filename)\r\n formData.append('original_ref', JSON.stringify(original_ref))\r\n formData.append('type', 'input')\r\n formData.append('subfolder', 'clipspace')\r\n\r\n this.saveButton.innerText = 'Saving...'\r\n this.saveButton.disabled = true\r\n await uploadMask(item, formData)\r\n ComfyApp.onClipspaceEditorSave()\r\n this.close()\r\n }\r\n}\r\n\r\napp.registerExtension({\r\n name: 'Comfy.MaskEditor',\r\n init(app) {\r\n ComfyApp.open_maskeditor = function () {\r\n const dlg = MaskEditorDialog.getInstance()\r\n if (!dlg.isOpened()) {\r\n dlg.show()\r\n }\r\n }\r\n\r\n const context_predicate = () =>\r\n ComfyApp.clipspace &&\r\n ComfyApp.clipspace.imgs &&\r\n ComfyApp.clipspace.imgs.length > 0\r\n ClipspaceDialog.registerButton(\r\n 'MaskEditor',\r\n context_predicate,\r\n ComfyApp.open_maskeditor\r\n )\r\n }\r\n})\r\n","import { app } from '../../scripts/app'\r\nimport { api } from '../../scripts/api'\r\nimport { ComfyDialog, $el } from '../../scripts/ui'\r\nimport { GroupNodeConfig, GroupNodeHandler } from './groupNode'\r\nimport { LGraphCanvas } from '@comfyorg/litegraph'\r\n\r\n// Adds the ability to save and add multiple nodes as a template\r\n// To save:\r\n// Select multiple nodes (ctrl + drag to select a region or ctrl+click individual nodes)\r\n// Right click the canvas\r\n// Save Node Template -> give it a name\r\n//\r\n// To add:\r\n// Right click the canvas\r\n// Node templates -> click the one to add\r\n//\r\n// To delete/rename:\r\n// Right click the canvas\r\n// Node templates -> Manage\r\n//\r\n// To rearrange:\r\n// Open the manage dialog and Drag and drop elements using the \"Name:\" label as handle\r\n\r\nconst id = 'Comfy.NodeTemplates'\r\nconst file = 'comfy.templates.json'\r\n\r\nclass ManageTemplates extends ComfyDialog {\r\n templates: any[]\r\n draggedEl: HTMLElement | null\r\n saveVisualCue: number | null\r\n emptyImg: HTMLImageElement\r\n importInput: HTMLInputElement\r\n\r\n constructor() {\r\n super()\r\n this.load().then((v) => {\r\n this.templates = v\r\n })\r\n\r\n this.element.classList.add('comfy-manage-templates')\r\n this.draggedEl = null\r\n this.saveVisualCue = null\r\n this.emptyImg = new Image()\r\n this.emptyImg.src =\r\n 'data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='\r\n\r\n this.importInput = $el('input', {\r\n type: 'file',\r\n accept: '.json',\r\n multiple: true,\r\n style: { display: 'none' },\r\n parent: document.body,\r\n onchange: () => this.importAll()\r\n }) as HTMLInputElement\r\n }\r\n\r\n createButtons() {\r\n const btns = super.createButtons()\r\n btns[0].textContent = 'Close'\r\n btns[0].onclick = (e) => {\r\n clearTimeout(this.saveVisualCue)\r\n this.close()\r\n }\r\n btns.unshift(\r\n $el('button', {\r\n type: 'button',\r\n textContent: 'Export',\r\n onclick: () => this.exportAll()\r\n })\r\n )\r\n btns.unshift(\r\n $el('button', {\r\n type: 'button',\r\n textContent: 'Import',\r\n onclick: () => {\r\n this.importInput.click()\r\n }\r\n })\r\n )\r\n return btns\r\n }\r\n\r\n async load() {\r\n let templates = []\r\n if (app.storageLocation === 'server') {\r\n if (app.isNewUserSession) {\r\n // New user so migrate existing templates\r\n const json = localStorage.getItem(id)\r\n if (json) {\r\n templates = JSON.parse(json)\r\n }\r\n await api.storeUserData(file, json, { stringify: false })\r\n } else {\r\n const res = await api.getUserData(file)\r\n if (res.status === 200) {\r\n try {\r\n templates = await res.json()\r\n } catch (error) {}\r\n } else if (res.status !== 404) {\r\n console.error(res.status + ' ' + res.statusText)\r\n }\r\n }\r\n } else {\r\n const json = localStorage.getItem(id)\r\n if (json) {\r\n templates = JSON.parse(json)\r\n }\r\n }\r\n\r\n return templates ?? []\r\n }\r\n\r\n async store() {\r\n if (app.storageLocation === 'server') {\r\n const templates = JSON.stringify(this.templates, undefined, 4)\r\n localStorage.setItem(id, templates) // Backwards compatibility\r\n try {\r\n await api.storeUserData(file, templates, { stringify: false })\r\n } catch (error) {\r\n console.error(error)\r\n alert(error.message)\r\n }\r\n } else {\r\n localStorage.setItem(id, JSON.stringify(this.templates))\r\n }\r\n }\r\n\r\n async importAll() {\r\n for (const file of this.importInput.files) {\r\n if (file.type === 'application/json' || file.name.endsWith('.json')) {\r\n const reader = new FileReader()\r\n reader.onload = async () => {\r\n const importFile = JSON.parse(reader.result as string)\r\n if (importFile?.templates) {\r\n for (const template of importFile.templates) {\r\n if (template?.name && template?.data) {\r\n this.templates.push(template)\r\n }\r\n }\r\n await this.store()\r\n }\r\n }\r\n await reader.readAsText(file)\r\n }\r\n }\r\n\r\n this.importInput.value = null\r\n\r\n this.close()\r\n }\r\n\r\n exportAll() {\r\n if (this.templates.length == 0) {\r\n alert('No templates to export.')\r\n return\r\n }\r\n\r\n const json = JSON.stringify({ templates: this.templates }, null, 2) // convert the data to a JSON string\r\n const blob = new Blob([json], { type: 'application/json' })\r\n const url = URL.createObjectURL(blob)\r\n const a = $el('a', {\r\n href: url,\r\n download: 'node_templates.json',\r\n style: { display: 'none' },\r\n parent: document.body\r\n })\r\n a.click()\r\n setTimeout(function () {\r\n a.remove()\r\n window.URL.revokeObjectURL(url)\r\n }, 0)\r\n }\r\n\r\n show() {\r\n // Show list of template names + delete button\r\n super.show(\r\n $el(\r\n 'div',\r\n {},\r\n this.templates.flatMap((t, i) => {\r\n let nameInput\r\n return [\r\n $el(\r\n 'div',\r\n {\r\n dataset: { id: i.toString() },\r\n className: 'templateManagerRow',\r\n style: {\r\n display: 'grid',\r\n gridTemplateColumns: '1fr auto',\r\n border: '1px dashed transparent',\r\n gap: '5px',\r\n backgroundColor: 'var(--comfy-menu-bg)'\r\n },\r\n ondragstart: (e) => {\r\n this.draggedEl = e.currentTarget\r\n e.currentTarget.style.opacity = '0.6'\r\n e.currentTarget.style.border = '1px dashed yellow'\r\n e.dataTransfer.effectAllowed = 'move'\r\n e.dataTransfer.setDragImage(this.emptyImg, 0, 0)\r\n },\r\n ondragend: (e) => {\r\n e.target.style.opacity = '1'\r\n e.currentTarget.style.border = '1px dashed transparent'\r\n e.currentTarget.removeAttribute('draggable')\r\n\r\n // rearrange the elements\r\n this.element\r\n .querySelectorAll('.templateManagerRow')\r\n .forEach((el: HTMLElement, i) => {\r\n var prev_i = Number.parseInt(el.dataset.id)\r\n\r\n if (el == this.draggedEl && prev_i != i) {\r\n this.templates.splice(\r\n i,\r\n 0,\r\n this.templates.splice(prev_i, 1)[0]\r\n )\r\n }\r\n el.dataset.id = i.toString()\r\n })\r\n this.store()\r\n },\r\n ondragover: (e) => {\r\n e.preventDefault()\r\n if (e.currentTarget == this.draggedEl) return\r\n\r\n let rect = e.currentTarget.getBoundingClientRect()\r\n if (e.clientY > rect.top + rect.height / 2) {\r\n e.currentTarget.parentNode.insertBefore(\r\n this.draggedEl,\r\n e.currentTarget.nextSibling\r\n )\r\n } else {\r\n e.currentTarget.parentNode.insertBefore(\r\n this.draggedEl,\r\n e.currentTarget\r\n )\r\n }\r\n }\r\n },\r\n [\r\n $el(\r\n 'label',\r\n {\r\n textContent: 'Name: ',\r\n style: {\r\n cursor: 'grab'\r\n },\r\n onmousedown: (e) => {\r\n // enable dragging only from the label\r\n if (e.target.localName == 'label')\r\n e.currentTarget.parentNode.draggable = 'true'\r\n }\r\n },\r\n [\r\n $el('input', {\r\n value: t.name,\r\n dataset: { name: t.name },\r\n style: {\r\n transitionProperty: 'background-color',\r\n transitionDuration: '0s'\r\n },\r\n onchange: (e) => {\r\n clearTimeout(this.saveVisualCue)\r\n var el = e.target\r\n var row = el.parentNode.parentNode\r\n this.templates[row.dataset.id].name =\r\n el.value.trim() || 'untitled'\r\n this.store()\r\n el.style.backgroundColor = 'rgb(40, 95, 40)'\r\n el.style.transitionDuration = '0s'\r\n // @ts-expect-error\r\n // In browser env the return value is number.\r\n this.saveVisualCue = setTimeout(function () {\r\n el.style.transitionDuration = '.7s'\r\n el.style.backgroundColor = 'var(--comfy-input-bg)'\r\n }, 15)\r\n },\r\n onkeypress: (e) => {\r\n var el = e.target\r\n clearTimeout(this.saveVisualCue)\r\n el.style.transitionDuration = '0s'\r\n el.style.backgroundColor = 'var(--comfy-input-bg)'\r\n },\r\n $: (el) => (nameInput = el)\r\n })\r\n ]\r\n ),\r\n $el('div', {}, [\r\n $el('button', {\r\n textContent: 'Export',\r\n style: {\r\n fontSize: '12px',\r\n fontWeight: 'normal'\r\n },\r\n onclick: (e) => {\r\n const json = JSON.stringify({ templates: [t] }, null, 2) // convert the data to a JSON string\r\n const blob = new Blob([json], {\r\n type: 'application/json'\r\n })\r\n const url = URL.createObjectURL(blob)\r\n const a = $el('a', {\r\n href: url,\r\n download: (nameInput.value || t.name) + '.json',\r\n style: { display: 'none' },\r\n parent: document.body\r\n })\r\n a.click()\r\n setTimeout(function () {\r\n a.remove()\r\n window.URL.revokeObjectURL(url)\r\n }, 0)\r\n }\r\n }),\r\n $el('button', {\r\n textContent: 'Delete',\r\n style: {\r\n fontSize: '12px',\r\n color: 'red',\r\n fontWeight: 'normal'\r\n },\r\n onclick: (e) => {\r\n const item = e.target.parentNode.parentNode\r\n item.parentNode.removeChild(item)\r\n this.templates.splice(item.dataset.id * 1, 1)\r\n this.store()\r\n // update the rows index, setTimeout ensures that the list is updated\r\n var that = this\r\n setTimeout(function () {\r\n that.element\r\n .querySelectorAll('.templateManagerRow')\r\n .forEach((el: HTMLElement, i) => {\r\n el.dataset.id = i.toString()\r\n })\r\n }, 0)\r\n }\r\n })\r\n ])\r\n ]\r\n )\r\n ]\r\n })\r\n )\r\n )\r\n }\r\n}\r\n\r\napp.registerExtension({\r\n name: id,\r\n setup() {\r\n const manage = new ManageTemplates()\r\n\r\n const clipboardAction = async (cb) => {\r\n // We use the clipboard functions but dont want to overwrite the current user clipboard\r\n // Restore it after we've run our callback\r\n const old = localStorage.getItem('litegrapheditor_clipboard')\r\n await cb()\r\n localStorage.setItem('litegrapheditor_clipboard', old)\r\n }\r\n\r\n const orig = LGraphCanvas.prototype.getCanvasMenuOptions\r\n LGraphCanvas.prototype.getCanvasMenuOptions = function () {\r\n const options = orig.apply(this, arguments)\r\n\r\n options.push(null)\r\n options.push({\r\n content: `Save Selected as Template`,\r\n disabled: !Object.keys(app.canvas.selected_nodes || {}).length,\r\n callback: () => {\r\n const name = prompt('Enter name')\r\n if (!name?.trim()) return\r\n\r\n clipboardAction(() => {\r\n app.canvas.copyToClipboard()\r\n let data = localStorage.getItem('litegrapheditor_clipboard')\r\n data = JSON.parse(data)\r\n const nodeIds = Object.keys(app.canvas.selected_nodes)\r\n for (let i = 0; i < nodeIds.length; i++) {\r\n const node = app.graph.getNodeById(Number.parseInt(nodeIds[i]))\r\n // @ts-expect-error\r\n const nodeData = node?.constructor.nodeData\r\n\r\n let groupData = GroupNodeHandler.getGroupData(node)\r\n if (groupData) {\r\n groupData = groupData.nodeData\r\n // @ts-expect-error\r\n if (!data.groupNodes) {\r\n // @ts-expect-error\r\n data.groupNodes = {}\r\n }\r\n // @ts-expect-error\r\n data.groupNodes[nodeData.name] = groupData\r\n // @ts-expect-error\r\n data.nodes[i].type = nodeData.name\r\n }\r\n }\r\n\r\n manage.templates.push({\r\n name,\r\n data: JSON.stringify(data)\r\n })\r\n manage.store()\r\n })\r\n }\r\n })\r\n\r\n // Map each template to a menu item\r\n const subItems = manage.templates.map((t) => {\r\n return {\r\n content: t.name,\r\n callback: () => {\r\n clipboardAction(async () => {\r\n const data = JSON.parse(t.data)\r\n await GroupNodeConfig.registerFromWorkflow(data.groupNodes, {})\r\n localStorage.setItem('litegrapheditor_clipboard', t.data)\r\n app.canvas.pasteFromClipboard()\r\n })\r\n }\r\n }\r\n })\r\n\r\n subItems.push(null, {\r\n content: 'Manage',\r\n callback: () => manage.show()\r\n })\r\n\r\n options.push({\r\n content: 'Node Templates',\r\n submenu: {\r\n options: subItems\r\n }\r\n })\r\n\r\n return options\r\n }\r\n }\r\n})\r\n","import { LiteGraph, LGraphCanvas } from '@comfyorg/litegraph'\r\nimport { app } from '../../scripts/app'\r\nimport { ComfyWidgets } from '../../scripts/widgets'\r\n// Node that add notes to your project\r\n\r\napp.registerExtension({\r\n name: 'Comfy.NoteNode',\r\n registerCustomNodes() {\r\n class NoteNode {\r\n static category: string\r\n\r\n color = LGraphCanvas.node_colors.yellow.color\r\n bgcolor = LGraphCanvas.node_colors.yellow.bgcolor\r\n groupcolor = LGraphCanvas.node_colors.yellow.groupcolor\r\n properties: { text: string }\r\n serialize_widgets: boolean\r\n isVirtualNode: boolean\r\n collapsable: boolean\r\n title_mode: number\r\n\r\n constructor() {\r\n if (!this.properties) {\r\n this.properties = { text: '' }\r\n }\r\n ComfyWidgets.STRING(\r\n // @ts-expect-error\r\n // Should we extends LGraphNode?\r\n this,\r\n '',\r\n ['', { default: this.properties.text, multiline: true }],\r\n app\r\n )\r\n\r\n this.serialize_widgets = true\r\n this.isVirtualNode = true\r\n }\r\n }\r\n\r\n // Load default visibility\r\n\r\n LiteGraph.registerNodeType(\r\n 'Note',\r\n // @ts-expect-error\r\n Object.assign(NoteNode, {\r\n title_mode: LiteGraph.NORMAL_TITLE,\r\n title: 'Note',\r\n collapsable: true\r\n })\r\n )\r\n\r\n NoteNode.category = 'utils'\r\n }\r\n})\r\n","import { app } from '../../scripts/app'\r\nimport { mergeIfValid, getWidgetConfig, setWidgetConfig } from './widgetInputs'\r\nimport { LiteGraph, LGraphCanvas, LGraphNode } from '@comfyorg/litegraph'\r\n\r\n// Node that allows you to redirect connections for cleaner graphs\r\n\r\napp.registerExtension({\r\n name: 'Comfy.RerouteNode',\r\n registerCustomNodes(app) {\r\n interface RerouteNode extends LGraphNode {\r\n __outputType?: string\r\n }\r\n\r\n class RerouteNode {\r\n static category: string | undefined\r\n static defaultVisibility = false\r\n\r\n constructor() {\r\n if (!this.properties) {\r\n this.properties = {}\r\n }\r\n this.properties.showOutputText = RerouteNode.defaultVisibility\r\n this.properties.horizontal = false\r\n\r\n this.addInput('', '*')\r\n this.addOutput(this.properties.showOutputText ? '*' : '', '*')\r\n\r\n this.onAfterGraphConfigured = function () {\r\n requestAnimationFrame(() => {\r\n this.onConnectionsChange(LiteGraph.INPUT, null, true, null)\r\n })\r\n }\r\n\r\n this.onConnectionsChange = function (\r\n type,\r\n index,\r\n connected,\r\n link_info\r\n ) {\r\n this.applyOrientation()\r\n\r\n // Prevent multiple connections to different types when we have no input\r\n if (connected && type === LiteGraph.OUTPUT) {\r\n // Ignore wildcard nodes as these will be updated to real types\r\n const types = new Set(\r\n this.outputs[0].links\r\n .map((l) => app.graph.links[l].type)\r\n .filter((t) => t !== '*')\r\n )\r\n if (types.size > 1) {\r\n const linksToDisconnect = []\r\n for (let i = 0; i < this.outputs[0].links.length - 1; i++) {\r\n const linkId = this.outputs[0].links[i]\r\n const link = app.graph.links[linkId]\r\n linksToDisconnect.push(link)\r\n }\r\n for (const link of linksToDisconnect) {\r\n const node = app.graph.getNodeById(link.target_id)\r\n node.disconnectInput(link.target_slot)\r\n }\r\n }\r\n }\r\n\r\n // Find root input\r\n let currentNode = this\r\n let updateNodes = []\r\n let inputType = null\r\n let inputNode = null\r\n while (currentNode) {\r\n updateNodes.unshift(currentNode)\r\n const linkId = currentNode.inputs[0].link\r\n if (linkId !== null) {\r\n const link = app.graph.links[linkId]\r\n if (!link) return\r\n const node = app.graph.getNodeById(link.origin_id)\r\n const type = node.constructor.type\r\n if (type === 'Reroute') {\r\n if (node === this) {\r\n // We've found a circle\r\n currentNode.disconnectInput(link.target_slot)\r\n currentNode = null\r\n } else {\r\n // Move the previous node\r\n currentNode = node\r\n }\r\n } else {\r\n // We've found the end\r\n inputNode = currentNode\r\n inputType = node.outputs[link.origin_slot]?.type ?? null\r\n break\r\n }\r\n } else {\r\n // This path has no input node\r\n currentNode = null\r\n break\r\n }\r\n }\r\n\r\n // Find all outputs\r\n const nodes = [this]\r\n let outputType = null\r\n while (nodes.length) {\r\n currentNode = nodes.pop()\r\n const outputs =\r\n (currentNode.outputs ? currentNode.outputs[0].links : []) || []\r\n if (outputs.length) {\r\n for (const linkId of outputs) {\r\n const link = app.graph.links[linkId]\r\n\r\n // When disconnecting sometimes the link is still registered\r\n if (!link) continue\r\n\r\n const node = app.graph.getNodeById(link.target_id)\r\n const type = node.constructor.type\r\n\r\n if (type === 'Reroute') {\r\n // Follow reroute nodes\r\n nodes.push(node)\r\n updateNodes.push(node)\r\n } else {\r\n // We've found an output\r\n const nodeOutType =\r\n node.inputs &&\r\n node.inputs[link?.target_slot] &&\r\n node.inputs[link.target_slot].type\r\n ? node.inputs[link.target_slot].type\r\n : null\r\n if (\r\n inputType &&\r\n inputType !== '*' &&\r\n nodeOutType !== inputType\r\n ) {\r\n // The output doesnt match our input so disconnect it\r\n node.disconnectInput(link.target_slot)\r\n } else {\r\n outputType = nodeOutType\r\n }\r\n }\r\n }\r\n } else {\r\n // No more outputs for this path\r\n }\r\n }\r\n\r\n const displayType = inputType || outputType || '*'\r\n const color = LGraphCanvas.link_type_colors[displayType]\r\n\r\n let widgetConfig\r\n let targetWidget\r\n let widgetType\r\n // Update the types of each node\r\n for (const node of updateNodes) {\r\n // If we dont have an input type we are always wildcard but we'll show the output type\r\n // This lets you change the output link to a different type and all nodes will update\r\n node.outputs[0].type = inputType || '*'\r\n node.__outputType = displayType\r\n node.outputs[0].name = node.properties.showOutputText\r\n ? displayType\r\n : ''\r\n node.size = node.computeSize()\r\n node.applyOrientation()\r\n\r\n for (const l of node.outputs[0].links || []) {\r\n const link = app.graph.links[l]\r\n if (link) {\r\n link.color = color\r\n\r\n if (app.configuringGraph) continue\r\n const targetNode = app.graph.getNodeById(link.target_id)\r\n const targetInput = targetNode.inputs?.[link.target_slot]\r\n if (targetInput?.widget) {\r\n const config = getWidgetConfig(targetInput)\r\n if (!widgetConfig) {\r\n widgetConfig = config[1] ?? {}\r\n widgetType = config[0]\r\n }\r\n if (!targetWidget) {\r\n targetWidget = targetNode.widgets?.find(\r\n (w) => w.name === targetInput.widget.name\r\n )\r\n }\r\n\r\n const merged = mergeIfValid(targetInput, [\r\n config[0],\r\n widgetConfig\r\n ])\r\n if (merged.customConfig) {\r\n widgetConfig = merged.customConfig\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n for (const node of updateNodes) {\r\n if (widgetConfig && outputType) {\r\n node.inputs[0].widget = { name: 'value' }\r\n setWidgetConfig(\r\n node.inputs[0],\r\n [widgetType ?? displayType, widgetConfig],\r\n targetWidget\r\n )\r\n } else {\r\n setWidgetConfig(node.inputs[0], null)\r\n }\r\n }\r\n\r\n if (inputNode) {\r\n const link = app.graph.links[inputNode.inputs[0].link]\r\n if (link) {\r\n link.color = color\r\n }\r\n }\r\n }\r\n\r\n this.clone = function () {\r\n const cloned = RerouteNode.prototype.clone.apply(this)\r\n cloned.removeOutput(0)\r\n cloned.addOutput(this.properties.showOutputText ? '*' : '', '*')\r\n cloned.size = cloned.computeSize()\r\n return cloned\r\n }\r\n\r\n // This node is purely frontend and does not impact the resulting prompt so should not be serialized\r\n this.isVirtualNode = true\r\n }\r\n\r\n getExtraMenuOptions(_, options) {\r\n options.unshift(\r\n {\r\n content:\r\n (this.properties.showOutputText ? 'Hide' : 'Show') + ' Type',\r\n callback: () => {\r\n this.properties.showOutputText = !this.properties.showOutputText\r\n if (this.properties.showOutputText) {\r\n this.outputs[0].name =\r\n this.__outputType || (this.outputs[0].type as string)\r\n } else {\r\n this.outputs[0].name = ''\r\n }\r\n this.size = this.computeSize()\r\n this.applyOrientation()\r\n app.graph.setDirtyCanvas(true, true)\r\n }\r\n },\r\n {\r\n content:\r\n (RerouteNode.defaultVisibility ? 'Hide' : 'Show') +\r\n ' Type By Default',\r\n callback: () => {\r\n RerouteNode.setDefaultTextVisibility(\r\n !RerouteNode.defaultVisibility\r\n )\r\n }\r\n },\r\n {\r\n // naming is inverted with respect to LiteGraphNode.horizontal\r\n // LiteGraphNode.horizontal == true means that\r\n // each slot in the inputs and outputs are laid out horizontally,\r\n // which is the opposite of the visual orientation of the inputs and outputs as a node\r\n content:\r\n 'Set ' + (this.properties.horizontal ? 'Horizontal' : 'Vertical'),\r\n callback: () => {\r\n this.properties.horizontal = !this.properties.horizontal\r\n this.applyOrientation()\r\n }\r\n }\r\n )\r\n }\r\n applyOrientation() {\r\n this.horizontal = this.properties.horizontal\r\n if (this.horizontal) {\r\n // we correct the input position, because LiteGraphNode.horizontal\r\n // doesn't account for title presence\r\n // which reroute nodes don't have\r\n this.inputs[0].pos = [this.size[0] / 2, 0]\r\n } else {\r\n delete this.inputs[0].pos\r\n }\r\n app.graph.setDirtyCanvas(true, true)\r\n }\r\n\r\n computeSize(): [number, number] {\r\n return [\r\n this.properties.showOutputText && this.outputs && this.outputs.length\r\n ? Math.max(\r\n 75,\r\n LiteGraph.NODE_TEXT_SIZE * this.outputs[0].name.length * 0.6 +\r\n 40\r\n )\r\n : 75,\r\n 26\r\n ]\r\n }\r\n\r\n static setDefaultTextVisibility(visible) {\r\n RerouteNode.defaultVisibility = visible\r\n if (visible) {\r\n localStorage['Comfy.RerouteNode.DefaultVisibility'] = 'true'\r\n } else {\r\n delete localStorage['Comfy.RerouteNode.DefaultVisibility']\r\n }\r\n }\r\n }\r\n\r\n // Load default visibility\r\n RerouteNode.setDefaultTextVisibility(\r\n !!localStorage['Comfy.RerouteNode.DefaultVisibility']\r\n )\r\n\r\n LiteGraph.registerNodeType(\r\n 'Reroute',\r\n Object.assign(RerouteNode, {\r\n title_mode: LiteGraph.NO_TITLE,\r\n title: 'Reroute',\r\n collapsable: false\r\n })\r\n )\r\n\r\n RerouteNode.category = 'utils'\r\n }\r\n})\r\n","import { app } from '../../scripts/app'\r\nimport { applyTextReplacements } from '../../scripts/utils'\r\n// Use widget values and dates in output filenames\r\n\r\napp.registerExtension({\r\n name: 'Comfy.SaveImageExtraOutput',\r\n async beforeRegisterNodeDef(nodeType, nodeData, app) {\r\n if (nodeData.name === 'SaveImage' || nodeData.name === 'SaveAnimatedWEBP') {\r\n const onNodeCreated = nodeType.prototype.onNodeCreated\r\n // When the SaveImage node is created we want to override the serialization of the output name widget to run our S&R\r\n nodeType.prototype.onNodeCreated = function () {\r\n const r = onNodeCreated\r\n ? onNodeCreated.apply(this, arguments)\r\n : undefined\r\n\r\n const widget = this.widgets.find((w) => w.name === 'filename_prefix')\r\n widget.serializeValue = () => {\r\n return applyTextReplacements(app, widget.value)\r\n }\r\n\r\n return r\r\n }\r\n } else {\r\n // When any other node is created add a property to alias the node\r\n const onNodeCreated = nodeType.prototype.onNodeCreated\r\n nodeType.prototype.onNodeCreated = function () {\r\n const r = onNodeCreated\r\n ? onNodeCreated.apply(this, arguments)\r\n : undefined\r\n\r\n if (!this.properties || !('Node name for S&R' in this.properties)) {\r\n this.addProperty('Node name for S&R', this.constructor.type, 'string')\r\n }\r\n\r\n return r\r\n }\r\n }\r\n }\r\n})\r\n","import { app } from '../../scripts/app'\r\nimport { LGraphCanvas, LiteGraph } from '@comfyorg/litegraph'\r\n\r\nlet touchZooming\r\nlet touchCount = 0\r\n\r\napp.registerExtension({\r\n name: 'Comfy.SimpleTouchSupport',\r\n setup() {\r\n let zoomPos\r\n let touchTime\r\n let lastTouch\r\n\r\n function getMultiTouchPos(e) {\r\n return Math.hypot(\r\n e.touches[0].clientX - e.touches[1].clientX,\r\n e.touches[0].clientY - e.touches[1].clientY\r\n )\r\n }\r\n\r\n app.canvasEl.addEventListener(\r\n 'touchstart',\r\n (e) => {\r\n touchCount++\r\n lastTouch = null\r\n if (e.touches?.length === 1) {\r\n // Store start time for press+hold for context menu\r\n touchTime = new Date()\r\n lastTouch = e.touches[0]\r\n } else {\r\n touchTime = null\r\n if (e.touches?.length === 2) {\r\n // Store center pos for zoom\r\n zoomPos = getMultiTouchPos(e)\r\n app.canvas.pointer_is_down = false\r\n }\r\n }\r\n },\r\n true\r\n )\r\n\r\n app.canvasEl.addEventListener('touchend', (e: TouchEvent) => {\r\n touchZooming = false\r\n touchCount = e.touches?.length ?? touchCount - 1\r\n if (touchTime && !e.touches?.length) {\r\n if (new Date().getTime() - touchTime > 600) {\r\n try {\r\n // hack to get litegraph to use this event\r\n e.constructor = CustomEvent\r\n } catch (error) {}\r\n // @ts-expect-error\r\n e.clientX = lastTouch.clientX\r\n // @ts-expect-error\r\n e.clientY = lastTouch.clientY\r\n\r\n app.canvas.pointer_is_down = true\r\n // @ts-expect-error\r\n app.canvas._mousedown_callback(e)\r\n }\r\n touchTime = null\r\n }\r\n })\r\n\r\n app.canvasEl.addEventListener(\r\n 'touchmove',\r\n (e) => {\r\n touchTime = null\r\n if (e.touches?.length === 2) {\r\n app.canvas.pointer_is_down = false\r\n touchZooming = true\r\n // @ts-expect-error\r\n LiteGraph.closeAllContextMenus()\r\n // @ts-expect-error\r\n app.canvas.search_box?.close()\r\n const newZoomPos = getMultiTouchPos(e)\r\n\r\n const midX = (e.touches[0].clientX + e.touches[1].clientX) / 2\r\n const midY = (e.touches[0].clientY + e.touches[1].clientY) / 2\r\n\r\n let scale = app.canvas.ds.scale\r\n const diff = zoomPos - newZoomPos\r\n if (diff > 0.5) {\r\n scale *= 1 / 1.07\r\n } else if (diff < -0.5) {\r\n scale *= 1.07\r\n }\r\n app.canvas.ds.changeScale(scale, [midX, midY])\r\n app.canvas.setDirty(true, true)\r\n zoomPos = newZoomPos\r\n }\r\n },\r\n true\r\n )\r\n }\r\n})\r\n\r\nconst processMouseDown = LGraphCanvas.prototype.processMouseDown\r\nLGraphCanvas.prototype.processMouseDown = function (e) {\r\n if (touchZooming || touchCount) {\r\n return\r\n }\r\n return processMouseDown.apply(this, arguments)\r\n}\r\n\r\nconst processMouseMove = LGraphCanvas.prototype.processMouseMove\r\nLGraphCanvas.prototype.processMouseMove = function (e) {\r\n if (touchZooming || touchCount > 1) {\r\n return\r\n }\r\n return processMouseMove.apply(this, arguments)\r\n}\r\n","import { app } from '../../scripts/app'\r\nimport { ComfyWidgets } from '../../scripts/widgets'\r\nimport { LiteGraph } from '@comfyorg/litegraph'\r\n// Adds defaults for quickly adding nodes with middle click on the input/output\r\n\r\napp.registerExtension({\r\n name: 'Comfy.SlotDefaults',\r\n suggestionsNumber: null,\r\n init() {\r\n LiteGraph.search_filter_enabled = true\r\n LiteGraph.middle_click_slot_add_default_node = true\r\n this.suggestionsNumber = app.ui.settings.addSetting({\r\n id: 'Comfy.NodeSuggestions.number',\r\n category: ['Comfy', 'Node Search Box', 'NodeSuggestions'],\r\n name: 'Number of nodes suggestions',\r\n tooltip: 'Only for litegraph searchbox/context menu',\r\n type: 'slider',\r\n attrs: {\r\n min: 1,\r\n max: 100,\r\n step: 1\r\n },\r\n defaultValue: 5,\r\n onChange: (newVal, oldVal) => {\r\n this.setDefaults(newVal)\r\n }\r\n })\r\n },\r\n slot_types_default_out: {},\r\n slot_types_default_in: {},\r\n async beforeRegisterNodeDef(nodeType, nodeData, app) {\r\n var nodeId = nodeData.name\r\n var inputs = []\r\n inputs = nodeData['input']['required'] //only show required inputs to reduce the mess also not logical to create node with optional inputs\r\n for (const inputKey in inputs) {\r\n var input = inputs[inputKey]\r\n if (typeof input[0] !== 'string') continue\r\n\r\n var type = input[0]\r\n if (type in ComfyWidgets) {\r\n var customProperties = input[1]\r\n if (!customProperties?.forceInput) continue //ignore widgets that don't force input\r\n }\r\n\r\n if (!(type in this.slot_types_default_out)) {\r\n this.slot_types_default_out[type] = ['Reroute']\r\n }\r\n if (this.slot_types_default_out[type].includes(nodeId)) continue\r\n this.slot_types_default_out[type].push(nodeId)\r\n\r\n // Input types have to be stored as lower case\r\n // Store each node that can handle this input type\r\n const lowerType = type.toLocaleLowerCase()\r\n if (!(lowerType in LiteGraph.registered_slot_in_types)) {\r\n LiteGraph.registered_slot_in_types[lowerType] = { nodes: [] }\r\n }\r\n LiteGraph.registered_slot_in_types[lowerType].nodes.push(\r\n nodeType.comfyClass\r\n )\r\n }\r\n\r\n var outputs = nodeData['output']\r\n for (const key in outputs) {\r\n var type = outputs[key] as string\r\n if (!(type in this.slot_types_default_in)) {\r\n this.slot_types_default_in[type] = ['Reroute'] // [\"Reroute\", \"Primitive\"]; primitive doesn't always work :'()\r\n }\r\n\r\n this.slot_types_default_in[type].push(nodeId)\r\n\r\n // Store each node that can handle this output type\r\n if (!(type in LiteGraph.registered_slot_out_types)) {\r\n LiteGraph.registered_slot_out_types[type] = { nodes: [] }\r\n }\r\n LiteGraph.registered_slot_out_types[type].nodes.push(nodeType.comfyClass)\r\n\r\n if (!LiteGraph.slot_types_out.includes(type)) {\r\n LiteGraph.slot_types_out.push(type)\r\n }\r\n }\r\n var maxNum = this.suggestionsNumber.value\r\n this.setDefaults(maxNum)\r\n },\r\n setDefaults(maxNum) {\r\n LiteGraph.slot_types_default_out = {}\r\n LiteGraph.slot_types_default_in = {}\r\n\r\n for (const type in this.slot_types_default_out) {\r\n LiteGraph.slot_types_default_out[type] = this.slot_types_default_out[\r\n type\r\n ].slice(0, maxNum)\r\n }\r\n for (const type in this.slot_types_default_in) {\r\n LiteGraph.slot_types_default_in[type] = this.slot_types_default_in[\r\n type\r\n ].slice(0, maxNum)\r\n }\r\n }\r\n})\r\n","import { app } from '../../scripts/app'\r\nimport {\r\n LGraphCanvas,\r\n LGraphNode,\r\n LGraphGroup,\r\n LiteGraph\r\n} from '@comfyorg/litegraph'\r\n\r\n// Shift + drag/resize to snap to grid\r\n\r\n/** Rounds a Vector2 in-place to the current CANVAS_GRID_SIZE. */\r\nfunction roundVectorToGrid(vec) {\r\n vec[0] =\r\n LiteGraph.CANVAS_GRID_SIZE * Math.round(vec[0] / LiteGraph.CANVAS_GRID_SIZE)\r\n vec[1] =\r\n LiteGraph.CANVAS_GRID_SIZE * Math.round(vec[1] / LiteGraph.CANVAS_GRID_SIZE)\r\n return vec\r\n}\r\n\r\napp.registerExtension({\r\n name: 'Comfy.SnapToGrid',\r\n init() {\r\n // Add setting to control grid size\r\n app.ui.settings.addSetting({\r\n id: 'Comfy.SnapToGrid.GridSize',\r\n category: ['Comfy', 'Graph', 'GridSize'],\r\n name: 'Snap to gird size',\r\n type: 'slider',\r\n attrs: {\r\n min: 1,\r\n max: 500\r\n },\r\n tooltip:\r\n 'When dragging and resizing nodes while holding shift they will be aligned to the grid, this controls the size of that grid.',\r\n defaultValue: LiteGraph.CANVAS_GRID_SIZE,\r\n onChange(value) {\r\n LiteGraph.CANVAS_GRID_SIZE = +value\r\n }\r\n })\r\n\r\n // After moving a node, if the shift key is down align it to grid\r\n const onNodeMoved = app.canvas.onNodeMoved\r\n app.canvas.onNodeMoved = function (node) {\r\n const r = onNodeMoved?.apply(this, arguments)\r\n\r\n if (app.shiftDown) {\r\n // Ensure all selected nodes are realigned\r\n for (const id in this.selected_nodes) {\r\n this.selected_nodes[id].alignToGrid()\r\n }\r\n }\r\n\r\n return r\r\n }\r\n\r\n // When a node is added, add a resize handler to it so we can fix align the size with the grid\r\n const onNodeAdded = app.graph.onNodeAdded\r\n app.graph.onNodeAdded = function (node) {\r\n const onResize = node.onResize\r\n node.onResize = function () {\r\n if (app.shiftDown) {\r\n roundVectorToGrid(node.size)\r\n }\r\n return onResize?.apply(this, arguments)\r\n }\r\n return onNodeAdded?.apply(this, arguments)\r\n }\r\n\r\n // Draw a preview of where the node will go if holding shift and the node is selected\r\n const origDrawNode = LGraphCanvas.prototype.drawNode\r\n LGraphCanvas.prototype.drawNode = function (node, ctx) {\r\n if (\r\n app.shiftDown &&\r\n this.node_dragged &&\r\n node.id in this.selected_nodes\r\n ) {\r\n const [x, y] = roundVectorToGrid([...node.pos])\r\n const shiftX = x - node.pos[0]\r\n let shiftY = y - node.pos[1]\r\n\r\n let w, h\r\n if (node.flags.collapsed) {\r\n // @ts-expect-error\r\n w = node._collapsed_width\r\n h = LiteGraph.NODE_TITLE_HEIGHT\r\n shiftY -= LiteGraph.NODE_TITLE_HEIGHT\r\n } else {\r\n w = node.size[0]\r\n h = node.size[1]\r\n // @ts-expect-error\r\n let titleMode = node.constructor.title_mode\r\n if (\r\n titleMode !== LiteGraph.TRANSPARENT_TITLE &&\r\n titleMode !== LiteGraph.NO_TITLE\r\n ) {\r\n h += LiteGraph.NODE_TITLE_HEIGHT\r\n shiftY -= LiteGraph.NODE_TITLE_HEIGHT\r\n }\r\n }\r\n const f = ctx.fillStyle\r\n ctx.fillStyle = 'rgba(100, 100, 100, 0.5)'\r\n ctx.fillRect(shiftX, shiftY, w, h)\r\n ctx.fillStyle = f\r\n }\r\n\r\n return origDrawNode.apply(this, arguments)\r\n }\r\n\r\n /**\r\n * The currently moving, selected group only. Set after the `selected_group` has actually started\r\n * moving.\r\n */\r\n let selectedAndMovingGroup: LGraphGroup | null = null\r\n\r\n /**\r\n * Handles moving a group; tracking when a group has been moved (to show the ghost in `drawGroups`\r\n * below) as well as handle the last move call from LiteGraph's `processMouseUp`.\r\n */\r\n const groupMove = LGraphGroup.prototype.move\r\n LGraphGroup.prototype.move = function (deltax, deltay, ignore_nodes) {\r\n const v = groupMove.apply(this, arguments)\r\n // When we've started moving, set `selectedAndMovingGroup` as LiteGraph sets `selected_group`\r\n // too eagerly and we don't want to behave like we're moving until we get a delta.\r\n if (\r\n !selectedAndMovingGroup &&\r\n app.canvas.selected_group === this &&\r\n (deltax || deltay)\r\n ) {\r\n selectedAndMovingGroup = this\r\n }\r\n\r\n // LiteGraph will call group.move both on mouse-move as well as mouse-up though we only want\r\n // to snap on a mouse-up which we can determine by checking if `app.canvas.last_mouse_dragging`\r\n // has been set to `false`. Essentially, this check here is the equivalent to calling an\r\n // `LGraphGroup.prototype.onNodeMoved` if it had existed.\r\n if (app.canvas.last_mouse_dragging === false && app.shiftDown) {\r\n // After moving a group (while app.shiftDown), snap all the child nodes and, finally,\r\n // align the group itself.\r\n this.recomputeInsideNodes()\r\n for (const node of this._nodes) {\r\n node.alignToGrid()\r\n }\r\n LGraphNode.prototype.alignToGrid.apply(this)\r\n }\r\n return v\r\n }\r\n\r\n /**\r\n * Handles drawing a group when, snapping the size when one is actively being resized tracking and/or\r\n * drawing a ghost box when one is actively being moved. This mimics the node snapping behavior for\r\n * both.\r\n */\r\n const drawGroups = LGraphCanvas.prototype.drawGroups\r\n LGraphCanvas.prototype.drawGroups = function (canvas, ctx) {\r\n if (this.selected_group && app.shiftDown) {\r\n if (this.selected_group_resizing) {\r\n roundVectorToGrid(this.selected_group.size)\r\n } else if (selectedAndMovingGroup) {\r\n // @ts-expect-error\r\n const [x, y] = roundVectorToGrid([...selectedAndMovingGroup.pos])\r\n const f = ctx.fillStyle\r\n const s = ctx.strokeStyle\r\n ctx.fillStyle = 'rgba(100, 100, 100, 0.33)'\r\n ctx.strokeStyle = 'rgba(100, 100, 100, 0.66)'\r\n // @ts-expect-error\r\n ctx.rect(x, y, ...selectedAndMovingGroup.size)\r\n ctx.fill()\r\n ctx.stroke()\r\n ctx.fillStyle = f\r\n ctx.strokeStyle = s\r\n }\r\n } else if (!this.selected_group) {\r\n selectedAndMovingGroup = null\r\n }\r\n return drawGroups.apply(this, arguments)\r\n }\r\n\r\n /** Handles adding a group in a snapping-enabled state. */\r\n const onGroupAdd = LGraphCanvas.onGroupAdd\r\n LGraphCanvas.onGroupAdd = function () {\r\n const v = onGroupAdd.apply(app.canvas, arguments)\r\n if (app.shiftDown) {\r\n // @ts-expect-error\r\n const lastGroup = app.graph._groups[app.graph._groups.length - 1]\r\n if (lastGroup) {\r\n // @ts-expect-error\r\n roundVectorToGrid(lastGroup.pos)\r\n // @ts-expect-error\r\n roundVectorToGrid(lastGroup.size)\r\n }\r\n }\r\n return v\r\n }\r\n }\r\n})\r\n","import { app } from '../../scripts/app'\r\nimport { ComfyNodeDef } from '@/types/apiTypes'\r\n\r\n// Adds an upload button to the nodes\r\n\r\napp.registerExtension({\r\n name: 'Comfy.UploadImage',\r\n async beforeRegisterNodeDef(nodeType, nodeData: ComfyNodeDef, app) {\r\n if (nodeData?.input?.required?.image?.[1]?.image_upload === true) {\r\n nodeData.input.required.upload = ['IMAGEUPLOAD']\r\n }\r\n }\r\n})\r\n","import { app } from '../../scripts/app'\r\nimport { api } from '../../scripts/api'\r\n\r\nconst WEBCAM_READY = Symbol()\r\n\r\napp.registerExtension({\r\n name: 'Comfy.WebcamCapture',\r\n getCustomWidgets(app) {\r\n return {\r\n WEBCAM(node, inputName) {\r\n let res\r\n node[WEBCAM_READY] = new Promise((resolve) => (res = resolve))\r\n\r\n const container = document.createElement('div')\r\n container.style.background = 'rgba(0,0,0,0.25)'\r\n container.style.textAlign = 'center'\r\n\r\n const video = document.createElement('video')\r\n video.style.height = video.style.width = '100%'\r\n\r\n const loadVideo = async () => {\r\n try {\r\n const stream = await navigator.mediaDevices.getUserMedia({\r\n video: true,\r\n audio: false\r\n })\r\n container.replaceChildren(video)\r\n\r\n setTimeout(() => res(video), 500) // Fallback as loadedmetadata doesnt fire sometimes?\r\n video.addEventListener('loadedmetadata', () => res(video), false)\r\n video.srcObject = stream\r\n video.play()\r\n } catch (error) {\r\n const label = document.createElement('div')\r\n label.style.color = 'red'\r\n label.style.overflow = 'auto'\r\n label.style.maxHeight = '100%'\r\n label.style.whiteSpace = 'pre-wrap'\r\n\r\n if (window.isSecureContext) {\r\n label.textContent =\r\n 'Unable to load webcam, please ensure access is granted:\\n' +\r\n error.message\r\n } else {\r\n label.textContent =\r\n 'Unable to load webcam. A secure context is required, if you are not accessing ComfyUI on localhost (127.0.0.1) you will have to enable TLS (https)\\n\\n' +\r\n error.message\r\n }\r\n\r\n container.replaceChildren(label)\r\n }\r\n }\r\n\r\n loadVideo()\r\n\r\n return { widget: node.addDOMWidget(inputName, 'WEBCAM', container) }\r\n }\r\n }\r\n },\r\n nodeCreated(node) {\r\n if ((node.type, node.constructor.comfyClass !== 'WebcamCapture')) return\r\n\r\n let video\r\n const camera = node.widgets.find((w) => w.name === 'image')\r\n const w = node.widgets.find((w) => w.name === 'width')\r\n const h = node.widgets.find((w) => w.name === 'height')\r\n const captureOnQueue = node.widgets.find(\r\n (w) => w.name === 'capture_on_queue'\r\n )\r\n\r\n const canvas = document.createElement('canvas')\r\n\r\n const capture = () => {\r\n canvas.width = w.value\r\n canvas.height = h.value\r\n const ctx = canvas.getContext('2d')\r\n ctx.drawImage(video, 0, 0, w.value, h.value)\r\n const data = canvas.toDataURL('image/png')\r\n\r\n const img = new Image()\r\n img.onload = () => {\r\n node.imgs = [img]\r\n app.graph.setDirtyCanvas(true)\r\n requestAnimationFrame(() => {\r\n node.setSizeForImage?.()\r\n })\r\n }\r\n img.src = data\r\n }\r\n\r\n const btn = node.addWidget(\r\n 'button',\r\n 'waiting for camera...',\r\n 'capture',\r\n capture\r\n )\r\n btn.disabled = true\r\n btn.serializeValue = () => undefined\r\n\r\n camera.serializeValue = async () => {\r\n if (captureOnQueue.value) {\r\n capture()\r\n } else if (!node.imgs?.length) {\r\n const err = `No webcam image captured`\r\n alert(err)\r\n throw new Error(err)\r\n }\r\n\r\n // Upload image to temp storage\r\n const blob = await new Promise((r) => canvas.toBlob(r))\r\n const name = `${+new Date()}.png`\r\n const file = new File([blob], name)\r\n const body = new FormData()\r\n body.append('image', file)\r\n body.append('subfolder', 'webcam')\r\n body.append('type', 'temp')\r\n const resp = await api.fetchApi('/upload/image', {\r\n method: 'POST',\r\n body\r\n })\r\n if (resp.status !== 200) {\r\n const err = `Error uploading camera image: ${resp.status} - ${resp.statusText}`\r\n alert(err)\r\n throw new Error(err)\r\n }\r\n return `webcam/${name} [temp]`\r\n }\r\n\r\n node[WEBCAM_READY].then((v) => {\r\n video = v\r\n // If width isnt specified then use video output resolution\r\n if (!w.value) {\r\n w.value = video.videoWidth || 640\r\n h.value = video.videoHeight || 480\r\n }\r\n btn.disabled = false\r\n btn.label = 'capture'\r\n })\r\n }\r\n})\r\n","import { app } from '../../scripts/app'\r\nimport { api } from '../../scripts/api'\r\nimport type { IWidget } from '@comfyorg/litegraph'\r\nimport type { DOMWidget } from '@/scripts/domWidget'\r\nimport { ComfyNodeDef } from '@/types/apiTypes'\r\n\r\ntype FolderType = 'input' | 'output' | 'temp'\r\n\r\nfunction splitFilePath(path: string): [string, string] {\r\n const folder_separator = path.lastIndexOf('/')\r\n if (folder_separator === -1) {\r\n return ['', path]\r\n }\r\n return [\r\n path.substring(0, folder_separator),\r\n path.substring(folder_separator + 1)\r\n ]\r\n}\r\n\r\nfunction getResourceURL(\r\n subfolder: string,\r\n filename: string,\r\n type: FolderType = 'input'\r\n): string {\r\n const params = [\r\n 'filename=' + encodeURIComponent(filename),\r\n 'type=' + type,\r\n 'subfolder=' + subfolder,\r\n app.getRandParam().substring(1)\r\n ].join('&')\r\n\r\n return `/view?${params}`\r\n}\r\n\r\nasync function uploadFile(\r\n audioWidget: IWidget,\r\n audioUIWidget: DOMWidget,\r\n file: File,\r\n updateNode: boolean,\r\n pasted: boolean = false\r\n) {\r\n try {\r\n // Wrap file in formdata so it includes filename\r\n const body = new FormData()\r\n body.append('image', file)\r\n if (pasted) body.append('subfolder', 'pasted')\r\n const resp = await api.fetchApi('/upload/image', {\r\n method: 'POST',\r\n body\r\n })\r\n\r\n if (resp.status === 200) {\r\n const data = await resp.json()\r\n // Add the file to the dropdown list and update the widget value\r\n let path = data.name\r\n if (data.subfolder) path = data.subfolder + '/' + path\r\n\r\n if (!audioWidget.options.values.includes(path)) {\r\n audioWidget.options.values.push(path)\r\n }\r\n\r\n if (updateNode) {\r\n audioUIWidget.element.src = api.apiURL(\r\n getResourceURL(...splitFilePath(path))\r\n )\r\n audioWidget.value = path\r\n }\r\n } else {\r\n alert(resp.status + ' - ' + resp.statusText)\r\n }\r\n } catch (error) {\r\n alert(error)\r\n }\r\n}\r\n\r\n// AudioWidget MUST be registered first, as AUDIOUPLOAD depends on AUDIO_UI to be\r\n// present.\r\napp.registerExtension({\r\n name: 'Comfy.AudioWidget',\r\n async beforeRegisterNodeDef(nodeType, nodeData) {\r\n if (\r\n ['LoadAudio', 'SaveAudio', 'PreviewAudio'].includes(nodeType.comfyClass)\r\n ) {\r\n nodeData.input.required.audioUI = ['AUDIO_UI']\r\n }\r\n },\r\n getCustomWidgets() {\r\n return {\r\n AUDIO_UI(node, inputName: string) {\r\n const audio = document.createElement('audio')\r\n audio.controls = true\r\n audio.classList.add('comfy-audio')\r\n audio.setAttribute('name', 'media')\r\n\r\n const audioUIWidget: DOMWidget = node.addDOMWidget(\r\n inputName,\r\n /* name=*/ 'audioUI',\r\n audio\r\n )\r\n // @ts-expect-error\r\n // TODO: Sort out the DOMWidget type.\r\n audioUIWidget.serialize = false\r\n\r\n const isOutputNode = node.constructor.nodeData.output_node\r\n if (isOutputNode) {\r\n // Hide the audio widget when there is no audio initially.\r\n audioUIWidget.element.classList.add('empty-audio-widget')\r\n // Populate the audio widget UI on node execution.\r\n const onExecuted = node.onExecuted\r\n node.onExecuted = function (message) {\r\n onExecuted?.apply(this, arguments)\r\n const audios = message.audio\r\n if (!audios) return\r\n const audio = audios[0]\r\n audioUIWidget.element.src = api.apiURL(\r\n getResourceURL(audio.subfolder, audio.filename, audio.type)\r\n )\r\n audioUIWidget.element.classList.remove('empty-audio-widget')\r\n }\r\n }\r\n return { widget: audioUIWidget }\r\n }\r\n }\r\n },\r\n onNodeOutputsUpdated(nodeOutputs: Record) {\r\n for (const [nodeId, output] of Object.entries(nodeOutputs)) {\r\n const node = app.graph.getNodeById(Number.parseInt(nodeId))\r\n if ('audio' in output) {\r\n const audioUIWidget = node.widgets.find(\r\n (w) => w.name === 'audioUI'\r\n ) as unknown as DOMWidget\r\n const audio = output.audio[0]\r\n audioUIWidget.element.src = api.apiURL(\r\n getResourceURL(audio.subfolder, audio.filename, audio.type)\r\n )\r\n audioUIWidget.element.classList.remove('empty-audio-widget')\r\n }\r\n }\r\n }\r\n})\r\n\r\napp.registerExtension({\r\n name: 'Comfy.UploadAudio',\r\n async beforeRegisterNodeDef(nodeType, nodeData: ComfyNodeDef) {\r\n if (nodeData?.input?.required?.audio?.[1]?.audio_upload === true) {\r\n nodeData.input.required.upload = ['AUDIOUPLOAD']\r\n }\r\n },\r\n getCustomWidgets() {\r\n return {\r\n AUDIOUPLOAD(node, inputName: string) {\r\n // The widget that allows user to select file.\r\n const audioWidget: IWidget = node.widgets.find(\r\n (w: IWidget) => w.name === 'audio'\r\n )\r\n const audioUIWidget: DOMWidget = node.widgets.find(\r\n (w: IWidget) => w.name === 'audioUI'\r\n )\r\n\r\n const onAudioWidgetUpdate = () => {\r\n audioUIWidget.element.src = api.apiURL(\r\n getResourceURL(...splitFilePath(audioWidget.value))\r\n )\r\n }\r\n // Initially load default audio file to audioUIWidget.\r\n if (audioWidget.value) {\r\n onAudioWidgetUpdate()\r\n }\r\n audioWidget.callback = onAudioWidgetUpdate\r\n\r\n // Load saved audio file widget values if restoring from workflow\r\n const onGraphConfigured = node.onGraphConfigured\r\n node.onGraphConfigured = function () {\r\n onGraphConfigured?.apply(this, arguments)\r\n if (audioWidget.value) {\r\n onAudioWidgetUpdate()\r\n }\r\n }\r\n\r\n const fileInput = document.createElement('input')\r\n fileInput.type = 'file'\r\n fileInput.accept = 'audio/*'\r\n fileInput.style.display = 'none'\r\n fileInput.onchange = () => {\r\n if (fileInput.files.length) {\r\n uploadFile(audioWidget, audioUIWidget, fileInput.files[0], true)\r\n }\r\n }\r\n // The widget to pop up the upload dialog.\r\n const uploadWidget = node.addWidget(\r\n 'button',\r\n inputName,\r\n /* value=*/ '',\r\n () => {\r\n fileInput.click()\r\n }\r\n )\r\n uploadWidget.label = 'choose file to upload'\r\n uploadWidget.serialize = false\r\n\r\n return { widget: uploadWidget }\r\n }\r\n }\r\n }\r\n})\r\n"],"names":["app","id","file","ext","prompt","links","_a","widget","_b","w","type","_c","def","node","link","selectedIds","newNodes","i","group","modal","x","y","audio"],"mappings":"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"}