{"version":3,"sources":["_init.js","Keyboard.code.js","Keyboard.js","Pointer/MouseClick.js","Pointer/MouseScroll.js","Pointer/Movement.js","UI/Button.js","UI/File.js","UI/SliderBox.js","UI/TextBox.js"],"names":["_Class","_KeyboardNode","_MouseNode","_MouseScrollNode","_PointerMovementNode","_Class2","_FileNode","_SliderBoxNode","_Class3","_classPrivateFieldLooseBase","e","t","hasOwnProperty","call","TypeError","id","_classPrivateFieldLooseKey","window","globalThis","async","imports","urls","sf","loader","mjs","Promise","all","map","v","import","task","Blackprint","loadScope","url","hasInterface","hasDocs","Context","createContext","EventSlot","slot","objLength","obj","i","k","_fType","fType","name","temp","Object","defineProperty","value","HTMLElement","Event","KeyboardEvent","PointerEvent","TouchEvent","MouseEvent","Blob","allWindow","Window","document","$","DepsLoader","js","cdn","registerCode","Code","routes","keys","this","iface","data","addOutput","forEach","Boolean","type","CodeType","Callback","selfRun","code","routeIn","CodeRoute","Optional","routeOut","registerNode","Node","constructor","instance","super","_onKeyboard","_onKeyboardEl","setInterface","title","description","enabled","onKeyboard","ev","Output","ref","view","Pressed","Released","out","initPorts","assign","length","createPort","waitKeyToBeListened","port","node","toast","$decoration","warn","_waiting","includes","text","indexOf","splice","push","renamePort","destroy","off","on","init","update","portMenu","callback","iPort","notifyEditorDataChanged","removePort","deletePort","menu","source","addMenu","slice","context","Input","el","Element","input","Listen","Port","Trigger","Unlisten","output","_onClick","_onClickEl","onClick","_isSync","Release","button","Left","Middle","Right","syncOut","syncIn","Union","_onScroll","_onScrollEl","onScroll","dx","deltaX","dy","deltaY","dz","deltaZ","dm","deltaMode","which","WheelEvent","StructOf","X","Number","field","Y","Z","_onMove","_onMoveEl","onMove","MoveX","MoveY","ClientX","ClientY","ScreenX","ScreenY","key","val","Clicked","Types","registerInterface","IFace","Button","Interface","clicked","URL","String","File","file","inputEl","createElement","that","addEventListener","setFile","files","revokeObjectURL","createObjectURL","browseFile","click","imported","pop","evName","changed","Default","SliderBoxIFace","focusIndex","index","valueListener","now","max","min","Math","round","_iface","clearTimeout","_wait","setTimeout","step","on$value","undefined","Value","importing","Changed","InputTextBoxData","_value","writable","utils","setEnumerablePrototype"],"mappings":"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","file":"nodes-input.mjs","sourcesContent":["// This script will run first, and then the other files\n// depends on blackprint.config.js configuration\n\n// Because .js and .sf is separated\n// we also need to call loadScope just like _init.js\nlet Blackprint = window.Blackprint.loadScope({\n\t// You can find the URL on Blackprint menu -> Modules\n\t// This will also be exported to JSON if this module's nodes is being used\n\turl: import.meta.url,\n\n\t// This will autoload (*.sf.mjs) and (*.sf.css) file for Browser\n\thasInterface: true,\n\n\t// This will autoload (*.docs.json) for Browser\n\thasDocs: true,\n});\n\n// Global shared context\nlet Context = Blackprint.createContext('Input');\n\n// This is needed to avoid duplicated event listener when using hot reload\n// Event listener that registered with same slot will be replaced\nContext.EventSlot = {slot: 'my-private-event-slot'};\n\n// Shared function\nlet objLength = Context.objLength = function(obj){\n\tvar i = 0;\n\tfor(var k in obj)\n\t\ti++;\n\n\treturn i;\n}\n\n// Fake Type, for Node.js/Deno\nlet _fType = {};\nlet fType = function(name){\n\tif(_fType[name] == null){\n\t\tlet temp = _fType[name] = class{};\n\t\tObject.defineProperty(temp, 'name', {value: name});\n\t}\n\n\treturn _fType[name];\n}\n\n// Fix for Node.js/Deno\nvar {\n\tHTMLElement = fType('HTMLElement'),\n\tEvent = fType('Event'),\n\tKeyboardEvent = fType('KeyboardEvent'),\n\tPointerEvent = fType('PointerEvent'),\n\tTouchEvent = fType('TouchEvent'),\n\tMouseEvent = fType('MouseEvent'),\n} = window;\n\nlet Blob = window.Blob; // Browser/Deno\nif(Blob === void 0) // Node.js\n\tBlob = (await import('node:buffer')).Blob;\n\nlet allWindow = window.sf?.Window ?? window.document;\n\n// ToDo: add import for Node.js\nvar [ $ ] = await Blackprint.DepsLoader.js({\n\twindow: ['sf.$'],\n\n\t// for browser, Deno, or supported environment that have internet access\n\tcdn: [\"https://cdn.jsdelivr.net/npm/scarletsframe@0.35.x/dist/squery.min.js\"]\n});","Blackprint.registerCode('Input/Keyboard',\nclass extends Blackprint.Code {\n\tstatic routeIn = Blackprint.CodeRoute.Optional;\n\tstatic routeOut = Blackprint.CodeRoute.Optional;\n\n\tjs(routes){\n\t\tlet { keys } = this.iface.data;\n\n\t\t// Define listened keys as output port\n\t\tlet addOutput = {};\n\t\tkeys.forEach(v => addOutput[v] = Boolean);\n\n\t\treturn {\n\t\t\ttype: Blackprint.CodeType.Callback,\n\t\t\tselfRun: true, // This code will run by itself\n\t\t\taddOutput,\n\t\t\tcode: `\n\t\t\t\tfunction onKeyboard(ev){\n\t\t\t\t\tif(ev.type === 'keydown'){\n\t\t\t\t\t\tOutput.Pressed = ev;\n\t\t\t\t\t\tOutput.Released = null;\n\t\t\t\t\t}\n\t\t\t\t\telse if(ev.type === 'keyup'){\n\t\t\t\t\t\tOutput.Pressed = null;\n\t\t\t\t\t\tOutput.Released = ev;\n\t\t\t\t\t}\n\n\t\t\t\t\tif(ev.code in Output)\n\t\t\t\t\t\tOutput[ev.code] = ev.type === 'keydown';\n\n\t\t\t\t\tRoute.Out();\n\t\t\t\t}\n\n\t\t\t\tInput.Listen = function(){\n\t\t\t\t\tlet temp = Input.Element || window;\n\t\t\t\t\ttemp.addEventListener('keydown', onKeyboard);\n\t\t\t\t\ttemp.addEventListener('keyup', onKeyboard);\n\t\t\t\t}\n\n\t\t\t\tInput.Unlisten = function(){\n\t\t\t\t\tlet temp = Input.Element || window;\n\t\t\t\t\ttemp.removeEventListener('keydown', onKeyboard);\n\t\t\t\t\ttemp.removeEventListener('keyup', onKeyboard);\n\t\t\t\t}\n\n\t\t\t\tInput.Listen();\n\t\t\t`,\n\t\t};\n\t}\n});","/**\n * Listen to keyboard event\n * You can also listen to specific keyboard key by right clicking the output port\n * Make sure to turn on AllowResync if you need to reupdate other node\n * @blackprint node\n */\nBlackprint.registerNode('Input/Keyboard',\nclass KeyboardNode extends Blackprint.Node {\n\tstatic input = {\n\t\t/** If this not connected to anything, this node will listen to window */\n\t\tElement: HTMLElement,\n\t\t/** Start listening to mouse click event */\n\t\tListen: Blackprint.Port.Trigger(function({ iface }){\n\t\t\tlet node = iface.node;\n\t\t\tnode.enabled = true;\n\t\t\tnode.update();\n\t\t}),\n\t\t/** Stop listener */\n\t\tUnlisten: Blackprint.Port.Trigger(function({ iface }){\n\t\t\tlet node = iface.node;\n\t\t\tnode.enabled = false;\n\t\t\tnode.update();\n\t\t}),\n\t};\n\n\tstatic output = {\n\t\t/** Raw event on button pressed */\n\t\tPressed: KeyboardEvent,\n\t\t/** Raw event on button released */\n\t\tReleased: KeyboardEvent,\n\t};\n\n\tconstructor(instance){\n\t\tsuper(instance);\n\n\t\tlet iface = this.setInterface();\n\t\tiface.title = 'Keyboard Event';\n\t\tiface.description = 'Listening to window';\n\t\tiface.type = 'event';\n\t\tiface.data = {keys: []};\n\n\t\tthis.enabled = true;\n\t}\n\n\t_onKeyboard = null;\n\t_onKeyboardEl = null;\n\tonKeyboard(ev){\n\t\tlet { Output } = this.ref;\n\n\t\t// Avoid receiving event from other window\n\t\tif(ev.view !== window) return;\n\n\t\tif(ev.type === 'keydown')\n\t\t\tOutput.Pressed = ev;\n\t\telse if(ev.type === 'keyup')\n\t\t\tOutput.Released = ev;\n\n\t\tif(ev.code in Output){\n\t\t\tif(ev.type === 'keydown')\n\t\t\t\tOutput[ev.code] = true;\n\t\t\telse if(ev.type === 'keyup')\n\t\t\t\tOutput[ev.code] = false;\n\t\t}\n\n\t\tif(this.routes.out != null) this.routes.routeOut();\n\t}\n\n\tinitPorts(data){\n\t\tlet iface = this.iface;\n\t\tObject.assign(iface.data, data);\n\n\t\tlet { keys } = iface.data;\n\t\tfor (var i = 0; i < keys.length; i++)\n\t\t\tthis.createPort('output', keys[i], Boolean);\n\t}\n\n\twaitKeyToBeListened(port){\n\t\tlet node = this;\n\t\tlet iface = this.iface;\n\t\tlet { keys } = iface.data;\n\n\t\tlet toast = iface.$decoration.warn(\"Press any key...\");\n\t\tthis._waiting = function(ev) {\n\t\t\tif(keys.includes(ev.code)){\n\t\t\t\ttoast.text = 'The key is already being used';\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet i = keys.indexOf('[?]');\n\n\t\t\tif(i !== -1) keys.splice(i, 1, ev.code);\n\t\t\telse keys.push(ev.code);\n\n\t\t\tnode.renamePort('output', port.name, ev.code);\n\t\t\ttoast.destroy();\n\n\t\t\t$(allWindow).off('keydown', node._waiting);\n\t\t\tnode._waiting = null;\n\t\t}\n\n\t\tthis._waiting.toast = toast;\n\t\t$(allWindow).on('keydown', this._waiting);\n\t}\n\n\tinit(){\n\t\tthis.update();\n\t\tlet node = this;\n\t\tlet iface = this.iface;\n\t\tlet { keys } = iface.data;\n\n\t\t// Put this array here, and reuse when port menu event\n\t\tvar portMenu = [{\n\t\t\ttitle:\"Create new port\", callback(){\n\t\t\t\tif(node._waiting != null) return;\n\n\t\t\t\tlet iPort = node.createPort('output', '[?]', Boolean);\n\t\t\t\tnode.waitKeyToBeListened(iPort);\n\n\t\t\t\t// Let editor know if this iface changed and unsaved\n\t\t\t\tnode.notifyEditorDataChanged();\n\t\t\t}\n\t\t}, {\n\t\t\ttitle:\"Change this port\", callback(){\n\t\t\t\tlet i = keys.indexOf(this.name);\n\t\t\t\tif(i !== -1) keys.splice(i, 1);\n\n\t\t\t\tnode.renamePort('output', this.name, '[?]');\n\t\t\t\tnode.waitKeyToBeListened(this);\n\n\t\t\t\t// Let editor know if this iface changed and unsaved\n\t\t\t\tnode.notifyEditorDataChanged();\n\t\t\t}\n\t\t}, {\n\t\t\ttitle:\"Delete this port\", callback(){\n\t\t\t\tif(node._waiting != null){\n\t\t\t\t\t$(allWindow).off('keydown', node._waiting);\n\n\t\t\t\t\tnode._waiting.toast.destroy();\n\t\t\t\t\tnode._waiting = null;\n\n\t\t\t\t\tif(this.name !== '[?]')\n\t\t\t\t\t\tnode.removePort('output', '[?]');\n\t\t\t\t}\n\n\t\t\t\tnode.deletePort('output', this.name);\n\n\t\t\t\tlet i = keys.indexOf(this.name);\n\t\t\t\tif(i !== -1) keys.splice(i, 1);\n\n\t\t\t\t// Let editor know if this iface changed and unsaved\n\t\t\t\tnode.notifyEditorDataChanged();\n\t\t\t}\n\t\t}];\n\n\t\tiface.on('port.menu', Context.EventSlot, function({ port, menu }){\n\t\t\tif(port.source !== 'output')\n\t\t\t\treturn;\n\n\t\t\tlet addMenu;\n\t\t\tif(port.name === 'Pressed' || port.name === 'Released')\n\t\t\t\taddMenu = [portMenu[0]];\n\t\t\telse addMenu = portMenu.slice(0);\n\n\t\t\tfor (var i = 0; i < addMenu.length; i++) {\n\t\t\t\t// Change every callback context to refer current port\n\t\t\t\taddMenu[i].context = port;\n\t\t\t}\n\n\t\t\tmenu.push(...addMenu);\n\t\t});\n\n\t\tiface.on('cable.disconnect', ({port}) => port.name === 'Element' && this.update());\n\t}\n\n\tupdate(){\n\t\tlet { Input } = this.ref;\n\n\t\tif(this._onKeyboard != null){\n\t\t\t$(this._onKeyboardEl ?? allWindow)\n\t\t\t\t.off('keydown', this._onKeyboard)\n\t\t\t\t.off('keyup', this._onKeyboard);\n\n\t\t\tthis._onKeyboardEl = null;\n\t\t}\n\n\t\tthis._onKeyboard = ev => this.onKeyboard(ev);\n\t\tlet el = Input.Element ?? allWindow;\n\n\t\tif(el === allWindow)\n\t\t\tthis.iface.description = 'Listening to window';\n\t\telse this.iface.description = 'Listening to element';\n\n\t\tif(!this.enabled){\n\t\t\tthis.iface.description = 'Not listening';\n\t\t\treturn;\n\t\t}\n\n\t\t$(el).on('keydown', this._onKeyboard)\n\t\t\t.on('keyup', this._onKeyboard);\n\n\t\tthis._onKeyboardEl = el;\n\t}\n\n\tdestroy(){\n\t\tif(this._onKeyboard != null){\n\t\t\t$(this._onKeyboardEl ?? allWindow)\n\t\t\t\t.off('keydown', this._onKeyboard)\n\t\t\t\t.off('keyup', this._onKeyboard);\n\n\t\t\tthis._onKeyboardEl = null;\n\t\t}\n\t}\n});","/** \n * Listen to mouse, pointer, or touch click event\n * Make sure to turn on AllowResync if you need to reupdate other node\n * @blackprint node\n */\nBlackprint.registerNode('Input/Pointer/MouseClick',\nclass MouseNode extends Blackprint.Node {\n\tstatic input = {\n\t\t/** If this not connected to anything, this node will listen to window */\n\t\tElement: HTMLElement,\n\t\t/** Start listening to mouse click event */\n\t\tListen: Blackprint.Port.Trigger(function({ iface }){\n\t\t\tlet node = iface.node;\n\t\t\tnode.enabled = true;\n\t\t\tnode.update();\n\t\t}),\n\t\t/** Stop listener */\n\t\tUnlisten: Blackprint.Port.Trigger(function({ iface }){\n\t\t\tlet node = iface.node;\n\t\t\tnode.enabled = false;\n\t\t\tnode.update();\n\t\t}),\n\t};\n\n\tstatic output = {\n\t\t/** Raw event on button pressed */\n\t\tPressed: Blackprint.Port.Union([PointerEvent, TouchEvent, MouseEvent]),\n\t\t/** Raw event on button released */\n\t\tRelease: Blackprint.Port.Union([PointerEvent, TouchEvent, MouseEvent]),\n\t\t/** Mouse's left click, pointer/touch tap */\n\t\tLeft: Boolean,\n\t\t/** Mouse's middle click */\n\t\tMiddle: Boolean,\n\t\t/** Mouse's right click */\n\t\tRight: Boolean,\n\t\t/** Gaming mouse's 4th button */\n\t\t\"4th\": Boolean,\n\t\t/** Gaming mouse's 5th button */\n\t\t\"5th\": Boolean,\n\t};\n\n\tconstructor(instance){\n\t\tsuper(instance);\n\n\t\tlet iface = this.setInterface();\n\t\tiface.title = 'Mouse Click Event';\n\t\tiface.description = 'Listening to window';\n\t\tiface.type = 'event';\n\n\t\tthis.enabled = true;\n\t}\n\n\tinit(){\n\t\tthis.update();\n\t\tthis.iface.on('cable.disconnect', ({port}) => {\n\t\t\tif(port.name === 'Element'){\n\t\t\t\tthis.update();\n\t\t\t\tthis.routes.routeOut();\n\t\t\t}\n\t\t});\n\t}\n\n\tupdate(){\n\t\tlet { Input } = this.ref;\n\n\t\tif(this._onClick != null){\n\t\t\tlet el = $(this._onClickEl ?? allWindow);\n\n\t\t\tel.off('pointerdown', this._onClick)\n\t\t\t\t.off('pointerup', this._onClick);\n\n\t\t\tthis._onClickEl = null;\n\t\t}\n\n\t\tthis._onClick = ev => this.onClick(ev);\n\t\tlet el = Input.Element ?? allWindow;\n\n\t\tif(el === allWindow)\n\t\t\tthis.iface.description = 'Listening to window';\n\t\telse this.iface.description = 'Listening to element';\n\n\t\tif(!this.enabled){\n\t\t\tthis.iface.description = 'Not listening';\n\t\t\treturn;\n\t\t}\n\n\t\t$(el).on('pointerdown', this._onClick)\n\t\t\t.on('pointerup', this._onClick);\n\n\t\tthis._onClickEl = el;\n\t}\n\n\t_onClick = null;\n\t_onClickEl = null;\n\tonClick(ev, _isSync){\n\t\tlet { Output } = this.ref;\n\n\t\t// Avoid receiving event from other window\n\t\tif(ev.view !== window) return;\n\n\t\tif(ev.type === 'pointerup'){\n\t\t\tOutput.Release = ev;\n\n\t\t\tif(ev.button === 0)\n\t\t\t\tOutput.Left = false;\n\t\t\telse if(ev.button === 1)\n\t\t\t\tOutput.Middle = false;\n\t\t\telse if(ev.button === 2)\n\t\t\t\tOutput.Right = false;\n\t\t\telse if(ev.button === 3)\n\t\t\t\tOutput[\"4th\"] = false;\n\t\t\telse if(ev.button === 4)\n\t\t\t\tOutput[\"5th\"] = false;\n\t\t}\n\t\telse if(ev.type === 'pointerdown'){\n\t\t\tOutput.Pressed = ev;\n\n\t\t\tif(ev.button === 0)\n\t\t\t\tOutput.Left = true;\n\t\t\telse if(ev.button === 1)\n\t\t\t\tOutput.Middle = true;\n\t\t\telse if(ev.button === 2)\n\t\t\t\tOutput.Right = true;\n\t\t\telse if(ev.button === 3)\n\t\t\t\tOutput[\"4th\"] = true;\n\t\t\telse if(ev.button === 4)\n\t\t\t\tOutput[\"5th\"] = true;\n\t\t}\n\n\t\tthis.routes.routeOut();\n\t\tif(!_isSync) this.syncOut(ev.type, ev.button);\n\t}\n\n\tsyncIn(type, button){\n\t\tthis.onClick({type, button}, true);\n\t}\n\n\tdestroy(){\n\t\tif(this._onClick != null){\n\t\t\tlet el = $(this._onClickEl ?? allWindow);\n\n\t\t\tel.off('pointerdown', this._onClick)\n\t\t\t\t.off('pointerup', this._onClick);\n\n\t\t\tthis._onClickEl = null;\n\t\t}\n\t}\n});","/** \n * Listen to mouse scroll event\n * Make sure to turn on AllowResync if you need to reupdate other node\n * @blackprint node\n */\nBlackprint.registerNode('Input/Pointer/MouseScroll',\nclass MouseScrollNode extends Blackprint.Node {\n\tstatic input = {\n\t\t/** If this not connected to anything, this node will listen to window */\n\t\tElement: HTMLElement,\n\t\t/** Start listening to mouse click event */\n\t\tListen: Blackprint.Port.Trigger(function({ iface }){\n\t\t\tlet node = iface.node;\n\t\t\tnode.enabled = true;\n\t\t\tnode.update();\n\t\t}),\n\t\t/** Stop listener */\n\t\tUnlisten: Blackprint.Port.Trigger(function({ iface }){\n\t\t\tlet node = iface.node;\n\t\t\tnode.enabled = false;\n\t\t\tnode.update();\n\t\t}),\n\t};\n\n\tstatic output = {\n\t\t/** Raw event on pressed */\n\t\tEvent: Blackprint.Port.StructOf(Event, {\n\t\t\t/** Horizontal scroll */\n\t\t\tX: {type: Number, field: 'deltaX'},\n\t\t\t/** Vertical scroll (middle mouse scroll) */\n\t\t\tY: {type: Number, field: 'deltaY'},\n\t\t\t/** Z-axis scroll */\n\t\t\tZ: {type: Number, field: 'deltaZ'},\n\t\t}),\n\t};\n\n\tconstructor(instance){\n\t\tsuper(instance);\n\n\t\tlet iface = this.setInterface();\n\t\tiface.title = 'Mouse Scroll Event';\n\t\tiface.description = 'Listening to window';\n\t\tiface.type = 'event';\n\n\t\tthis.enabled = true;\n\t}\n\n\tinit(){\n\t\tthis.update();\n\t\tthis.iface.on('cable.disconnect', ({port}) => {\n\t\t\tif(port.name === 'Element'){\n\t\t\t\tthis.update();\n\t\t\t\tthis.routes.routeOut();\n\t\t\t}\n\t\t});\n\t}\n\n\tupdate(){\n\t\tlet { Input } = this.ref;\n\n\t\tif(this._onScroll != null){\n\t\t\t$(this._onScrollEl ?? allWindow).off('wheel', this._onScroll);\n\t\t\tthis._onScrollEl = null;\n\t\t}\n\n\t\tthis._onScroll = ev => this.onScroll(ev);\n\t\tlet el = Input.Element ?? allWindow;\n\n\t\tif(el === allWindow)\n\t\t\tthis.iface.description = 'Listening to window';\n\t\telse this.iface.description = 'Listening to element';\n\n\t\tif(!this.enabled){\n\t\t\tthis.iface.description = 'Not listening';\n\t\t\treturn;\n\t\t}\n\n\t\t$(el).on('wheel', this._onScroll);\n\t\tthis._onScrollEl = el;\n\t}\n\n\t_onScroll = null;\n\t_onScrollEl = null;\n\tonScroll(ev, _isSync){\n\t\t// Avoid receiving event from other window\n\t\tif(ev.view !== window) return;\n\n\t\tthis.ref.Output.Event = ev;\n\t\tthis.routes.routeOut();\n\n\t\tif(!_isSync) this.syncOut('wheel', {\n\t\t\tdx: ev.deltaX,\n\t\t\tdy: ev.deltaY,\n\t\t\tdz: ev.deltaZ,\n\t\t\tdm: ev.deltaMode,\n\t\t});\n\t}\n\n\tsyncIn(which, data){\n\t\tthis.onScroll(new WheelEvent('wheel', {\n\t\t\tdeltaX: data.dx,\n\t\t\tdeltaY: data.dy,\n\t\t\tdeltaZ: data.dz,\n\t\t\tdeltaMode: data.dm,\n\t\t}), true);\n\t}\n\n\tdestroy(){\n\t\tif(this._onScroll != null){\n\t\t\t$(this._onScrollEl ?? allWindow).off('wheel', this._onScroll);\n\t\t\tthis._onScrollEl = null;\n\t\t}\n\t}\n});","/** \n * Listen to mouse scroll event\n * Make sure to turn on AllowResync if you need to reupdate other node\n * @blackprint node\n */\nBlackprint.registerNode('Input/Pointer/Movement',\nclass PointerMovementNode extends Blackprint.Node {\n\tstatic input = {\n\t\t/** If this not connected to anything, this node will listen to window */\n\t\tElement: HTMLElement,\n\t\t/** Start listening to mouse click event */\n\t\tListen: Blackprint.Port.Trigger(function({ iface }){\n\t\t\tlet node = iface.node;\n\t\t\tnode.enabled = true;\n\t\t\tnode.update();\n\t\t}),\n\t\t/** Stop listener */\n\t\tUnlisten: Blackprint.Port.Trigger(function({ iface }){\n\t\t\tlet node = iface.node;\n\t\t\tnode.enabled = false;\n\t\t\tnode.update();\n\t\t}),\n\t};\n\n\tstatic output = {\n\t\t/** Raw event on pressed */\n\t\tEvent: Blackprint.Port.StructOf(Event, {\n\t\t\t/** Total X-axis movement after the previous 'pointermove' event */\n\t\t\tMoveX: {type: Number, field: 'moveX'},\n\t\t\t/** Total Y-axis movement after the previous 'pointermove' event */\n\t\t\tMoveY: {type: Number, field: 'moveY'},\n\t\t\t/** Pointer X-axis coordinate in local (DOM content) */\n\t\t\tClientX: {type: Number, field: 'clientX'},\n\t\t\t/** Pointer Y-axis coordinate in local (DOM content) */\n\t\t\tClientY: {type: Number, field: 'clientY'},\n\t\t\t/** Pointer X-axis coordinate in global (screen) */\n\t\t\tScreenX: {type: Number, field: 'screenX'},\n\t\t\t/** Pointer Y-axis coordinate in global (screen) */\n\t\t\tScreenY: {type: Number, field: 'screenY'},\n\t\t}),\n\t};\n\n\tconstructor(instance){\n\t\tsuper(instance);\n\n\t\tlet iface = this.setInterface();\n\t\tiface.title = 'Pointer Move Event';\n\t\tiface.description = 'Listening to window';\n\t\tiface.type = 'event';\n\n\t\tthis.enabled = true;\n\t}\n\n\tinit(){\n\t\tthis.update();\n\t\tthis.iface.on('cable.disconnect', ({port}) => {\n\t\t\tif(port.name === 'Element'){\n\t\t\t\tthis.update();\n\t\t\t\tthis.routes.routeOut();\n\t\t\t}\n\t\t});\n\t}\n\n\tupdate(){\n\t\tlet { Input } = this.ref;\n\n\t\tif(this._onMove != null){\n\t\t\t$(this._onMoveEl ?? allWindow).off('pointermove', this._onMove);\n\t\t\tthis._onMoveEl = null;\n\t\t}\n\n\t\tthis._onMove = ev => this.onMove(ev);\n\t\tlet el = Input.Element ?? allWindow;\n\n\t\tif(el === allWindow)\n\t\t\tthis.iface.description = 'Listening to window';\n\t\telse this.iface.description = 'Listening to element';\n\n\t\tif(!this.enabled){\n\t\t\tthis.iface.description = 'Not listening';\n\t\t\treturn;\n\t\t}\n\n\t\t$(el).on('pointermove', this._onMove);\n\t\tthis._onMoveEl = el;\n\t}\n\n\t_onMove = null;\n\t_onMoveEl = null;\n\tonMove(ev){\n\t\t// Avoid receiving event from other window\n\t\tif(ev.view !== window) return;\n\n\t\tthis.ref.Output.Event = ev;\n\t\tthis.routes.routeOut();\n\n\t\t// no sync because there will too many event need to be synced\n\t}\n\n\tdestroy(){\n\t\tif(this._onMove != null){\n\t\t\t$(this._onMoveEl ?? allWindow).off('pointermove', this._onMove);\n\t\t\tthis._onMoveEl = null;\n\t\t}\n\t}\n});","/**\n * User Interface (UI) for calling a function port\n * @blackprint node\n */\nBlackprint.registerNode('Input/UI/Button',\nclass extends Blackprint.Node {\n  static output = {\n    /** Call every function port */\n    Clicked: Blackprint.Types.Trigger\n  };\n\n  constructor(instance){\n    super(instance);\n\n    let iface = this.setInterface('BPIC/Input/UI/Button');\n    iface.title = \"Button\";\n  }\n\n  syncIn(key, val){\n    if(key === 'clicked') this.output.Clicked();\n  }\n});\n\nBlackprint.registerInterface('BPIC/Input/UI/Button',\nContext.IFace.Button = class ButtonIFace extends Blackprint.Interface {\n  clicked(ev){\n    this.node.output.Clicked();\n    this.node.syncOut('clicked');\n  }\n});","/**\n * User Interface for handling file input\n * @blackprint node\n */\nBlackprint.registerNode('Input/UI/File',\nclass FileNode extends Blackprint.Node {\n\t// Let's declare the Node port's outputs\n\tstatic output = {\n\t\t/** Blob URL that can only be used locally in this browser */\n\t\tURL: String,\n\t\t/** Blob Object */\n\t\tBlob: Blob,\n\t}\n\n\tconstructor(instance){\n\t\tsuper(instance);\n\n\t\t// Let's use an Interface\n\t\tlet iface = this.setInterface('BPIC/Input/UI/File');\n\t\tiface.title = 'File loader'; // Give it a name\n\t}\n});\n\nBlackprint.registerInterface('BPIC/Input/UI/File',\nContext.IFace.File = class FileIFace extends Blackprint.Interface {\n\tconstructor(node){\n\t\tsuper(node);\n\n\t\tthis.file = null;\n\t\tthis.name = '';\n\n\t\t// Create input element for browse/dropping file\n\t\tlet inputEl = this.inputEl = document.createElement('input');\n\t\tinputEl.type = 'file';\n\n\t\t// Listen to the input element if it has been changed\n\t\tlet that = this;\n\t\tinputEl.addEventListener('input', function(){\n\t\t\tthat.setFile(that.inputEl.files[0]);\n\t\t});\n\t}\n\n\tsetFile(file){\n\t\tthis.name = file.name;\n\n\t\tlet node = this.node;\n\t\tnode.output.Blob = file;\n\n\t\tURL.revokeObjectURL(node.output.URL);\n\t\tnode.output.URL = URL.createObjectURL(file);\n\t\tnode.routes.routeOut();\n\t}\n\n\tbrowseFile(ev){\n\t\tthis.inputEl.click();\n\t}\n});","/**\n * User Interface for handling number input with a horizontal slider\n * @blackprint node\n */\nBlackprint.registerNode('Input/UI/SliderBox',\nclass SliderBoxNode extends Blackprint.Node {\n\tstatic output = {\n\t\t/** You can also right click to create a new port */\n\t\t\"0\": Blackprint.Port.Default(Number, 0),\n\t};\n\n\tconstructor(instance){\n\t\tsuper(instance);\n\n\t\tlet iface = this.setInterface('BPIC/Input/UI/SliderBox');\n\t\tiface.title = 'Slider Box';\n\t}\n\n\t// Callback when this single node was loaded\n\t// Lets handle saved data\n\timported(data){\n\t\tif(data === void 0)\n\t\t\treturn;\n\n\t\tlet node = this;\n\t\tlet iface = this.iface;\n\n\t\t// Assign the first one\n\t\tObject.assign(iface.data[0], data['0']);\n\n\t\t// Set current port value\n\t\tnode.output['0'] = data['0'].value;\n\n\t\tvar length = objLength(data);\n\t\tif(length === 1)\n\t\t\treturn;\n\n\t\t// Create new port handler if data is more than one\n\t\tfor (var i = 1; i < length; i++){\n\t\t\t// Equal to 'iface.data.push({...})'\n\t\t\tiface.createPort();\n\n\t\t\tlet key = i+'';\n\n\t\t\t// Because it object property, we need to cast as string\n\t\t\tvar val = data[key];\n\n\t\t\t// Assign object values into data\n\t\t\tObject.assign(iface.data[i], val);\n\n\t\t\t// Add new port and set current port value\n\t\t\tnode.createPort('output', i, Number);\n\t\t\tnode.output[key] = val.value;\n\t\t}\n\t}\n\n\t// Callback when all nodes in container was loaded\n\tinit(){\n\t\tlet node = this;\n\t\tlet iface = this.iface;\n\n\t\t// Put this array here, and reuse when port menu event\n\t\tvar portMenu = [{\n\t\t\ttitle:\"Create port\", callback(){\n\t\t\t\t// Always create on last position -> (key, default value)\n\t\t\t\tnode.createPort('output', iface.data.length, Number);\n\t\t\t\tiface.createPort();\n\t\t\t}\n\t\t}, {\n\t\t\ttitle:\"Delete last port\", callback(){\n\t\t\t\tvar length = iface.data.length;\n\t\t\t\tif(length === 1)\n\t\t\t\t\treturn;\n\n\t\t\t\tnode.deletePort('output', length - 1);\n\t\t\t\tiface.data.pop();\n\t\t\t}\n\t\t}];\n\n\t\tiface.on('port.menu', Context.EventSlot, function({ port, menu }){\n\t\t\tfor (var i = 0; i < portMenu.length; i++) {\n\t\t\t\t// Change every callback context to refer current port\n\t\t\t\tlet temp = portMenu[i];\n\n\t\t\t\ttemp.context = port;\n\t\t\t\tmenu.push(temp);\n\t\t\t}\n\t\t});\n\t}\n\n\tsyncIn(evName, data){\n\t\tif(evName === 'data'){\n\t\t\tlet iface = this.iface;\n\t\t\tObject.assign(iface.data, data);\n\n\t\t\tfor (var i = 0; i < data.length; i++) {\n\t\t\t\tiface.changed(i, data[i].value);\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Save it on Context, so we can also access it from .sf files\nBlackprint.registerInterface('BPIC/Input/UI/SliderBox',\nContext.IFace.SliderBoxIFace = class SliderBoxIFace extends Blackprint.Interface {\n\tconstructor(node){\n\t\tsuper(node);\n\n\t\tthis.focusIndex = void 0;\n\t\tthis.data = [];\n\t\tthis.createPort(); // port: 0\n\t}\n\n\tchanged(index, val){\n\t\tlet node = this.node;\n\t\tnode.output[index] = val;\n\t\tnode.routes.routeOut();\n\n\t\t// Already throttled before being send to remote\n\t\tnode.syncOut('data', this.data);\n\t}\n\n\t// Put this here to reduce memory usage because of function creation\n\t// And reuse it on every node.data's item\n\tvalueListener(now){\n\t\t// 'this' == current object item\n\n\t\tif(now > this.max)\n\t\t\tnow = this.max;\n\t\telse if(now < this.min)\n\t\t\tnow = this.min;\n\t\telse // Fix floating point\n\t\t\tnow = Math.round(now*100)/100;\n\n\t\tlet iface = this._iface;\n\n\t\t// Wait until the data has been changed\n\t\tclearTimeout(this._wait);\n\t\tthis._wait = setTimeout(()=> iface.changed(iface.focusIndex, now), 1);\n\n\t\t// Let editor know if this iface changed and unsaved\n\t\tthis.node.notifyEditorDataChanged();\n\n\t\treturn now;\n\t}\n\n\tcreatePort(){\n\t\tthis.data.push({\n\t\t\tvalue: 0,\n\t\t\tmin: -100,\n\t\t\tmax: 100,\n\t\t\tstep: 0.1,\n\t\t\t_iface: this, // For reference in valueListener\n\n\t\t\t// Listener if value changed\n\t\t\ton$value: this.valueListener,\n\t\t});\n\n\t\t// Let editor know if this iface changed and unsaved\n\t\tthis.node.notifyEditorDataChanged();\n\t}\n});","/**\n * User Interface for handling text input\n * @blackprint node\n */\nBlackprint.registerNode('Input/UI/TextBox',\nclass extends Blackprint.Node {\n\t// Output Port's Template (This will be transformed to it's type after initialized)\n\tstatic output = {\n\t\t/** This can be used to call a function every time the value was changed */\n\t\tChanged: Blackprint.Types.Trigger,\n\t\t/** Input box's text value */\n\t\tValue: String,\n\t};\n\n\tconstructor(instance){\n\t\tsuper(instance);\n\n\t\tlet iface = this.setInterface('BPIC/Input/UI/TextBox'); // Let's use ./input.js\n\t\tiface.title = \"Input\";\n\t}\n\n\t// Bring value from imported node to handle output\n\timported(data){\n\t\tlet iface = this.iface;\n\n\t\tif(data === undefined) return;\n\n\t\t// Use object assign to avoid replacing the object reference\n\t\tObject.assign(iface.data, data);\n\t\tthis.output.Value = data.value;\n\t}\n\n\t// Proxy string value from: node.changed -> node.changed -> output.Value\n\t// And also call output.Changed() if connected to other node\n\tchanged(text, ev){\n\t\tlet iface = this.iface;\n\n\t\t// This node still being imported\n\t\tif(iface.importing !== false)\n\t\t\treturn;\n\n\t\t// iface.data.value === text;\n\t\tthis.output.Value = iface.data.value;\n\t\tthis.syncOut('data', {value: iface.data.value});\n\n\t\t// This will call every connected node\n\t\tthis.output.Changed();\n\t}\n\n\t// Remote sync in\n\tsyncIn(id, data){\n\t\tif(id === 'data'){\n\t\t\tObject.assign(this.iface.data, data);\n\t\t\tthis.changed();\n\t\t}\n\t}\n});\n\n\n// Register Interface\n// Interface will be exposed to public and being attached for a node\n// it's just like API or User Interface (on sketch editor)\n// Let's think you're creating a library, these properties can be accessed by other developers\nBlackprint.registerInterface('BPIC/Input/UI/TextBox',\nContext.IFace.Input = class InputIFace extends Blackprint.Interface{\n\tconstructor(node){\n\t\tsuper(node);\n\t\tthis.data = new InputTextBoxData(this);\n\t}\n});\n\nclass InputTextBoxData {\n\t#iface = null;\n\n\tconstructor(iface){\n\t\tthis.#iface = iface;\n\t}\n\n\t// Use underscore \"_\" or \"$\" to avoid being exported as JSON\n\t#value = '';\n\n\tget value(){ return this.#value }\n\tset value(val){\n\t\tif(this.#value === val) return;\n\t\tthis.#value = val;\n\n\t\tlet node = this.#iface.node;\n\t\tnode.changed(val);\n\t\tnode.routes.routeOut();\n\n\t\t// Let editor know if this iface changed and unsaved\n\t\tnode.notifyEditorDataChanged();\n\t}\n}\n\n// Using getter/setter will make the property not enumerable and Blackprint will skip that property when exporting\nBlackprint.utils.setEnumerablePrototype(InputTextBoxData, {\n\tvalue: true,\n});"]}