|  | import { app } from "../../../scripts/app.js"; | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | const LOCKED = Symbol(); | 
					
						
						|  |  | 
					
						
						|  | function lockArray(arr, isLocked) { | 
					
						
						|  | const v = []; | 
					
						
						|  |  | 
					
						
						|  | for (let i = 0; i < 2; i++) { | 
					
						
						|  | v[i] = arr[i]; | 
					
						
						|  |  | 
					
						
						|  | Object.defineProperty(arr, i, { | 
					
						
						|  | get() { | 
					
						
						|  | return v[i]; | 
					
						
						|  | }, | 
					
						
						|  | set(value) { | 
					
						
						|  | if (!isLocked()) { | 
					
						
						|  | v[i] = value; | 
					
						
						|  | } | 
					
						
						|  | }, | 
					
						
						|  | }); | 
					
						
						|  | } | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | app.registerExtension({ | 
					
						
						|  | name: "pysssss.Locking", | 
					
						
						|  | init() { | 
					
						
						|  | function lockGroup(node) { | 
					
						
						|  | node[LOCKED] = true; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | const serialize = LGraphGroup.prototype.serialize; | 
					
						
						|  | LGraphGroup.prototype.serialize = function () { | 
					
						
						|  | const o = serialize.apply(this, arguments); | 
					
						
						|  | o.locked = !!this[LOCKED]; | 
					
						
						|  | return o; | 
					
						
						|  | }; | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | const configure = LGraphGroup.prototype.configure; | 
					
						
						|  | LGraphGroup.prototype.configure = function (o) { | 
					
						
						|  | configure.apply(this, arguments); | 
					
						
						|  | if (o.locked) { | 
					
						
						|  | lockGroup(this); | 
					
						
						|  | } | 
					
						
						|  | }; | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | const getGroupOnPos = LGraph.prototype.getGroupOnPos; | 
					
						
						|  | LGraph.prototype.getGroupOnPos = function () { | 
					
						
						|  | const r = getGroupOnPos.apply(this, arguments); | 
					
						
						|  | if (r && r[LOCKED] && !new Error().stack.includes("processContextMenu")) return null; | 
					
						
						|  | return r; | 
					
						
						|  | }; | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | const getGroupMenuOptions = LGraphCanvas.prototype.getGroupMenuOptions; | 
					
						
						|  | LGraphCanvas.prototype.getGroupMenuOptions = function (node) { | 
					
						
						|  | const opts = getGroupMenuOptions.apply(this, arguments); | 
					
						
						|  |  | 
					
						
						|  | opts.unshift( | 
					
						
						|  | node[LOCKED] | 
					
						
						|  | ? { | 
					
						
						|  | content: "Unlock", | 
					
						
						|  | callback: () => { | 
					
						
						|  | delete node[LOCKED]; | 
					
						
						|  | }, | 
					
						
						|  | } | 
					
						
						|  | : { | 
					
						
						|  | content: "Lock", | 
					
						
						|  | callback: () => lockGroup(node), | 
					
						
						|  | }, | 
					
						
						|  | null | 
					
						
						|  | ); | 
					
						
						|  |  | 
					
						
						|  | return opts; | 
					
						
						|  | }; | 
					
						
						|  | }, | 
					
						
						|  | setup() { | 
					
						
						|  | const drawNodeShape = LGraphCanvas.prototype.drawNodeShape; | 
					
						
						|  | LGraphCanvas.prototype.drawNodeShape = function (node, ctx, size, fgcolor, bgcolor, selected, mouse_over) { | 
					
						
						|  | const res = drawNodeShape.apply(this, arguments); | 
					
						
						|  |  | 
					
						
						|  | if (node[LOCKED]) { | 
					
						
						|  | ctx.fillText("🔒", node.getBounding()[2] - 20, -10); | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | return res; | 
					
						
						|  | }; | 
					
						
						|  | }, | 
					
						
						|  | async beforeRegisterNodeDef(nodeType) { | 
					
						
						|  | const nodesArray = (nodes) => { | 
					
						
						|  | if (nodes) { | 
					
						
						|  | if (nodes instanceof Array) { | 
					
						
						|  | return nodes; | 
					
						
						|  | } | 
					
						
						|  | return [nodes]; | 
					
						
						|  | } | 
					
						
						|  | return Object.values(app.canvas.selected_nodes); | 
					
						
						|  | }; | 
					
						
						|  | function unlockNode(nodes) { | 
					
						
						|  | nodes = nodesArray(nodes); | 
					
						
						|  | for (const node of nodes) { | 
					
						
						|  | delete node[LOCKED]; | 
					
						
						|  | } | 
					
						
						|  | app.graph.setDirtyCanvas(true, false); | 
					
						
						|  | } | 
					
						
						|  | function lockNode(nodes) { | 
					
						
						|  | nodes = nodesArray(nodes); | 
					
						
						|  | for (const node of nodes) { | 
					
						
						|  | if (node[LOCKED]) continue; | 
					
						
						|  |  | 
					
						
						|  | node[LOCKED] = true; | 
					
						
						|  |  | 
					
						
						|  | lockArray(node.pos, () => !!node[LOCKED]); | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | const sz = [node.size[0], node.size[1]]; | 
					
						
						|  | Object.defineProperty(node, "size", { | 
					
						
						|  | get() { | 
					
						
						|  | return sz; | 
					
						
						|  | }, | 
					
						
						|  | set(value) { | 
					
						
						|  | if (!node[LOCKED]) { | 
					
						
						|  | sz[0] = value[0]; | 
					
						
						|  | sz[1] = value[1]; | 
					
						
						|  | } | 
					
						
						|  | }, | 
					
						
						|  | }); | 
					
						
						|  |  | 
					
						
						|  | lockArray(sz, () => !!node[LOCKED]); | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | app.graph.setDirtyCanvas(true, false); | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | const getExtraMenuOptions = nodeType.prototype.getExtraMenuOptions; | 
					
						
						|  | nodeType.prototype.getExtraMenuOptions = function (_, options) { | 
					
						
						|  | const r = getExtraMenuOptions ? getExtraMenuOptions.apply(this, arguments) : undefined; | 
					
						
						|  |  | 
					
						
						|  | options.splice( | 
					
						
						|  | options.findIndex((o) => o?.content === "Properties") + 1, | 
					
						
						|  | 0, | 
					
						
						|  | null, | 
					
						
						|  | this[LOCKED] | 
					
						
						|  | ? { | 
					
						
						|  | content: "Unlock", | 
					
						
						|  | callback: () => { | 
					
						
						|  | unlockNode(); | 
					
						
						|  | }, | 
					
						
						|  | } | 
					
						
						|  | : { | 
					
						
						|  | content: "Lock", | 
					
						
						|  | callback: () => lockNode(), | 
					
						
						|  | } | 
					
						
						|  | ); | 
					
						
						|  |  | 
					
						
						|  | return r; | 
					
						
						|  | }; | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | const onSerialize = nodeType.prototype.onSerialize; | 
					
						
						|  | nodeType.prototype.onSerialize = function (o) { | 
					
						
						|  | if (onSerialize) { | 
					
						
						|  | onSerialize.apply(this, arguments); | 
					
						
						|  | } | 
					
						
						|  | o.locked = this[LOCKED]; | 
					
						
						|  | }; | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | const onConfigure = nodeType.prototype.onConfigure; | 
					
						
						|  | nodeType.prototype.onConfigure = function (o) { | 
					
						
						|  | if (onConfigure) { | 
					
						
						|  | onConfigure.apply(this, arguments); | 
					
						
						|  | } | 
					
						
						|  | if (o.locked) { | 
					
						
						|  | lockNode(this); | 
					
						
						|  | } | 
					
						
						|  | }; | 
					
						
						|  | }, | 
					
						
						|  | }); | 
					
						
						|  |  |