@kemu-io/edge-runtime 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/package.json +42 -0
  2. package/runner.d.ts +89 -0
  3. package/runner.js +1 -0
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@kemu-io/edge-runtime",
3
+ "type": "module",
4
+ "version": "0.1.2",
5
+ "description": "Kemu Edge runtime for running Kemu recipes",
6
+ "author": "Kemu Pty Ltd",
7
+ "main": "runner.js",
8
+ "module": "runner.js",
9
+ "types": "runner.d.ts",
10
+ "publishConfig": {
11
+ "registry": "https://registry.npmjs.org/"
12
+ },
13
+ "exports": {
14
+ ".": {
15
+ "import": "./runner.js",
16
+ "require": "./runner.js"
17
+ }
18
+ },
19
+ "files": [
20
+ "runner.js",
21
+ "runner.d.ts"
22
+ ],
23
+ "dependencies": {
24
+ "@napi-rs/canvas": "^0.1.53",
25
+ "debug": "^4.3.5",
26
+ "emittery": "^1.0.3",
27
+ "minimist": "^1.2.8",
28
+ "compare-versions": "^6.1.1",
29
+ "node-ipc": "10.1.0",
30
+ "axios": "^1.7.2",
31
+ "crypto-js": "^4.2.0",
32
+ "jsonp": "^0.2.1",
33
+ "jszip": "^3.10.1",
34
+ "microseconds": "^0.2.0",
35
+ "nanoid": "^3.3.7",
36
+ "@paralleldrive/cuid2": "^2.2.2",
37
+ "js-yaml": "^4.1.0",
38
+ "sharp": "^0.33.4",
39
+ "unzipper": "^0.12.1",
40
+ "ws": "^8.17.0"
41
+ }
42
+ }
package/runner.d.ts ADDED
@@ -0,0 +1,89 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ export type KemuObjectWrapper<O, DT extends DataType> = O & {
4
+ _kemuType: DT;
5
+ };
6
+ export type ImageDataLike = KemuObjectWrapper<{
7
+ /** the raw image data */
8
+ data: Uint8ClampedArray;
9
+ /** the width of the image */
10
+ width: number;
11
+ /** the height of the image */
12
+ height: number;
13
+ colorSpace: string;
14
+ }, DataType.ImageData>;
15
+ export type Rect = {
16
+ width: number;
17
+ height: number;
18
+ top: number;
19
+ left: number;
20
+ };
21
+ export type Point = {
22
+ x: number;
23
+ y: number;
24
+ };
25
+ export type BinaryFile<D extends ArrayBuffer | Uint8Array | Uint8ClampedArray | Buffer = ArrayBuffer> = {
26
+ format: string;
27
+ data: D;
28
+ };
29
+ /**
30
+ * Valid Kemu Data types
31
+ **/
32
+ export declare enum DataType {
33
+ Number = 0,
34
+ String = 1,
35
+ ArrayBuffer = 2,
36
+ Array = 3,
37
+ Boolean = 4,
38
+ /** a javascript object */
39
+ JsonObj = 5,
40
+ /**
41
+ * Does not care; mostly used by actions to indicate they accept anything since they probably won't use the
42
+ * value.
43
+ **/
44
+ Anything = 6,
45
+ /** Raw image data, produced in browser environments */
46
+ ImageData = 7,
47
+ /** Raw audio data fraction */
48
+ AudioBuffer = 8,
49
+ Rect = 9,
50
+ Point = 10,
51
+ ImageBitmap = 11,
52
+ /**
53
+ * Custom binary data. Use the `format` property to specify the type of data, i.e. 'image/png', 'audio/mp3', etc.
54
+ **/
55
+ BinaryFile = 12
56
+ }
57
+ export type JsonType = {
58
+ [key: string]: SupportedTypes;
59
+ };
60
+ export type KemuType = number | string | ArrayBuffer | JsonType | boolean | ImageData | AudioBuffer | Rect | Point | ImageBitmap | BinaryFile;
61
+ export type SupportedTypes = KemuType | KemuType[];
62
+ /** Type passed around between gates and blocks */
63
+ export type Data = {
64
+ /** the type of data represented */
65
+ type: DataType;
66
+ value: SupportedTypes;
67
+ /** original time when the event was first picked up by an input gate. */
68
+ timestamp: number;
69
+ };
70
+ export type PartialData = Omit<Data, "timestamp">;
71
+ export declare const utils: {
72
+ createImageDataLike: (buffer: Uint8ClampedArray | ArrayBuffer | Buffer, width: number, height: number, colorSpace?: string) => ImageDataLike;
73
+ };
74
+ declare const _default: {
75
+ start: (config?: {
76
+ /** path to the recipe file or containing directory */
77
+ recipePath?: string;
78
+ }) => Promise<{
79
+ /** use it to send data to input widgets */
80
+ sendToInputWidget: (inputName: string, data: PartialData, thingId?: string | undefined) => Promise<void>;
81
+ }>;
82
+ terminate: () => Promise<void>;
83
+ };
84
+
85
+ export {
86
+ _default as default,
87
+ };
88
+
89
+ export {};
package/runner.js ADDED
@@ -0,0 +1 @@
1
+ import{readFile as e,access as t}from"node:fs/promises";import{nanoid as n}from"nanoid";import r from"jsonp";import a from"crypto-js";import i from"util";import o from"emittery";import"axios";import s from"jszip";import{satisfies as c,compare as u}from"compare-versions";import d from"debug";import l,{join as p,resolve as g,dirname as m}from"path";import v from"node-ipc";import{readFile as f,access as y,constants as h,rm as I,mkdir as S}from"fs/promises";import $ from"minimist";import w,{promises as b}from"fs";import{spawn as N}from"child_process";import{createHash as A}from"crypto";import{homedir as x}from"os";import{WebSocketServer as P}from"ws";import{fileURLToPath as C}from"url";import E from"node:os";import{exec as j}from"node:child_process";import{createId as k}from"@paralleldrive/cuid2";import{dirname as D,join as O,resolve as T}from"node:path";import{ImageData as L,createCanvas as M}from"@napi-rs/canvas";var B;!function(e){e.STARTING="STARTING",e.PENDING="PENDING",e.RUNNING="RUNNING",e.PAUSED="PAUSED",e.DRAINING="DRAINING",e.STOPPED="STOPPED",e.ERROR="ERROR"}(B=B||(B={}));const R={};let W=0,U="";const F=e=>R[e]?R[e]:null,_=(e,t)=>{const n=F(e);if(!n)return n;return n.blocks[t]||null},G=(e,t,n)=>{const r=_(e,t);if(!r)return r;return r.gates[n]},z=(e,t)=>{let r=n(4);for(;R[r];)r=n(4);const a=(i=e,JSON.parse(JSON.stringify(i)));var i;return a.logs="",a.addLog=e=>{a.logs+=`${(()=>{const e=Date.now();if(e!==W){const t=new Date;W=e,U=t.toJSON()}return U})()}:: ${e}\n`},a.dbInfo={...t},R[r]=a,r},V="interrupt_port",H="main.js",J="state.json",q="{#}",K="$var_",X="default";var Y,Z,Q,ee,te,ne,re,ae;!function(e){e.Browser="browser",e.Cloud="cloud",e.Desktop="desktop"}(Y||(Y={})),function(e){e[e.Number=0]="Number",e[e.String=1]="String",e[e.ArrayBuffer=2]="ArrayBuffer",e[e.Array=3]="Array",e[e.Boolean=4]="Boolean",e[e.JsonObj=5]="JsonObj",e[e.Anything=6]="Anything",e[e.ImageData=7]="ImageData",e[e.AudioBuffer=8]="AudioBuffer",e[e.Rect=9]="Rect",e[e.Point=10]="Point",e[e.ImageBitmap=11]="ImageBitmap",e[e.BinaryFile=12]="BinaryFile"}(Z||(Z={})),function(e){e.Number="Number",e.String="String",e.ArrayBuffer="ArrayBuffer",e.Array="Array",e.Boolean="Boolean",e.JsonObj="JsonObj",e.Anything="Anything",e.ImageData="ImageData",e.AudioBuffer="AudioBuffer",e.Rect="Rect",e.Point="Point",e.ImageBitmap="ImageBitmap",e.BinaryFile="BinaryFile"}(Q||(Q={})),function(e){e.Javascript="js",e.Python="py",e.Executable="exe"}(ee||(ee={})),function(e){e.IpcAcknowledge="iack:",e.SocketAcknowledge="sack:",e.AcknowledgeResponse="ackr:",e.ServicesListChanged="update-services",e.SendManifest="send-manifest",e.BroadcastStart="broadcast-start",e.BroadcastEnd="broadcast-end",e.AssumeSession="assume:"}(te||(te={})),function(e){e.GetServices="getServices",e.SubscribeToService="subscribeToService",e.UnsubscribeFromService="unsubscribeFromService",e.GetServiceContents="getServiceContents",e.OnParentEvent="onParentEvent",e.GetDefaultState="getDefaultState",e.BroadcastEvent="broadcastEvent",e.HubBroadcastEvent="hubBroadcastEvent",e.ServiceManifest="serviceManifest",e.GetState="getState",e.SetState="setState",e.SetOutputs="setOutputs",e.UIEvent="uiEvent",e.InitializeInstance="initializeInstance",e.TerminateInstance="terminateInstance",e.ChooseDirectoryDialog="chooseDirectoryDialog",e.ChooseFileDialog="chooseFileDialog",e.GetUniqueId="getUniqueId"}(ne||(ne={})),function(e){e.SetDependencyPath="setDependencyPath",e.GetDependencyPath="getDependencyPath"}(re||(re={})),function(e){e.IPC="ipc",e.WS="ws"}(ae||(ae={}));const ie="undefined"!=typeof window&&void 0!==window.document&&void 0!==typeof window.document.createElement,oe="object"==typeof self&&self.constructor&&"DedicatedWorkerGlobalScope"===self.constructor.name,se="undefined"!=typeof process&&null!=process.versions&&null!=process.versions.node,ce="-",ue=`inner${ce}`,de=`outer${ce}`,le=`${de}input${ce}`,pe=`${de}output${ce}`,ge=`${ue}input${ce}`,me=`${ue}output${ce}`,ve=e=>(new TextEncoder).encode(e),fe=e=>e===V,ye=e=>e&&void 0!==e.width&&void 0!==e.height&&void 0!==e.data&&e.data.constructor&&"Uint8ClampedArray"===e.data.constructor.name,he=e=>e&&void 0!==e.width&&void 0!==e.height&&void 0!==e.top&&void 0!==e.left&&"number"==typeof e.width&&"number"==typeof e.height&&"number"==typeof e.top&&"number"==typeof e.left,Ie=e=>e&&"number"==typeof e.x&&"number"==typeof e.y,Se=e=>"number"==typeof e?Z.Number:"string"==typeof e?Z.String:"boolean"==typeof e?Z.Boolean:Array.isArray(e)?Z.Array:ye(e)?Z.ImageData:e&&void 0!==e.duration&&void 0!==e.length&&void 0!==e.numberOfChannels&&void 0!==e.sampleRate&&"function"==typeof e.getChannelData&&"AudioBuffer"===e.constructor.name?Z.AudioBuffer:e&&void 0!==e.byteLength?Z.ArrayBuffer:he(e)?Z.Rect:e&&void 0!==e.x&&void 0!==e.y&&"number"==typeof e.x&&"number"==typeof e.y?Z.Point:Z.JsonObj,$e=e=>{const t={};let n;n=Array.isArray(e)?e[0]:e;for(const e in n){const r=Se(n[e]);t[e]=r}return t},we=(e,t,n)=>"inner"===e?"input"===t?`${ge}${n}`:`${me}${n}`:"input"===t?`${le}${n}`:`${pe}${n}`,be=e=>{const t=(e||"")?.split("_");if(t.length<3)throw new Error(`Unknown child identifier format [${e}]`);const n=t[0];return{portType:t[1],widgetId:n,portName:t[2]}},Ne=e=>new ImageData(e.data,e.width,e.height,{colorSpace:e.colorSpace});var Ae,xe;!function(e){e.Action="action",e.CustomInput="customInput"}(Ae=Ae||(Ae={})),function(e){e.input="input",e.counter="counter",e.play="play",e.elapsed="elapsed",e.ifGate="ifGate",e.skipEvent="skipEvent",e.between="between",e.map="map",e.parser="parser",e.slider="slider",e.suspend="suspend",e.display="display",e.json="json",e.arrayItem="arrayItem",e.extractImage="extractImage",e.imageConvolution="imageConvolution",e.firstEvent="firstEvent",e.pixelDraw="pixelDraw",e.randomBetween="randomBetween",e.arrayCombine="arrayCombine",e.clock="clock",e.multiplication="multiplication",e.object="object",e.widgetGroup="widgetGroup",e.script="script",e.base64ToImageData="base64ToImageData",e.jsonParse="jsonParse",e.text="text",e.imageCrop="imageCrop",e.imageResize="imageResize",e.value="value",e.imageWarp="imageWarp",e.widgetBundle="widgetBundle",e.sequence="sequence",e.variable="variable",e.hubService="hubService"}(xe=xe||(xe={}));const Pe={};let Ce;const Ee=async e=>{const t=Pe[e],n={name:V,type:Z.Boolean};if(t){const r={name:t.portName},a=t.data||{type:Z.Boolean,value:!0};Ce?(await Ce(!0,t.targetWidgetId,t.thingId,t.recipePoolId,n.name,r,{...a,timestamp:Date.now()},[n]),"timeout"===t.type&&je(e)):console.warn("Interrupt service has not been initialized")}},je=e=>{const t=Pe[e];return!!t&&(t.timerRef&&("interval"===t.type?clearInterval(t.timerRef):"timeout"===t.type&&clearTimeout(t.timerRef)),delete Pe[e],!0)};var ke={interruptHandler:Ee,createInterrupt:(e,t,r,a,i,o,s,c)=>{if(c&&Pe[c])throw new Error("The given interrupt id already exists");const u=c||n().replace(/_/g,"-");if("interval"===e&&!o.interval)throw new Error(`Invalid interval. Expected a number greater than 0, but got '${o.interval}'`);if("timeout"===e&&!o.timeout)throw new Error(`Invalid timeout. Expected a number greater than 0, but got '${o.timeout}'`);if(Pe[u]={data:s,portName:i,recipePoolId:t,targetWidgetId:a,thingId:r,type:e},"interval"===e)Pe[u].timerRef=setInterval((async()=>await Ee(u)),o.interval);else{if("timeout"!==e)throw new Error(`Invalid interrupt type '${e}'`);Pe[u].timerRef=setTimeout((async()=>await Ee(u)),o.timeout)}return u},destroyInterrupt:je,destroyAllInterrupts:()=>{Object.keys(Pe).forEach(je)},setInvokeChildGateCb:e=>{Ce=e}};const De=(e,t,n,r,a)=>{const i=G(e,n,r);if(!i)return console.warn(`Gate ${r} not found in block ${n} for recipe ${e}`),null;const o=(t,a,i,o)=>ke.createInterrupt(t,e,n,r,a,i,o),s=()=>Object.freeze({...i.state,...i.type===xe.input&&{customInputs:[]}}),c=e=>{if("object"!=typeof e)return void console.warn(`Invalid state type [${typeof e}]. Expected an 'object'`);const t={...e,...i.type===xe.input&&!e.customInputs&&{customInputs:[]}};i.state=t};if(a){return{getState:s,setState:c,registerInterrupt:o,getStorageData:async t=>{const r=((e,t,n)=>{const r=F(e);if(!r)throw new Error(`Recipe [${e} does not exist]`);if(!r.storage)return null;const a=_(e,t);if(!a)throw new Error(`The Thing "${t}" does not exist in recipe ${e}`);if(!(a.storageUnits||[]).includes(n))throw new Error(`The Thing "${t}" has no access to storage unit "${n}"`);return r.storage[n]||null})(e,n,t);return r},recipePoolId:e,recipeType:t,thingRecipeId:n,widgetThingId:r}}return{getState:s,setState:c,recipePoolId:e,widgetId:r}},Oe=[10001,"Invalid `sourcePort` parameter"],Te=[10002,"The gate [%s] does not exist. Have you called `loadWidgets` yet?"],Le=[10110,"No storage medium has been loaded, call `loadMedium()` first"],Me=(e,...t)=>JSON.stringify({code:e[0],message:t[0]?i.format(e[1],...t):e[1].replace(/ \[%s\]/g,"")}),Be=()=>({inputName:"",dataType:Z.Anything}),Re="output",We={processEvent:async(e,t)=>{const n=t.getState(),r={...Be(),...n};if(e.type===r.dataType)return t.nextWidget(Re,{type:e.type,value:e.value});console.error(`Invalid data type: ${e.type} for input: ${r.inputName}. Expected: ${r.dataType}`)},getOutputNames:e=>{const t={...Be(),...e};return[{name:Re,type:t.dataType}]},getInputNames:()=>[]},Ue=Object.freeze({in:"in",reset:"reset",increment:"increment"}),Fe="output";var _e={onParentEvent:async(e,t,n,r)=>{if(!e)throw new Error(Me(Oe));const a={currentValue:0,increment:1,...r.getState()};let i=a.increment,o=a.currentValue;const s=await r.getParentAtPort(Ue.increment);if(t.name===Ue.increment)return void(n.data.type===Z.Number&&r.setState({...a,increment:Number(n.data.value)}));if(s){const e=s.getValue();null!==e&&(i=e)}if(t.name===Ue.reset)return r.setState({...a,currentValue:0});o+=i,r.setState({currentValue:o,increment:i});const c={type:Z.Number,value:o};return r.nextGate(Fe,c)},getInputNames:()=>[{name:Ue.in,type:Z.Anything},{name:Ue.reset,type:Z.Anything},{name:Ue.increment,type:Z.Number}],getOutputNames:()=>[{name:Fe,type:Z.Number}]};const Ge=Object.freeze({in:"in",reset:"reset"}),ze="output";var Ve={onParentEvent:async(e,t,n,r)=>{const a={updatedAt:0,elapsed:0,...r.getState()},i=Date.now(),o=i-(a.updatedAt||i);return t.name===Ge.reset?r.setState({...a,updatedAt:i,elapsed:0}):(r.setState({updatedAt:i,elapsed:o}),r.nextGate(ze,{type:Z.Number,value:o}))},getInputNames:()=>[{name:Ge.in,type:Z.Anything},{name:Ge.reset,type:Z.Anything}],getOutputNames:()=>[{name:ze,type:Z.Number}]};const He=Object.freeze({data:"data",evaluation:"evaluation"}),Je="then",qe="else";var Ke={onParentEvent:async(e,t,n,r)=>{const a={value:5,condition:"Equal",useDataPort:!1,...r.getState()},i=n.data.value,o=!isNaN(Number(i)),s="string"==typeof i;if(!a.useDataPort&&(n.data.type===Z.Number||n.data.type===Z.String||n.data.type===Z.Anything&&o||n.data.type===Z.Anything&&s)){let e=!1;return("Equal"===a.condition&&n.data.value==a.value||"Not Equal"===a.condition&&n.data.value!==a.value||"Greater"===a.condition&&n.data.value>Number(a.value)||"Less"===a.condition&&n.data.value<Number(a.value)||"Starts With"===a.condition&&String(n.data.value).startsWith(String(a.value))||"Ends With"===a.condition&&String(n.data.value).endsWith(String(a.value))||"Includes"===a.condition&&String(n.data.value).includes(String(a.value))||"Matches"===a.condition&&String(n.data.value).match(String(a.value)))&&(e=!0),e?r.nextGate(Je,n.data):r.nextGate(qe,n.data)}if((t.name===He.evaluation&&n.data.type===Z.Number||n.data.type===Z.String||n.data.type===Z.Anything&&(o||s))&&(a.$lastValue=n.data.value,r.setState({...a})),t.name===He.data){let e=!1;return("Equal"===a.condition&&a.$lastValue==a.value||"Not Equal"===a.condition&&a.$lastValue!==a.value||"Greater"===a.condition&&Number(a.$lastValue)>Number(a.value)||"Less"===a.condition&&Number(a.$lastValue)<Number(a.value)||"Starts With"===a.condition&&String(a.$lastValue).startsWith(String(a.value))||"Ends With"===a.condition&&String(a.$lastValue).endsWith(String(a.value))||"Includes"===a.condition&&String(a.$lastValue).includes(String(a.value))||"Matches"===a.condition&&String(a.$lastValue).match(String(a.value)))&&(e=!0),r.setState({...a,$lastValue:void 0,$lastDataType:n.data.type}),e?r.nextGate(Je,n.data):r.nextGate(qe,n.data)}},getInputNames:e=>e.useDataPort?[{name:He.data,type:Z.Anything},{name:He.evaluation,type:[Z.Number,Z.String]}]:[{name:"in",type:[Z.Number,Z.String]}],getOutputNames:e=>e.$lastDataType?[{name:Je,type:e.$lastDataType},{name:qe,type:e.$lastDataType}]:[{name:Je,type:[Z.Number,Z.String]},{name:qe,type:[Z.Number,Z.String]}]};const Xe=Object.freeze({in:"in",reset:"reset"}),Ye="out";var Ze={onParentEvent:async(e,t,n,r)=>{const a={totalCalls:0,callsLimit:1,...r.getState()};return t.name===Xe.reset?r.setState({...a,totalCalls:0}):(a.totalCalls=a.totalCalls+1,a.totalCalls>a.callsLimit?(a.totalCalls=0,r.setState(a),r.nextGate(Ye,n.data)):void r.setState(a))},getInputNames:()=>[{name:Xe.in,type:Z.Anything},{name:Xe.reset,type:Z.Anything}],getOutputNames:()=>[{name:Ye,type:Z.Anything}]};const Qe=Object.freeze({in:"in"}),et="then",tt="else";var nt={onParentEvent:async(e,t,n,r)=>{const a={min:1,max:10,...r.getState()};if(n.data.type===Z.Number)return n.data.value>=a.min&&n.data.value<=a.max?r.nextGate(et,n.data):r.nextGate(tt,n.data)},getInputNames:()=>[{name:Qe.in,type:Z.Number}],getOutputNames:()=>[{name:et,type:Z.Number},{name:tt,type:Z.Number}]};const rt=Object.freeze({in:"in"}),at="out";var it={onParentEvent:async(e,t,n,r)=>{const a={clamp:!0,...r.getState()},i=Number(n.data.value);if(void 0!==a.fromMax&&void 0!==a.fromMin&&void 0!==a.toMax&&void 0!==a.toMin&&""!==a.fromMax&&""!==a.fromMin&&""!==a.toMax&&""!==a.toMin&&(n.data.type===Z.Number||n.data.type===Z.Anything&&!isNaN(Number(i)))){let e=((e,t,n,r,a)=>(e-t)*(a-r)/(n-t)+r)(i,Number(a.fromMin),Number(a.fromMax),Number(a.toMin),Number(a.toMax));if(isNaN(e))return;return a.clamp&&(e<Number(a.toMin)&&(e=Number(a.toMin)),e>Number(a.toMax)&&(e=Number(a.toMax))),r.nextGate(at,{type:Z.Number,value:Number(e)})}},getInputNames:()=>[{name:rt.in,type:Z.Number}],getOutputNames:()=>[{name:at,type:Z.Number}]};const ot=Object.freeze({in:"in"}),st="out";var ct={onParentEvent:async(e,t,n,r)=>{const a={convertTo:"Integer",floatPlaces:2,...r.getState()};let i=n.data.value;if(n.data.type===Z.Number||n.data.type===Z.Anything||n.data.type===Z.String){if((!isNaN(Number(i))||"string"==typeof i)&&!Array.isArray(i))return"Integer"===a.convertTo?i=parseInt(i):"Decimal"===a.convertTo?i=parseFloat(Number(i).toFixed(a.floatPlaces)):"String"===a.convertTo?i=String(i):"Abs"===a.convertTo?i=Math.abs(Number(i)):"Round"===a.convertTo&&(i=Math.round(Number(i))),r.nextGate(st,{type:"String"===a.convertTo?Z.String:Z.Number,value:i})}},getInputNames:()=>[{name:ot.in,type:Z.Number}],getOutputNames:e=>{const t="String"===e?.convertTo?Z.String:Z.Number;return[{name:st,type:t}]}};const ut=Object.freeze({in:"in"}),dt="out";var lt={onParentEvent:async(e,t,n,r)=>{const a={currentValue:50,min:0,max:100,...r.getState()};let i=!1;return a.currentValue<a.min&&(a.currentValue=a.min,i=!0),a.currentValue>a.max&&(a.currentValue=a.max,i=!0),i&&r.setState(a),r.nextGate(dt,{type:Z.Number,value:a.currentValue})},getInputNames:()=>[{name:ut.in,type:Z.Anything}],getOutputNames:()=>[{name:dt,type:Z.Number}]};const pt=Object.freeze({in:"in",reset:"reset"}),gt="out";var mt={onParentEvent:async(e,t,n,r)=>{const a={lastCalledAt:0,delayMs:500},i={lastCalledAt:0,delayMs:500,...r.getState()};if(t.name===pt.reset)return r.setState({...i,lastCalledAt:0});const o=Date.now(),s=o-i.lastCalledAt;return i.lastCalledAt===a.lastCalledAt||s>=i.delayMs&&i.delayMs>0?(i.lastCalledAt=o,r.setState(i),r.nextGate(gt,n.data)):void 0},getInputNames:()=>[{name:pt.in,type:Z.Anything},{name:pt.reset,type:Z.Anything}],getOutputNames:()=>[{name:gt,type:Z.Anything}]};const vt="in";var ft={onParentEvent:async()=>{},getInputNames:()=>[{name:vt,type:[Z.ImageData,Z.Number]}],getOutputNames:()=>[]};const yt=()=>({properties:[{label:"property1",name:"property1"}],detectedProperties:{}}),ht=(e,t)=>t.split(".").reduce(((e,t)=>null!=e?e[t]:e),e);var It={onParentEvent:async(e,t,n,r)=>{const a={properties:[{label:"property1",name:"property1"}],detectedProperties:{},...r.getState()},i=n?.data?.value,o=Array.isArray(i);if(n.data.type===Z.JsonObj||n.data.type===Z.Rect||n.data.type===Z.Anything||o){let e=!1;for(const t in i){const n=Se(i[t]),r=!!a.detectedProperties[t],o=a.detectedProperties[t]?.type!==n;if(!r||o){const r=n===Z.JsonObj||n===Z.Rect||n===Z.Array;a.detectedProperties[t]={type:n,...r?{shape:$e(i[t])}:void 0},e=!0}}if(o&&void 0===a.detectedProperties.length&&(a.detectedProperties.length={type:Z.Number}),e&&r.setState(a),i){const e=[];for(const t of a.properties||[]){const n=ht(i,t.label),o=t.label.includes(".");if(void 0!==n){const i=o?Se(n):void 0!==a.detectedProperties[t.label]?.type?a.detectedProperties[t.label].type:Z.Anything;e.push(r.nextGate(t.name,{type:i,value:n}))}}await Promise.allSettled(e)}}},getInputNames:()=>[{name:"in",type:Z.JsonObj}],getOutputNames:e=>{const t={properties:[{label:"property1",name:"property1"}],detectedProperties:{},...e};return t.properties.map((e=>{const n=void 0!==t.detectedProperties[e.label]?t.detectedProperties[e.label]?.type:Z.Anything,r=t.detectedProperties[e.label]?.shape||void 0,a="string"==typeof e;return{name:a?e:e.name,label:a?e:e.label,type:n,jsonShape:r}}))},getDefaultState:yt};const St="output",$t="noItem";var wt={onParentEvent:async(e,t,n,r)=>{const a={index:0,...r.getState()};let i=a.index;const o=n.data.value,s="string"==typeof n.data.value,c=Array.isArray(n.data.value);if(n.data.type===Z.Anything&&(c||s)||n.data.type===Z.String&&s||n.data.type===Z.Array&&c){i<0&&(i=o.length+i);const e=s?Z.String:Se(o[i]);return e!==a.$$lastDetectedType&&r.setState({...a,$$lastDetectedType:e}),void 0!==o[i]?r.nextGate(St,{value:o[i],type:e}):r.nextGate($t,{value:!0,type:Z.Boolean})}},getInputNames:()=>[{name:"in",type:[Z.Array,Z.String]}],getOutputNames:e=>[{name:St,type:e.$$lastDetectedType??Z.Anything},{name:$t,type:Z.Boolean}]};let bt;const Nt=e=>{bt=e},At=(e,t)=>(()=>{if(!bt)throw new Error("CanvasManager not set");return bt})().createCanvas(e,t),xt=e=>ie?e.getContext("2d",{willReadFrequently:!0}):e.getContext("2d"),Pt=Object.freeze({image:"image",rect:"rect"}),Ct="image";var Et={onParentEvent:async(e,t,n,r)=>{const a={offset:{height:0,left:0,top:0,width:0},...r.getState()},i=await r.getParentAtPort(Pt.rect),o=[Z.Anything,Z.Rect,Z.JsonObj];if(t.name!==Pt.rect){if(i){const e=i.getValue();null!==e&&(a.rect={...e},r.setState(a))}if(!ie)return n.data.type===Z.ImageData?r.nextGate(Ct,n.data):void 0;if(a.$$canvasFrom&&a.$$canvasFrom.getContext||(a.$$canvasFrom=At(320,240)),a.$$canvasTo&&a.$$canvasTo.getContext||(a.$$canvasTo=At(320,240)),(n.data.type===Z.ImageData||n.data.type===Z.Anything&&ye(n.data.value))&&!a.$$processing&&a.$$canvasFrom&&a.rect){const e=((e,t,n,r,a)=>{if(r&&r.getContext){const i=r.getContext("2d"),o=n.getContext("2d");if(i&&o){n.width=e.width,n.height=e.height,o.putImageData(e,0,0);const s={...a};a&&(s.height=Number(a.height),s.width=Number(a.width),s.left=Number(a.left),s.top=Number(a.top));const c={top:0,width:0,left:0,height:0,...s};return a&&(Number.isInteger(c.width)||(c.width=t.width*c.width),Number.isInteger(c.height)||(c.height=t.height*c.height),Number.isInteger(c.left)||(c.left=t.left+t.width*c.left),Number.isInteger(c.top)||(c.top=t.top+t.height*c.top)),r.width=t.width+c.width,r.height=t.height+c.height,i.drawImage(n,t.left+c.left,t.top+c.top,t.width+c.width,t.height+c.height,0,0,r.width+c.width,r.height+c.height),i.getImageData(0,0,r.width||1,r.height||1)}}return e})(n.data.value,a.rect,a.$$canvasFrom,a.$$canvasTo,a.offset);return r.nextGate(Ct,{type:Z.ImageData,value:e})}}else he(n.data.value)&&o.includes(n.data.type)&&r.setState({...a,rect:n.data.value})},getInputNames:()=>[{name:Pt.image,type:Z.ImageData},{name:Pt.rect,type:[Z.Rect,Z.JsonObj]}],getOutputNames:()=>[{name:Ct,type:Z.ImageData}]};const jt=(e,t)=>{const n=Math.round(Math.sqrt(t.length)),r=Math.floor(n/2),a=e.data,i=e.width,o=e.height,s=i,c=o,u=((e,t,n)=>{if(ie)return new ImageData(t,n);return console.warn("Node environment detected. Aborting new ImageData creation"),e})(e,s,c),d=u.data;for(let e=0;e<c;e++)for(let c=0;c<s;c++){const u=e,l=c,p=4*(e*s+c);let g=0,m=0,v=0,f=0;for(let e=0;e<n;e++)for(let s=0;s<n;s++){const c=u+e-r,d=l+s-r;if(c>=0&&c<o&&d>=0&&d<i){const r=4*(c*i+d),o=t[e*n+s];g+=a[r]*o,m+=a[r+1]*o,v+=a[r+2]*o,f+=a[r+3]*o}}d[p]=g,d[p+1]=m,d[p+2]=v,d[p+3]=f+1*(255-f)}return u},kt=[-1,0,1,-2,0,2,1,0,1],Dt=Object.freeze({image:"image"}),Ot="image";var Tt={onParentEvent:async(e,t,n,r)=>{const a=r.getState(),i={matrix:[...kt],...a};if(n.data.type===Z.ImageData||n.data.type===Z.Anything&&ye(n.data.value)){const e=jt(n.data.value,i.matrix);return r.nextGate(Ot,{type:Z.ImageData,value:e})}},getInputNames:()=>[{name:Dt.image,type:Z.ImageData}],getOutputNames:()=>[{name:Ot,type:Z.ImageData}]};const Lt=Object.freeze({output:"output",aborted:"aborted"}),Mt=()=>({inputs:2,matchingOutputs:!0,lastInputIndex:-1,delayMs:500,triggeredAt:0}),Bt=e=>{const t={inputs:2,matchingOutputs:!0,lastInputIndex:-1,delayMs:500,triggeredAt:0,...e},n=Array(t.inputs).fill(0).map(((e,t)=>({name:`input${t+1}`,type:Z.Anything})));return n.push({name:"reset",type:Z.Anything}),n};var Rt={onParentEvent:async(e,t,n,r)=>{const a={inputs:2,matchingOutputs:!0,lastInputIndex:-1,delayMs:500,triggeredAt:0,...r.getState()};if("reset"===t.name)return r.setState({...a,triggeredAt:0});const i=Date.now(),o=i-a.triggeredAt;if(a.triggeredAt&&!(o>=a.delayMs&&a.delayMs>0)&&a.delayMs)return r.nextGate(Lt.aborted,n.data);{a.triggeredAt=i;const e=Bt(a,(r.recipePoolId,r.recipeType,r.thingRecipeId,r.id)).findIndex((e=>e.name===t.name));-1!==e&&(a.lastInputIndex=e),a.matchingOutputs?-1!==e&&await r.nextGate(`output${e+1}`,n.data):await r.nextGate(Lt.output,n.data),r.setState(a)}},getInputNames:Bt,getOutputNames:e=>{const t={inputs:2,matchingOutputs:!0,lastInputIndex:-1,delayMs:500,triggeredAt:0,...e};if(e.matchingOutputs){const e=Array(t.inputs).fill(0).map(((e,t)=>({name:`output${t+1}`,type:Z.Anything})));return e.push({name:Lt.aborted,type:Z.Anything}),e}return[{name:Lt.output,type:Z.Anything},{name:Lt.aborted,type:Z.Anything}]},getDefaultState:Mt};const Wt=(e,t,n,r,a,i)=>{if(a){const o=e.measureText(a),s=o.fontBoundingBoxAscent+o.fontBoundingBoxDescent;e.fillStyle=r,e.fillRect(t,n-i,1.1*o.width,s),e.font=`${i}px Arial`,e.fillStyle="black",e.fillText(a,t,n)}},Ut=(e,t,n,r,a,i,o)=>{e.fillStyle=a,e.fillRect(t,n,r,r),Wt(e,t,n,a,i,o)},Ft=(e,t,n,r,a,i)=>{e.beginPath(),e.strokeStyle=r,e.lineWidth=n,e.rect(t.left,t.top,t.width,t.height),e.stroke();const o=n/2;Wt(e,t.left-o,t.top-o,r,a,i)},_t=Object.freeze({image:"image",pixels:"pixels"}),Gt="image";var zt={onParentEvent:async(e,t,n,r)=>{const a={fontSize:12,color:"#00ff00",size:2,...r.getState()},i=n.data.type===Z.ImageData||n.data.type===Z.Anything&&ye(n.data.value);if(t.name===_t.pixels){const e=((e,t)=>t===Z.Anything&&(ye(e)||Ie(e)||he(e)||Array.isArray(e))||t===Z.Array||t===Z.Rect||t===Z.Point)(n.data.value,n.data.type);if(!e)return;a.$$pixels=n.data.value}if(t.name===_t.image&&i){const e=n.data.value;a.$$memCanvas&&a.$$memCanvas.getContext||(a.$$memCanvas=At(e.width||1,e.height||1)),a.$$lastFrame=e}if(a.$$lastFrame&&a.$$pixels&&a.$$memCanvas){const e=(e=>{const{sourceImage:t,pixels:n,memCanvas:r,size:a,color:i,labelProp:o,fontSize:s}=e;if(r){const e=xt(r);if(e){r.width!==t.width&&(r.width=t.width),r.height!==t.height&&(r.height=t.height),e.putImageData(t,0,0);const c=Array.isArray(n)?n:[n];for(let t=0;t<c.length;t++){const n=c[t],r=o?n[o]:"";he(n)?Ft(e,n,a,i,r,s):Ie(n)&&Ut(e,n.x,n.y,a,i,r,s)}return e.getImageData(0,0,r.width,r.height)}}return t})({sourceImage:a.$$lastFrame,pixels:a.$$pixels||[],memCanvas:a.$$memCanvas,size:a.size,color:a.color,labelProp:a.labelProp,fontSize:a.fontSize});return r.setState({...a,$$lastFrame:void 0,$$pixels:void 0}),r.nextWidget(Gt,{type:Z.ImageData,value:e})}r.setState(a)},getInputNames:()=>[{name:_t.image,type:Z.ImageData},{name:_t.pixels,type:[Z.Rect,Z.Point,Z.Array]}],getOutputNames:()=>[{name:Gt,type:Z.ImageData}]};const Vt=Object.freeze({in:"in"}),Ht="output",Jt=e=>{const t=String(e).split(".");return t.length<2?0:t[1].length};var qt={onParentEvent:async(e,t,n,r)=>{const a={min:1,max:100,...r.getState()},i=!Number.isInteger(a.min),o=!Number.isInteger(a.max),s=i||o;let c=(u=a.min,d=a.max,Math.random()*(d-u)+u);var u,d;if(s){let e=0;if(i&&(e=Jt(a.min)),o){const t=Jt(a.max);t>e&&(e=t)}c=Number(c.toFixed(e))}else c=Math.floor(c);return r.nextGate(Ht,{type:Z.Number,value:c})},getInputNames:()=>[{name:Vt.in,type:Z.Anything}],getOutputNames:()=>[{name:Ht,type:Z.Number}]};const Kt=Object.freeze({output:"output",totalItems:"totalItems"}),Xt=Object.freeze({trigger:"trigger",clear:"clear"}),Yt=()=>({totalSentItems:-1,totalSentAt:0,$$list:[],$$outputShape:{},totalInputs:1}),Zt=async(e,t)=>t.nextGate(Kt.totalItems,{type:Z.Number,value:e});var Qt={onParentEvent:async(e,t,n,r)=>{const a={totalSentItems:-1,totalSentAt:0,$$list:[],$$outputShape:{},totalInputs:1,...r.getState()};if(t.name===Xt.clear)return a.$$list=[],a.properties?.autoFilled&&delete a.properties,r.setState(a),Zt(a.$$list.length,r);const i=t.name===Xt.trigger;if(!i)if(Array.isArray(n.data.value))n.data.type!==Z.Array&&n.data.type!==Z.Anything||(a.$$outputShape={...a.$$outputShape,...e?.jsonShape},a.$$list=a.$$list.concat(n.data.value),r.setState({...a}),await Zt(a.$$list.length,r));else{const t=`$$primitive_${Object.keys(a.$$outputShape).length}`;n.data.type===Z.JsonObj?a.$$outputShape={...a.$$outputShape,...e?.jsonShape?e.jsonShape:void 0}:a.$$outputShape={...a.$$outputShape,[t]:n.data.type},a.$$list.push(n.data.value),r.setState({...a}),await Zt(a.$$list.length,r)}if(i){Object.keys(a.$$outputShape).length&&(a.properties={autoFilled:!0,jsonShape:{...a.$$outputShape}});const e=a.$$list.length,t=[...a.$$list];return a.$$list=[],r.setState({...a}),await Zt(e,r),r.nextGate(Kt.output,{type:Z.Array,value:t})}},getInputNames:e=>{const t={totalSentItems:-1,totalSentAt:0,$$list:[],$$outputShape:{},totalInputs:1,...e},n=Array(t.totalInputs||1).fill(0).map(((e,t)=>({name:`array${t+1}`,type:Z.Array})));return n.push({name:Xt.clear,type:Z.Anything},{name:Xt.trigger,type:Z.Anything}),n},getOutputNames:e=>[{name:Kt.output,type:Z.Array,...e.properties?{jsonShape:e.properties?.jsonShape}:void 0},{name:Kt.totalItems,label:"Total Items",type:Z.Number}],getDefaultState:Yt};const en=Object.freeze({start:"start",stop:"stop"}),tn="output",nn="clock_interrupt";var rn={onParentEvent:async(e,t,n,r)=>{const a={enabled:!1,interval:1e3,intervalMode:"ms",...r.getState()};if(fe(e?.name||"")&&t.name===nn)return r.nextGate(tn,{type:Z.Boolean,value:!0});if(t.name===en.stop&&a.enabled&&a.$$interruptId){r.cancelInterrupt(a.$$interruptId)?(a.enabled=!1,a.$$interruptId=void 0,r.setState(a)):console.warn(`Failed to cancel interrupt [${a.$$interruptId}]`)}else t.name!==en.start||a.enabled||a.$$interruptId||(a.$$interruptId=r.registerInterrupt("interval",nn,{interval:a.interval}),a.enabled=!0,r.setState(a))},getInputNames:()=>[{name:en.start,type:Z.Anything},{name:en.stop,type:Z.Anything}],getOutputNames:()=>[{name:tn,type:Z.Boolean}],initialize:async e=>{const t=e.getState();if(t.enabled&&!t.$$interruptId){const n=e.registerInterrupt("interval",nn,{interval:t.interval});e.setState({...t,$$interruptId:n})}}};const an=Object.freeze({in:"in"}),on="output",sn=(e,t,n)=>"number"==typeof e?Number((e*t).toFixed(n)):e;var cn={onParentEvent:async(e,t,n,r)=>{const a={userProperties:[],factor:2,decimalPoints:2,...r.getState()},i=n.data.type;let o=n.data.value,s=!1;return e?.jsonShape&&(a.detectedInputJson={...a.detectedInputJson,...e?.jsonShape},s=!0),a.detectedInputType||(a.detectedInputType=i,s=!0),n.data.type===Z.Array&&("number"==typeof n.data.value?.[0]?o=((e,t,n)=>{const r=(e||[]).map((e=>sn(e,t,n)));return r})(n.data.value,a.factor,a.decimalPoints):"object"==typeof n.data.value?.[0]&&(o=((e,t,n,r)=>{const a=(e||[]).map((e=>{const a={...e};return Object.keys(a).forEach((e=>{r?.length&&!r?.includes(e)||(a[e]=sn(a[e],t,n))})),a}));return a})(n.data.value,a.factor,a.decimalPoints,a.userProperties))),n.data.type===Z.Number&&(o=sn(n.data.value,a.factor,a.decimalPoints)),s&&r.setState(a),r.nextGate(on,{type:i,value:o})},getInputNames:()=>[{name:an.in,type:[Z.Array,Z.Number]}],getOutputNames:e=>[{name:on,type:e.detectedInputType||Z.Number,jsonShape:e.detectedInputJson}]};const un=Object.freeze({output:"output"}),dn=Object.freeze({trigger:"trigger"}),ln=()=>({useTriggerPort:!0,properties:[{name:"x",label:"x",type:Z.Number,value:10},{name:"y",label:"y",type:Z.Number,value:20}]}),pn=e=>{const t={};for(let n=0;n<e.properties.length;n++)t[e.properties[n].label]=e.properties[n].type;return t},gn=e=>{const t={};for(let n=0;n<e.properties.length;n++){let r=e.properties[n].value;const a=e.properties[n].type;a===Z.Number?r=Number(r):a===Z.String&&(r=String(r)),t[e.properties[n].label]=r}return t};var mn={onParentEvent:async(e,t,n,r)=>{const a=r.getState(),i=structuredClone(a),o={...ln(),...i};if(t.name===dn.trigger){const e=gn(o);return r.nextGate(un.output,{type:Z.JsonObj,value:e})}const s=o.properties.findIndex((e=>e.name===t.name));if(-1!==s){let e=n.data.type===o.properties[s].type;if(!e&&n.data.type===Z.Anything){e=Se(n.data.type)===o.properties[s].type}if(e?(o.properties[s].value=n.data.value,o.properties[s].$$invalidInputType=!1):o.properties[s].$$invalidInputType=!0,r.setState(o),!o.useTriggerPort){const e=gn(o);return r.nextGate(un.output,{type:Z.JsonObj,value:e})}}},getInputNames:e=>{const t={...ln(),...e},n=t.properties.map((e=>({name:e.name,label:e.label,type:e.type})));return t.useTriggerPort&&n.push({name:dn.trigger,label:dn.trigger,type:Z.Anything}),n},getOutputNames:e=>[{name:un.output,label:un.output,type:Z.JsonObj,jsonShape:pn(e)}],getDefaultState:ln};const vn=async e=>{const t=(e,t)=>e.split(t)[1];if(e.startsWith(le)){const n=t(e,le);return we("inner","input",n)}if(e.startsWith(me)){const n=t(e,me);return we("outer","output",n)}return null},fn=()=>({canvasPosition:{x:0,y:0},canvasZoom:1,inputs:[{name:"input",type:[Z.Anything],index:0}],outputs:[{name:"output",type:[Z.Anything],index:0}],name:"Custom Widget 1",description:"",type:"custom"}),yn=e=>{const t={...fn(),...e},n=t.inputs.map(((e,t)=>({name:we("outer","input",e.name),type:e.type,...e.jsonShape?{jsonShape:e.jsonShape}:void 0,...e.position?{position:e.position}:void 0,label:e.label,isInner:!1,index:t}))),r=t.outputs.map(((e,t)=>({name:we("inner","output",e.name),type:e.type,...e.jsonShape?{jsonShape:e.jsonShape}:void 0,...e.position?{position:e.position}:void 0,label:e.label,isInner:!0,index:n.length+t})));return[...n,...r]};var hn={onParentEvent:async(e,t,n,r)=>{const a=r.getState(),i={...fn(),...a},o=yn(i,(r.recipePoolId,r.recipeType,r.thingRecipeId,r.id));for(let e=0;e<o.length;e++){const a=o[e];if(t.name===a.name&&(a.type.includes(Z.Anything)||a.type.includes(n.data.type))){const e=await vn(t.name);e&&await r.nextWidget(e,{type:n.data.type,value:n.data.value})}}},getInputNames:yn,getOutputNames:e=>{const t={...fn(),...e},n=t.outputs.map(((e,t)=>({name:we("outer","output",e.name),type:e.type,...e.jsonShape?{jsonShape:e.jsonShape}:void 0,...e.position?{position:e.position}:void 0,label:e.label,isInner:!1,index:t})));return[...t.inputs.map(((e,t)=>({name:we("inner","input",e.name),type:e.type,...e.jsonShape?{jsonShape:e.jsonShape}:void 0,...e.position?{position:e.position}:void 0,label:e.label,isInner:!0,index:t+n.length}))),...n]},getDefaultState:fn};const In=(e,t,n,r,a)=>{const i=4*(t*n.width+e),o=n.data[i],s=n.data[i+1],c=n.data[i+2];return Math.abs(o-r.r)<=a&&Math.abs(s-r.g)<=a&&Math.abs(c-r.b)<=a};var Sn,$n,wn,bn,Nn,An,xn,Pn,Cn,En,jn={getPixelValueAtIndex:(e,t)=>{const n=e.data,r=n[t]||0,a=n[t+1]||0,i=n[t+2]||0;return{avr:(r+a+i)/3,r:r,g:a,b:i}},getBoundingBox:(e,t,n)=>{const r=e.width,a=e.height,i=new Set,o=Number(n.threshold||0),s=isNaN(o)?10:o,c=(n,o)=>{const c=[[n,o]];let u=n,d=n,l=o,p=o;for(;c.length>0;){const n=c.shift();if(!n)continue;const[o,g]=n;o<0||g<0||o>=r||g>=a||i.has(`${o},${g}`)||!In(o,g,e,t,s||0)||(i.add(`${o},${g}`),u=Math.min(u,o),d=Math.max(d,o),l=Math.min(l,g),p=Math.max(p,g),c.push([o+1,g],[o-1,g],[o,g+1],[o,g-1]))}return{minX:u,maxX:d,minY:l,maxY:p}},u=[];for(let o=0;o<a;o+=4)for(let a=0;a<r;a+=4)if(!i.has(`${a},${o}`)&&In(a,o,e,t,s)){const{minX:e,maxX:t,minY:r,maxY:i}=c(a,o),s=t-e,d=i-r;if(s>=(n.minWidth||1)&&d>=(n.minHeight||1)&&u.push({left:e,top:r,width:s,height:d}),n.maxBoxes&&u.length>=n.maxBoxes)return u}return u},copyImageData:e=>new ImageData(new Uint8ClampedArray(e.data),e.width,e.height),setPixelValueAtIndex:(e,t,n)=>{const r=e.data,a="object"==typeof n,i=a?n.r:n,o=a?n.g:n,s=a?n.b:n;r[t]=i,r[t+1]=o,r[t+2]=s,r[t+3]=255}};!function(e){e.Browser="browser",e.Cloud="cloud",e.Desktop="desktop"}(Sn||(Sn={})),function(e){e.Bundle="bundle",e.Group="group"}($n||($n={})),function(e){e.Hardware="hardware",e.Virtual="virtual"}(wn||(wn={})),function(e){e.Cloud="cloud",e.Web="web"}(bn||(bn={})),function(e){e.Cpu_128M="kmu-cpu-128m",e.Cpu_256M="kmu-cpu-256m",e.Cpu_512M="kmu-cpu-512m",e.Cpu_1024M="kmu-cpu-1024m",e.Cpu_2048M="kmu-cpu-2048m",e.Cpu_4096M="kmu-cpu-4096m"}(Nn||(Nn={})),function(e){e.Gateway="gateway",e.Timer="timer"}(An||(An={})),function(e){e.InstallInProgress="installation-in-progress"}(xn||(xn={})),function(e){e.InstallDependencies="install-dependencies",e.GetInstalledDependencies="get-installed-dep"}(Pn||(Pn={})),function(e){e.Success="success",e.Error="error",e.Pending="pending"}(Cn||(Cn={})),function(e){e.NotFound="not-found",e.BadRequest="bad-request",e.Forbidden="forbidden",e.InternalError="internal-error"}(En||(En={}));let kn=null;var Dn=()=>{if(!kn)throw new Error("Required function is not set");return kn};class On extends Error{constructor(e,t){super(e),this.name="UserCodeError",t&&(this.stack=t)}}const Tn=(e,t)=>`\n\t\tfunction _user_code_(){\n\t\t\t${t===Sn.Browser?"\n\t\t\tvar global = {\n\t\t\t\t__user_code: true\n\t\t\t};\n\t\t\tvar process = {};\n\t\t\tvar console = this.console;\n\t\t\tvar globalThis = global;\n\t\t\tvar require = this.___notSupportedMethod;\n\t\t\t":"\n\t\t\tvar require = this.require;\n\t\t\tvar process = this.kemuProcess;\n\t\t\t"}\n\n\t\t\tvar eval = () => {};\n\t\t\tvar document = {};\n\t\t\tvar navigator = {};\n\t\t\tvar window = this.window;\n\t\t\tvar alert = this.notify.info;\n\t\t\tvar DataType = this.dataTypesEnum;\n\t\t\tvar setInterval = this.setInterval;\n\t\t\tvar setTimeout = this.setTimeout;\n\t\t\tvar addEventListener = this.addEventListener;\n\t\t\tvar removeEventListener = this.removeEventListener;\n\t\t\tvar requestAnimationFrame = this.___notSupportedMethod;\n\t\t\tvar __delay = (ms) => new Promise((resolve, reject) => setTimeout(resolve, ms, reject));\n\n\t\t\tvar Kemu = {\n\t\t\t\tservices: {\n\t\t\t\t\thttp: { ...this.httpWebService },\n\t\t\t\t\tdynamoDb: { ...this.dynamoService },\n\t\t\t\t\tgoogleSheets: {\n\t\t\t\t\t\t...this.googleSheetsService,\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\timage: this.imageHelpers,\n\t\t\t\tvariable: this.variablesManager,\n\n\t\t\t\thelpers: {\n\t\t\t\t\tcryptoJS: this.CryptoJS,\n\t\t\t\t\tjsonp: this.jsonp,\n\t\t\t\t\tdelay: __delay,\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvar sendToPort;\n\n\t\t\t// --- User Methods Start ---\n\t\t\t${e||""};\n\t\t\t// --- User Methods End ---\n\t\t\t\n\t\t\t// Processes the user code asynchronously.\n\t\t\tconst asyncProcessEvent = async (targetPort, sourcePort, event) => {\n\t\t\t\tconst userProcessEvent = typeof processEvent === 'undefined' ? undefined : processEvent;\n\t\t\t\tif(userProcessEvent) {\n\t\t\t\t\ttry{\n\t\t\t\t\t\treturn await userProcessEvent(targetPort, sourcePort, event, sendToPort);\n\t\t\t\t\t}catch(e){\n\t\t\t\t\t\tthis.__errorTracer(e);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/** invoked the very first time the recipe is initialized */\n\t\t\tconst asyncRecipeInit = async (context, logger) => {\n\t\t\t\ttry {\n\t\t\t\t\t${t===Sn.Browser?"if(logger) { console = logger; }":""}\n\t\t\t\t\tif(typeof recipeInit === 'function') {\n\t\t\t\t\t\treturn recipeInit(context);\n\t\t\t\t\t}\n\t\t\t\t}catch(e){\n\t\t\t\t\tthis.__errorTracer(e);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/** invoked every time the code is about to be replaced */\n\t\t\tconst asyncOnTerminate = async (context) => {\n\t\t\t\ttry {\n\t\t\t\t\tif(typeof onTerminate === 'function') {\n\t\t\t\t\t\treturn onTerminate(context);\n\t\t\t\t\t}\n\t\t\t\t}catch(e){\n\t\t\t\t\tthis.__errorTracer(e);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/** updates the function that allows widget contexts to send data to the next widget */\n\t\t\tconst setSendToPort = (sendNextFun) => {\n\t\t\t\tsendToPort = sendNextFun;\n\t\t\t}\n\n\t\t\t/** invoked the every time the user code is compiled. */\n\t\t\tconst asyncMainEvent = async (sendNextFun, logger) => {\n\t\t\t\ttry{\n\t\t\t\t\tsetSendToPort(sendNextFun);\n\t\t\t\t\tif(logger) { console = logger; }\n\t\t\t\t\tif(typeof main === 'function'){\n\t\t\t\t\t\treturn main();\n\t\t\t\t\t}\n\t\t\t\t}catch(e){\n\t\t\t\t\tthis.__errorTracer(e);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tasyncProcessEvent: asyncProcessEvent,\n\t\t\t\tmain: asyncMainEvent,\n\t\t\t\trecipeInit: asyncRecipeInit,\n\t\t\t\tsetSendToPortFun: setSendToPort,\n\t\t\t\tonTerminate: asyncOnTerminate,\n\t\t\t\tgetLocalContext: () => global,\n\t\t\t\tgetWidgetInputs: typeof getWidgetInputs === 'undefined' ? undefined : getWidgetInputs,\n\t\t\t\tgetWidgetOutputs: typeof getWidgetOutputs === 'undefined' ? undefined : getWidgetOutputs,\n\t\t\t};\n\t\t}\n\t\t\n\t\treturn function compiler(context){\n\t\t\treturn _user_code_.call(context)\n\t\t}\n\n\t\treturn compiler;\n\t`,Ln=(e,t,n,i)=>{const o=Tn(e,n),s={...t,document:{},__errorTracer:e=>{throw new On(e.message,e.stack)},__jest:void 0===globalThis.__jest?void 0:globalThis.__jest,___notSupportedMethod:()=>i?.error("This method is not supported."),console:console,setInterval:()=>i?.error("'setInterval' is not supported. Please use a \"Timer\" widget instead."),setTimeout:t?.setTimeout,imageHelpers:jn,...n===Sn.Cloud?{require:Dn(),kemuProcess:process.env.KEMU_PROCESS?process.env.KEMU_PROCESS:{}}:{},jsonp:r,CryptoJS:a,window:{addEventListener:t?.addEventListener,removeEventListener:t?.removeEventListener}};try{const e="browser"===(()=>{if(ie)return"browser";if(se)return"node";if(oe)return"worker";throw new Error("Unsupported environment")})()?(e=>e.replace(/[//]{2}[ ]*@kemu-cloud[ \t]*\{[\s\S]*?[//]{2}[ ]*@kemu-cloud[ \t]*\}/gim,""))(o):(e=>e.replace(/[//]{2}[ ]*@kemu-browser[ \t]*\{[\s\S]*?[//]{2}[ ]*@kemu-browser[ \t]*\}/gim,""))(o),t=new Function(e);return{compiledModule:t()(s)}}catch(e){return{error:{name:"CompileError",message:e.message,stack:e.stack}}}},Mn="main",Bn=()=>({pauseExecution:!1,autoPauseOnError:!0,$$eventListeners:{},pages:{[Mn]:{code:"\nconst getWidgetInputs = () => [\n\t{ name: 'Input 1', type: DataType.Number }\n];\n\nconst getWidgetOutputs = () => [\n\t{ name: 'Output 1', type: DataType.Number }\n]\n\nlet counter = 0;\n\nconst processEvent = async (targetPort, sourceWidget, event) => {\n\tif(targetPort.name === 'Input 1'){\n\t\treturn sendToPort('Output 1', {\n\t\t\ttype: DataType.Number,\n\t\t\tvalue: counter++,\n\t\t});\n\t}\n}\n",language:"javascript",name:"My First Script"}},consoleVisible:!1,$$consoleLines:[]}),Rn=(e,t)=>{const n={message:"Unknown Error"};if(e?.stack){const r=e?.stack?.split(":")[0].trim();n.type=r;const a=(e=>{const t=/,[ ]?<anonymous>:([0-9]+:[0-9]+)\)/gm;let n;for(;null!==(n=t.exec(e));){n.index===t.lastIndex&&t.lastIndex++;const e=n[1].split(":");if(2===e.length)return{line:Number(e[0])||0,column:Number(e[1])||0}}return null})(e.stack);a&&(n.line=a.line-(e=>{const t="___user_code_section___";return Tn(t,e).split(t)[0].split("\n").length+2})(t),n.column=a.column)}return e.message&&(n.message=e.message),n},Wn=(e,t)=>{const n={...Bn(),...t.getState()},r={...n,...e?{$$error:e}:void 0,...n.autoPauseOnError&&e?{pauseExecution:!0}:void 0};e&&(r.$$consoleLines=[...r.$$consoleLines,{type:"error",text:e.message,timestamp:Date.now(),fileName:Mn}]),t.setState(r)};var Un,Fn;!function(e){e.ServiceCreationLog="service-creation-log"}(Un=Un||(Un={})),function(e){e.Service="service",e.ServiceUI="serviceUI"}(Fn=Fn||(Fn={}));const _n=new o,Gn=(e,t,n)=>{const r=_(e,t);if(!r)throw new Error(`Thing ${t} not found in recipe ${e}`);const a=r.gates[n];if(!a)throw new Error(`Widget ${n} not found in thing ${t}`);return a},zn=(e,t,n)=>`${t}:${n}:${e}`,Vn=e=>`${e}:new-var`,Hn=async(e,t,n,r,a,i,o)=>{const s={...o},c={thingId:n,recipeId:t,variableName:e,changes:i,ownerId:r,callerWidgetId:a,varDefinition:Object.freeze(s)};if(i.includes("added")){const e=Vn(n);return _n.emit(e,c)}{const t=zn(e,n,r);return _n.emit(t,c)}},Jn=(e,t,n,r)=>{const a=Gn(e,t,r);a.variablesListener={...a.variablesListener,[n]:0},Kn(e,t)},qn=(e,t,n,r)=>{const a=Gn(e,t,r),i={...a.variablesListener};void 0!==a.variablesListener?.[n]&&(delete i[n],a.variablesListener=i)},Kn=async(e,t)=>{const n=_(e,t);if(!n)throw new Error(`Thing "${t}" not found in recipe "${e}"`);const r={...n.variables},a=Object.keys(r);for(const i of a){const a=r[i],o=Object.keys(a);for(const a of o){!n.gates[a]&&(delete r[i][a],await Hn(i,e,t,a,void 0,["removed"],null))}0===Object.keys(r[i]).length&&delete r[i]}n.variables=r},Xn=(e,t,n)=>{for(const r in t){const a=t[r];if(a.createdByWidgetId===e.id)return a;if(e.type===xe.variable&&a.ownerType===xe.variable)return a;if(e.type===xe.script){const t=a.createdByWidgetId===e.groupId,r=n[a.createdByWidgetId];if(!r)continue;const i=r.groupId===e.groupId;if(t||r.type===xe.variable&&i)return a}}return null};var Yn=async(e,t,n,r,a,i)=>{const o=_(e,t);if(!o)throw new Error(`Thing ${t} not found in recipe ${e}`);const s={...o.variables};s[r]=s[r]||{};const c=s[r],u=o.gates[n];if(!u)throw new Error(`Widget ${n} not found in thing ${t}`);const d=Object.values(c);let l=!1,p=!1;const g=async a=>Hn(r,e,t,a.createdByWidgetId,n,["value"],a);if(u.type===xe.variable){l=!0;for(const e of d)e.ownerType===xe.variable&&e.type===a.type&&(e.value=a.value,p=!0,await g(e))}if(u.type===xe.script){l=!0;for(const e of d){const t=e.createdByWidgetId===u.groupId,n=o.gates[e.createdByWidgetId],r=n?.type===xe.variable,i=n?.groupId===u.groupId;(t||r&&i)&&e.type===a.type&&(e.value=a.value,p=!0,await g(e))}}if(!l){l=!0;for(const e of d){e.createdByWidgetId===n&&e.type===a.type&&(e.value=a.value,p=!0,await g(e))}}if(!i?.skipNotifications&&p){const s=Object.values(o.gates);for(const o of s){if(o.id===n&&i?.skipCallerNotification)continue;const s=o.variablesListener?.[r];void 0!==s&&await Ba(o.id,t,e,`${K}${r}`,a)}}},Zn=(e,t,n,r)=>{const a=_(e,t);if(!a)throw new Error(`Thing ${t} not found in recipe ${e}`);if(!r.readerWidgetId&&!r.ownerWidgetId)throw new Error("readerWidgetId or ownerWidgetId must be provided");const i={...a.variables}[n];if(!i)return;if(r.ownerWidgetId){const e=i[r.ownerWidgetId];return e?.value}const o=a.gates[r.readerWidgetId];if(!o)throw new Error(`Widget ${r.readerWidgetId} not found in thing ${t}`);const s=Xn(o,i,a.gates);return s?s.value:null},Qn=Jn,er=qn;const tr="setTimeout",nr="variableChanged",rr=e=>{const{recipePoolId:t,thingId:n,scriptWidgetId:r}=e;if(!G(t,n,r))throw new Error(`Widget "${r}" not found in recipe "${t}"`);return{get:(e,a)=>{const i=Zn(t,n,e,{readerWidgetId:r});if(null===i){if(void 0===a)throw new Error(`Variable "${e}" is not defined`);return a}return i},set:async(e,a)=>{await Yn(t,n,r,e,{type:Se(a),value:a})},onValueChange:(a,i)=>{if(!e.setState)return void console.warn("Cannot subscribe to variable changes without a setState function");Qn(t,n,a,r);const o={...Bn(),...e.getState()};o.$$eventListeners[a]={handler:i,abort:async()=>{er(t,n,a,r)},name:nr},e.setState(o)}}},ar="__command-compile__";let ir;const or=()=>{console.log("Method not implemented")},sr=(e,t,r)=>{const a=(e,...n)=>{const r={...Bn(),...t.getState()}.$$eventListeners[e];r&&r.handler(n)},i={};return Object.keys(Z).forEach((e=>{i[e]=Z[e]})),{dataTypesEnum:i,notify:{success:e=>{t.getState()?.$$managedUI?.notify?.success(e)},error:e=>{t.getState()?.$$managedUI?.notify?.error(e)},info:e=>{t.getState()?.$$managedUI?.notify?.info(e)}},variablesManager:e.variablesManager?rr({recipePoolId:r.recipePoolId,scriptWidgetId:r.widgetId,thingId:r.thingId,getState:t.getState,setState:t.setState}):{get:or,set:async()=>or(),onValueChange:or},setTimeout:(r,a,i)=>{if(e.withTimers&&t&&t.setState&&t.registerInterrupt){const e=n(),o={...Bn(),...t.getState()};o.$$eventListeners[e]={handler:r,rejectHandler:i,name:tr},t.setState(o),t.registerInterrupt("timeout",e,{timeout:a},void 0,e)}},addEventListener:(e,r)=>{if(t.setState){const i=n(),o={...Bn(),...t.getState()};o.$$eventListeners[i]={handler:r,name:e},t.setState(o),window.addEventListener(e,a.bind(i))}else console.warn(`Cannot remove event listener '${e}' because the widget context is not available.`)},removeEventListener:(e,n)=>{if(t.setState){const r={...Bn(),...t.getState()},a=Object.keys(r.$$eventListeners).find((t=>r.$$eventListeners[t].name===e&&r.$$eventListeners[t].handler===n));t.setState(r),a&&removeEventListener(r.$$eventListeners[a].name,r.$$eventListeners[a].handler)}else console.warn(`Cannot remove event listener '${e}' because the widget context is not available.`)}}},cr=(e,t,n,r)=>{const a={...Bn(),...n.getState()},i=a.pages[Mn].$$compiledCode;if(i)return{compiledModule:i};{const i=sr(e,n,t);return Ln(a.pages[Mn].code,i,n.recipeType,r)}},ur=e=>e.map((e=>({...e,name:e.name.replace("_","")}))),dr=async(e,t)=>{const n={...e};for(const r in e){if(e[r].name===tr){const e=n[r]?.rejectHandler;if("function"==typeof e)try{await e("TIMER_ABORTED")}catch(e){console.log("Error in reject interrupt handler: ",e)}t.cancelInterrupt(r),delete n[r]}}return n},lr=async(e,t,n)=>{let r={...Bn(),...e.getState()};if(void 0!==n){r.pages[Mn]?.$$compiledCode?.onTerminate&&await(r.pages[Mn].$$compiledCode?.onTerminate());let t=await dr(r.$$eventListeners,e);t=await(async e=>{const t={...e};for(const n in e)if(e[n].name===nr){const r=e[n]?.abort;if("function"==typeof r)try{await r()}catch(e){console.log("Error in abort interrupt handler: ",e)}delete t[n]}return t})(t),r.$$eventListeners=t,r.$$error=void 0,r.pages[Mn].$$compiledCode=void 0,r.pages[Mn].code=n,e.setState({...r})}const a=!r.pages[Mn].$$compiledCode,{compiledModule:i,error:o}=cr({variablesManager:!0,withTimers:!0},{recipePoolId:e.recipePoolId,thingId:e.thingRecipeId,widgetId:e.id},{getState:e.getState,setState:e.setState,recipeType:e.recipeType,registerInterrupt:e.registerInterrupt});if(o){console.log("Failed to compile user code");const t=Rn(o,e.recipeType);return Wn(t,e),null}if(i){const n=(e=>{const t=(t,n)=>{if(ir)try{return ir[t](n)}catch(e){return void console.log("Error in custom logger: ",e)}const r={...Bn(),...e.getState()},a=[...r.$$consoleLines||[]];a.push({fileName:Mn,text:n,type:t,timestamp:Date.now()}),a.length>100&&a.splice(0,30),e.setState({...r,$$consoleLines:a})},n={log:e=>{t("log",e)},error:e=>{t("error",e)},warn:e=>{t("warn",e)},info:e=>{t("info",e)}};return n})(e);let o;if(r={...e.getState()},r.pages[Mn].$$compiledCode=i,e.nextGate&&i.setSendToPortFun(e.nextGate),t)try{await i.recipeInit({setState:e.setState,getState:e.getState},n)}catch(t){o=Rn(t,e.recipeType)}if(e.nextGate&&a)try{await i.main(e.nextGate,n)}catch(t){o=Rn(t,e.recipeType)}r.$$lastInputs=i.getWidgetInputs?i.getWidgetInputs():[],r.$$lastOutputs=i.getWidgetOutputs?i.getWidgetOutputs():[],e.setState(r),Wn(o,e)}};var pr={onParentEvent:async(e,t,n,r)=>{const a=r.getState(),i={...Bn(),...a};if(!i.pages[Mn])return console.warn("Missing default page");if(i.pauseExecution){if(Object.keys(i.$$eventListeners).length){const e=await dr(i.$$eventListeners,r);r.setState({...i,$$eventListeners:e})}return}if(fe(e?.name||""))return i.$$eventListeners[t.name]?(await i.$$eventListeners[t.name].handler(),i.$$eventListeners[t.name].name===tr&&delete i.$$eventListeners[t.name],void r.setState({...i})):void console.log(`Unknown interrupt id [${t.name}] `);if(t.name.startsWith(K)){const e=t.name.replace(K,""),r=n.data.value,a=i.$$eventListeners[e];return void(a?.handler&&await a.handler(r))}const o=t.name===ar;await lr(r,!1,o?n.data.value:void 0);const s=i.pages[Mn].$$compiledCode;if(e&&e.name!==ar&&s){let a;try{await s.asyncProcessEvent(t,e,n)}catch(e){"UserCodeError"===e.name&&(a=Rn(e,r.recipeType))}Wn(a,r)}},getInputNames:(e,t)=>{const n={...Bn(),...e},{compiledModule:r}=cr({},{recipePoolId:t.recipePoolId,thingId:t.thingRecipeId,widgetId:t.widgetId},{getState:()=>n,recipeType:t.recipeType});if(r?.getWidgetInputs){const e=r.getWidgetInputs();return ur(e)}return e.$$lastInputs||[]},getOutputNames:(e,t)=>{const n={...Bn(),...e},{compiledModule:r}=cr({},{recipePoolId:t.recipePoolId,thingId:t.thingRecipeId,widgetId:t.widgetId},{getState:()=>n,recipeType:t.recipeType});if(r?.getWidgetOutputs){const e=r.getWidgetOutputs();return ur(e)}return e.$$lastOutputs||[]},getDefaultState:Bn,initialize:async e=>{const t=e.getState(),n={...Bn(),...t};n.pages[Mn].code&&await lr({getState:e.getState,id:e.widgetThingId,recipePoolId:e.recipePoolId,recipeType:e.recipeType,registerInterrupt:e.registerInterrupt,setState:e.setState,thingRecipeId:e.thingRecipeId,cancelInterrupt:()=>!0},!0,n.pages[Mn].code)}};const gr=async(e,t,n,r)=>{e.startsWith("data:image/")||(e=`data:image/png;base64,${e}`);const a=await mr(e);return((e,t,n,r)=>{const a=r.getContext("2d");if(!a)throw new Error("Failed to get canvas context");const i=e.width,o=e.height;return r.width=t,r.height=n,a.drawImage(e,0,0,i,o,0,0,t,n),a.getImageData(0,0,t,n)})(a,n||a.naturalWidth,r||a.naturalHeight,t)},mr=e=>new Promise(((t,n)=>{const r=new Image;r.onload=()=>t(r),r.onerror=e=>n(e),r.src=e})),vr=Object.freeze({image:"image"}),fr=Object.freeze({base64:"base64"}),yr=()=>({});var hr={onParentEvent:async(e,t,n,r)=>{const a={...r.getState()};if(t.name===fr.base64){if("string"!=typeof n.data.value)return;if(n.data.type!==Z.String&&n.data.type!==Z.Anything)return;const e=n.data.value;ie&&(a.$$memCanvas&&a.$$memCanvas.getContext||(a.$$memCanvas=At(320,240)));try{const t=await gr(e,a.$$memCanvas,a.resize?.width,a.resize?.height);return r.setState(a),r.nextGate(vr.image,{type:Z.ImageData,value:t})}catch(e){console.log("[base64ToImageData] Error: ",e)}}},getInputNames:()=>[{name:fr.base64,type:Z.String}],getOutputNames:()=>[{name:vr.image,type:Z.ImageData}],getDefaultState:yr};const Ir=Object.freeze({object:"object",error:"error"}),Sr=Object.freeze({string:"string"}),$r=()=>({outputIsArray:!1});var wr={onParentEvent:async(e,t,n,r)=>{const a={outputIsArray:!1,...r.getState()};if((n.data.type===Z.String||n.data.type===Z.Anything)&&"string"==typeof n.data.value)try{const e=JSON.parse(n.data.value),t=Array.isArray(e);return t&&!a.outputIsArray?r.setState({...a,outputIsArray:!0}):!t&&a.outputIsArray&&r.setState({...a,outputIsArray:!1}),r.nextGate("object",{type:t?Z.Array:Z.JsonObj,value:e})}catch(e){return r.nextGate("error",{type:Z.Boolean,value:!0})}},getInputNames:()=>[{name:Sr.string,type:Z.String}],getOutputNames:e=>[{name:Ir.object,type:[Z.JsonObj,Z.Array],label:e.outputIsArray?"array":Ir.object},{name:Ir.error,type:Z.Boolean}],getDefaultState:$r};const br=Object.freeze({string:"string",length:"length"}),Nr=Object.freeze({trigger:"trigger",setText:"setText"}),Ar=()=>({text:"",dispatchOnSet:!1});var xr={onParentEvent:async(e,t,n,r)=>{const a={text:"",dispatchOnSet:!1,...r.getState()};if(t.name===Nr.setText){if(!((n.data.type===Z.String||n.data.type===Z.Anything)&&"string"==typeof n.data.value))return;if("string"==typeof n.data.value&&(a.text=n.data.value,r.setState(a)),!a.dispatchOnSet)return}const i=r.nextGate(br.length,{type:Z.Number,value:a.text.length}),o=r.nextGate(br.string,{type:Z.String,value:a.text});await Promise.all([i,o])},getInputNames:e=>{const t=[{name:Nr.setText,type:Z.String}];return e.dispatchOnSet||t.push({name:Nr.trigger,type:Z.Anything}),t},getOutputNames:()=>[{name:br.string,type:Z.String},{name:br.length,type:Z.Number}],getDefaultState:Ar};const Pr=Object.freeze({image:"image"}),Cr=Object.freeze({image:"image",x:"x",y:"y",width:"width",height:"height"}),Er=()=>({showInputPorts:!1});var jr={onParentEvent:async(e,t,n,r)=>{const a={showInputPorts:!1,...r.getState()};if("number"==typeof n.data.value)return t.name===Cr.x&&(a.cropX=n.data.value),t.name===Cr.y&&(a.cropY=n.data.value),t.name===Cr.width&&(a.cropWidth=n.data.value),t.name===Cr.height&&(a.cropHeight=n.data.value),void r.setState(a);if(t.name===Cr.image){if(n.data.type!==Z.ImageData&&n.data.type!==Z.Anything)return;if(!ye(n.data.value))return;const e=n.data.value;if(a.$$memCanvas&&a.$$memCanvas.getContext||(ie&&(a.$$memCanvas=At(320,240),a.$$memCanvasContext=xt(a.$$memCanvas)),r.setState(a)),!a.$$memCanvas||!a.$$memCanvasContext)return;let t=e;return a.$$memCanvas.width=e.width,a.$$memCanvas.height=e.height,(a.cropX||a.cropY||a.cropWidth||a.cropHeight)&&(t=((e,t,n,r)=>{if(!n)return e;const a=Math.max(r.x||0,0),i=Math.max(r.y||0,0),o=e.width,s=e.height,c=Math.min(Math.ceil(r.width||o),o),u=Math.min(Math.ceil(r.height||s),s);return t.width=e.width,t.height=e.height,n.putImageData(e,0,0),n.drawImage(t,a,i,c,u,0,0,c,u),n.getImageData(0,0,c,u)})(e,a.$$memCanvas,a.$$memCanvasContext,{x:a.cropX,y:a.cropY,width:a.cropWidth,height:a.cropHeight})),r.nextGate(Pr.image,{type:Z.ImageData,value:t})}},getInputNames:e=>{const t=[{name:Cr.image,type:[Z.ImageData]}];return e.showInputPorts&&(t.push({name:Cr.x,type:Z.Number}),t.push({name:Cr.y,type:Z.Number}),t.push({name:Cr.width,type:Z.Number}),t.push({name:Cr.height,type:Z.Number})),t},getOutputNames:()=>[{name:Pr.image,type:Z.ImageData}],getDefaultState:Er};const kr=Object.freeze({image:"image"}),Dr=Object.freeze({image:"image",width:"width",height:"height"}),Or=()=>({showInputPorts:!1});var Tr={onParentEvent:async(e,t,n,r)=>{const a={showInputPorts:!1,...r.getState()};if("number"==typeof n.data.value)return t.name===Dr.width&&(a.width=n.data.value),t.name===Dr.height&&(a.height=n.data.value),void r.setState(a);if(t.name===Dr.image){if(n.data.type!==Z.ImageData&&n.data.type!==Z.Anything)return;if(!ye(n.data.value))return;const e=n.data.value;if(a.$$memCanvas&&a.$$memCanvas.getContext||(a.$$memCanvas=At(320,240),r.setState(a)),!a.$$memCanvas)return;let t=e;return(a.width||a.height)&&(t=((e,t,n,r)=>{if(!n&&!r)return e;n&&!r?r=n*(e.height/e.width):!n&&r&&(n=r*(e.width/e.height));const a=Math.max(1,n||e.width),i=Math.max(1,r||e.height);t.width=Math.max(e.width,a),t.height=Math.max(e.height,i);const o=xt(t);if(!o)throw new Error("Failed to get canvas context");return o.putImageData(e,0,0),o.drawImage(t,0,0,e.width,e.height,0,0,a,i),o.getImageData(0,0,a,i)})(e,a.$$memCanvas,a.width,a.height)),r.nextGate(kr.image,{type:Z.ImageData,value:t})}},getInputNames:e=>{const t=[{name:Dr.image,type:Z.ImageData}];return e.showInputPorts&&(t.push({name:Dr.width,type:Z.Number}),t.push({name:Dr.height,type:Z.Number})),t},getOutputNames:()=>[{name:kr.image,type:Z.ImageData}],getDefaultState:Or};const Lr=Object.freeze({value:"value"}),Mr=Object.freeze({trigger:"trigger",setValue:"setValue"}),Br=()=>({value:0,dispatchOnSet:!1});var Rr={onParentEvent:async(e,t,n,r)=>{const a={value:0,dispatchOnSet:!1,...r.getState()};if(t.name===Mr.setValue){const e=n.data.type===Z.Number||n.data.type===Z.Anything||n.data.type===Z.String,t=!isNaN(Number(n.data.value))&&!Array.isArray(n.data.value);if(!e||!t)return;if(a.value=Number(n.data.value),r.setState(a),!a.dispatchOnSet)return}return r.nextGate(Lr.value,{type:Z.Number,value:a.value})},getInputNames:e=>{const t=[{name:Mr.setValue,type:Z.Number}];return e.dispatchOnSet||t.push({name:Mr.trigger,type:Z.Anything}),t},getOutputNames:()=>[{name:Lr.value,type:Z.Number}],getDefaultState:Br};const Wr=Object.freeze({image:"image"}),Ur=Object.freeze({image:"image"}),Fr=()=>({anchors:[],vertices:[],matrix:[]}),_r={onParentEvent:async(e,t,n,r)=>{const a={anchors:[],vertices:[],matrix:[],...r.getState()},i=window,o=n.data.type===Z.ImageData;if(i.Speedy&&o){const e=i.Speedy,t=n.data.value;let o,d,l,p=a.$$private?.canvas,g=a.$$private?.context,m={...a};const v=4===a.anchors.length;if(a.$$private?.pipeline)o=a.$$private?.pipeline,d=a.$$private?.source;else{o=e.Pipeline(),d=e.Image.Source();const n=e.Image.Sink();l=e.Transform.PerspectiveWarp(),p?p.width===t.width&&p.height===t.height||(p.width=t.width,p.height=t.height,g=p.getContext("2d")):(c=t.width,u=t.height,p=At(c,u),g=p.getContext("2d")),d.output().connectTo(l.input()),l.output().connectTo(n.input()),o.init(d,n,l);let r=e.Matrix(3,3,[1,0,0,0,1,0,0,0,1]);if(4===a.anchors.length){const t=e.Matrix(2,4,[(s=a.anchors)[0].x,s[0].y,s[1].x,s[1].y,s[2].x,s[2].y,s[3].x,s[3].y]),n=e.Matrix(2,4,a.vertices.reduce(((e,t)=>e.concat([t.x,t.y])),[])),i=e.Matrix.Zeros(3,3);await e.Matrix.perspective(i,t,n);const o=i.read();r=e.Matrix(3,3,o)}l.transform=r,m={...m,$$private:{...m.$$private,canvas:p,context:g,perspective:l,pipeline:o,source:d}}}let f=t;if(v){const e=await(async(e,t)=>{const n=window,r=e.$$private?.source,a=e.$$private?.pipeline;if(n.Speedy&&r&&a){const e=n.Speedy,i=await createImageBitmap(t),o=await e.load(i);return r.media=o,(await a.run()).image.source}return null})(m,f);e&&(p&&g&&(f=((e,t,n)=>(t.width=e.width,t.height=e.height,n.drawImage(e,0,0),n.getImageData(0,0,e.width,e.height)))(e,p,g)),m.$$private&&r.setState({...m,$$private:{...m.$$private,lastInputImage:t}}))}else m.$$private&&r.setState({...m,$$private:{...m.$$private,lastInputImage:t}});return r.nextGate(Wr.image,{type:Z.ImageData,value:f})}var s,c,u;console.log("Environment not supported")},getInputNames:()=>[{name:Ur.image,type:Z.ImageData}],getOutputNames:()=>[{name:Wr.image,type:Z.ImageData}],getDefaultState:Fr,terminate:async e=>{const t=e.getState();t.$$private?.pipeline.release()}},Gr=()=>({name:"Default widget bundle",description:"",inputs:[{dataType:[Z.Anything],name:"input"}],outputs:[{dataType:[Z.Anything],name:"output"}]});let zr;const Vr=()=>{if(!zr)throw new Error(Me(Le));return zr};const Hr=async e=>{const t=new s,n=await t.loadAsync(e),r={};for(const e in n.files)if(!n.files[e].dir){const t=await n.file(e);t&&(r[e]=await t.async("uint8array"))}return r},Jr={};var qr=e=>Jr[e]||null;const Kr=async(e,t,n)=>{try{const r=Vr(),a=n?r.loadBlobAsString:r.loadBlob;return await a(e,t)}catch(e){return null}},Xr=async e=>{const t=H;try{const n=await Kr(e,t,!0);if(!n)return null;return Function(n)()}catch(e){return null}},Yr=async e=>{const t=J;try{const n=await Kr(e,t,!0);if(!n)return null;return JSON.parse(n)}catch(n){return console.log(`Failed to parse the bundle's state [${e}/${t}] %j`,n),null}},Zr=(e,t)=>`${e.replace(q,"")}_${t}`,Qr=(e,t)=>`widget/${e.replace(q,"")}/v/${t}`,ea=async(e,t)=>{const n=Vr(),[r]=await Promise.all([Hr(e),n.createLocation(t)]);for(const e in r)e.startsWith("__MACOSX")||await n.saveBlob(t,e,r[e])},ta=(e,t)=>{const n=Zr(e,t),r=qr(n);return r?{...r}:null},na=(e,t,n)=>{const r=`${`widget/${e.replace(q,"")}/tmp`}/${t}`;if(n){return Vr().getCacheLocation(r)}return r};var ra=ta,aa=async(e,t,n)=>{const r=na(t,n);await ea(e,r);const a=Xr(r),i=Yr(r),o=Vr(),s=o.getCacheLocation(r),[c,u]=await Promise.all([a,i]);if(!c)return null;let d=u;if(!u){const e=Gr(),t=JSON.stringify(e);await o.saveBlob(r,J,ve(t)),d=e}return{cachePath:s,processor:c,storedState:Object.freeze(d)}},ia=(e,t,n)=>{if(n.isTempStorage)return na(e,t,n.fullStorageRoot);const r=Vr(),a=Qr(e,t);return n.fullStorageRoot?r.getCacheLocation(a):a};const oa=()=>Gr();var sa={onParentEvent:async(e,t,n,r)=>{const a=r.getState();return a.$$processor?.onParentEvent({sourcePort:e?.name||"",targetPort:t?.name||"",data:n.data},{getState:r.getState,recipeId:r.recipePoolId,recipeType:r.recipeType,setState:r.setState,nextWidget:r.nextGate})},getInputNames:(e,t)=>{const n={...oa(),...e};return n.$$processor?.getInputNames?n.$$processor.getInputNames(e,t):n.inputs.map((e=>({name:e.name,type:e.dataType})))},getOutputNames:(e,t)=>{const n={...oa(),...e};return n.$$processor?.getOutputNames?n.$$processor.getOutputNames(e,t):n.outputs.map((e=>({name:e.name,type:e.dataType})))},getDefaultState:oa,initialize:async(e,t)=>{console.log("Widget bundle initialize",e);let n={...e.getState()},r=n.$$cacheInfo?.widgetThingId||n.collectionInfo?.widgetId||e.widgetThingId;const a=n.$$cacheInfo?.version.toString()||n.collectionInfo?.version.toString()||1;if(n.$$cacheInfo={...n.$$cacheInfo,version:Number(a),widgetThingId:r},!r||!a)throw new Error("Widget bundle state is missing cache id or version");console.log("Loading state from cache");const i=ra(r,a);let o=!i;if(!n.$$processor)if(n.storageUnitId&&!i){const t=await e.getStorageData(n.storageUnitId);if(t){r=e.widgetThingId;const i=await aa(t,r,a);o=!0,i&&(n={...n,$$processor:i.processor,$$cacheInfo:{...n.$$cacheInfo,widgetThingId:r,version:Number(a)}},e.setState(n))}}else if(i){o=!1;const r=n.collectionInfo?{...n.collectionInfo}:void 0;n={...n,...!t.keepCurrentState&&i.storedState?{...i.storedState,...r?{collectionInfo:r}:{}}:{},$$processor:i.processor},e.setState(n)}const s=ia(r,a,{fullStorageRoot:!0,isTempStorage:o});console.log("Invoking bundle initialize with cache: ",s);try{await(n.$$processor?.initialize({cacheLocation:s,getState:e.getState,setState:e.setState}));const t=e.getState();e.setState({...t,$$initializationError:void 0})}catch(t){const n=e.getState();throw e.setState({...n,$$initializationError:t.message||"An error occurred initializing the widget"}),t}},terminate:async e=>{const t={...e.getState()};console.log(`Terminating widget bundle ${t.name} [${t.$$cacheInfo?.widgetThingId||""}]`);const n=t.$$processor;n&&"function"==typeof n.terminate&&await n.terminate({getState:e.getState,setState:e.setState,recipePoolId:e.recipePoolId,widgetId:e.widgetId})}};const ca=Object.freeze({event:"event"}),ua="1",da="2",la="3";var pa={onParentEvent:async(e,t,n,r)=>{const a={...r.getState()};r.setState({...a,$$lastEventType:n.data.type}),await r.nextGate(ua,n.data),await r.nextGate(da,n.data),await r.nextGate(la,n.data)},getInputNames:()=>[{name:ca.event,type:Z.Anything}],getOutputNames:e=>{const t={type:{...e}.$$lastEventType??Z.Anything};return[{name:ua,...t},{name:da,...t},{name:la,...t}]}};const ga=Object.freeze({set:"set",trigger:"trigger"}),ma="value";let va;var fa=e=>{va=e},ya=()=>{if(!va)throw new Error("Hub Connector not set");return va};const ha=async(e,t=!1)=>{const n=ya();let r=e.$$$serviceId;if(!e.service)return console.log("Aborting service initialization, missing property `service` in state."),null;if(!r||t){const t=await n.getCompatibleService(e.service.name,e.service.version,"^");if(!t)return null;r=t.sessionId}return r};const Ia={input:We,counter:_e,elapsed:Ve,ifGate:Ke,skipEvent:Ze,between:nt,map:it,parser:ct,slider:lt,suspend:mt,display:ft,json:It,arrayItem:wt,extractImage:Et,imageConvolution:Tt,firstEvent:Rt,pixelDraw:zt,randomBetween:qt,arrayCombine:Qt,clock:rn,multiplication:cn,object:mn,widgetGroup:hn,script:pr,base64ToImageData:hr,jsonParse:wr,text:xr,imageCrop:jr,imageResize:Tr,value:Rr,imageWarp:_r,widgetBundle:sa,sequence:pa,variable:{onParentEvent:async(e,t,n,r)=>{const a=r.getState(),i={name:"myVar",type:Z.String,reactive:!0,defaultValue:"",...a};if(t.name.startsWith(K)){if(!i.reactive)return;if(n.data.type!==i.type)return;return r.nextWidget(ma,n.data)}if(t.name!==ga.set){if(t.name===ga.trigger){const e=Zn(r.recipePoolId,r.thingRecipeId,i.name,{ownerWidgetId:r.id}),t=e||i.defaultValue;await r.nextWidget(ma,{type:i.type,value:t})}}else await Yn(r.recipePoolId,r.thingRecipeId,r.id,i.name,n.data,{skipCallerNotification:!i.reactive})},getInputNames:e=>{const t={...e};return[{name:ga.set,type:t.type||Z.Anything},{name:ga.trigger,type:Z.Anything}]},getOutputNames:e=>{const t={...e};return[{name:ma,type:t.type||Z.Anything}]}},hubService:{onParentEvent:async(e,t,n,r)=>{const a={dynamicInputs:{},dynamicOutputs:{},customState:{},...r.getState()};if(!e)return;const i=ya();let o=a.$$$serviceId;if(!o){const e=i.getCachedServices().find((e=>e.name===a.service?.name&&e.version===a.service?.version));if(!e)return;o=e.sessionId,a.$$$serviceId=o,r.setState(a)}const s=a.service?.variants?.find((e=>e.id===a.variantId)),c=s?a.dynamicInputs[s.id]||s?.inputs||[]:a.service?.inputs||[];if(!c?.length)return;if(!s&&a.service?.ignoreParentEvents)return;const u=a.service?.processingTimeoutSec;return i.onParentEvent({recipeId:r.recipePoolId,data:n.data,targetServiceSessionId:o,currentState:a.customState,targetVariantId:a.variantId,target:{portName:t.name,widgetId:r.id,widgetType:r.type},source:e,config:{timeout:u?1e3*u:0,async:a.service?.asyncParentEvents}})},getInputNames:async e=>{const t=e.variantId;if(t&&e.dynamicInputs?.[t])return[...e.dynamicInputs[t]||[]];if(!t)return e.service?.inputs||[];{const n=e.service?.variants?.find((e=>e.id===t));if(n)return n.inputs||[]}return[]},getOutputNames:async e=>{const t=e.variantId;if(t&&e.dynamicOutputs?.[t])return[...e.dynamicOutputs[t]||[]];if(!t)return e.service?.outputs||[];{const n=e.service?.variants?.find((e=>e.id===t));if(n)return n.outputs||[]}return[]},initialize:async e=>{const t={dynamicInputs:{},dynamicOutputs:{},customState:{},...e.getState()},n=ya(),r=await ha(t);if(r)try{return await n.initializeServiceInstance({recipeId:e.recipePoolId,sessionId:r,widgetId:e.widgetThingId,recipeType:e.recipeType,variantId:t.variantId})}catch(t){if("FNC_NOT_FOUND"!==t?.errCode){if(!!("string"!=typeof t||!t.match('^Function ".*" not found.$')))throw t;console.warn(`Widget [${e.widgetThingId}] does not have an init function.`)}}else console.log(`Aborting service initialization, "${t.service?.name}" was not found in the current Hub.`)},terminate:async e=>{const t={dynamicInputs:{},dynamicOutputs:{},customState:{},...e.getState()},n=ya(),r=await ha(t,!0);if(r)return n.terminateServiceInstance(r,e.widgetId,e.recipePoolId,t.variantId)}},play:{getInputNames:()=>[],onParentEvent:()=>Promise.resolve(),getOutputNames:()=>[{name:"out",type:Z.Boolean}]}},Sa={},$a=async()=>{if(!Object.keys(Sa).length)for(const e in Ia){const t=Ia[e];Sa[e]=Object.freeze({...t})}};var wa=e=>{if(Sa[e])return Sa[e];throw new Error(Me(Te,e))},ba=$a;const Na=new o,Aa="invoked";let xa={},Pa={},Ca={},Ea={};const ja=(e,t,n)=>`${e}-${t}${n?`-${n}`:""}`;var ka=(e,t,n,r,a)=>{const i=ja(e,t,n),o=ja(e,t),s=ja(e,t,"produced"),c=Ca[o],u=Date.now();Ea[o]=u,xa[i]={data:r,sourcePortName:n,...a?{target:{widgetId:a.widgetId,portName:a.portName}}:{}},Na.emit(s,{currentTime:u,prevTime:c,...a?{targetPort:a?.portName}:{}})},Da=(e,t,n,r,a)=>{const i=ja(e,t,n),o=ja(e,t),s=ja(e,t,Aa),c=Ca[o],u=Date.now();Ca[o]=u,Pa[i]={data:r,sourcePortName:n,...a?{source:{widgetId:a.widgetId,portName:a.portName}}:{}},Na.emit(s,{prevTime:c,currentTime:u,targetPort:n,sourceInfo:a})},Oa=()=>{xa={},Pa={},Ca={},Ea={},Na.clearListeners()};let Ta,La,Ma;const Ba=async(e,t,n,r,a)=>{const i=_(n,t);if(!i)return;const o=i.gates[e];if(!o||o.disabled)return;const s={...a,timestamp:Date.now()},c=wa(o.type),u=Fa(e,s,i.recipeId,i.id,i.version,n);if(u&&c.onParentEvent){const t={name:r};return Ta&&await Ta({recipeId:n,blockId:i.recipeId,gateId:e,targetPort:t.name,data:a}),c.onParentEvent(null,t,{originalEvent:s,data:{...s}},u)}},Ra=async(e,t,n,r,a,i,o,s,c,u)=>{if(!e&&!c)throw new Error("Missing parameter ['sourceGateId']");if(!e&&!u)throw new Error("Missing parameter ['originalEvent']");e&&(u={timestamp:Date.now(),type:Z.Boolean,value:!0});const d=u;if("string"==typeof n){const e=_(r,n);if(!e)return;n=e}const l=n.gates[t];if(!l||l.disabled)return;const p=s.findIndex((e=>e.name===a)),g=wa(l.type),m=Fa(t,d,n.recipeId,n.id,n.version,r);if(m&&g.onParentEvent&&-1!==p){Ta&&await Ta({recipeId:r,blockId:n.recipeId,gateId:t,targetPort:i.name,data:o,sourceGate:e?"interrupt_widget":c,sourcePort:e?V:a});const u={name:s[p].name,type:s[p].type,...s[p].jsonShape?{jsonShape:s[p].jsonShape}:void 0};return Da(n.recipeId,t,i.name,o,c?{widgetId:c,portName:a}:void 0),g.onParentEvent(u,i,{originalEvent:d,data:o},m)}},Wa=async(e,t,n,r,a,i,o,s)=>{const c=F(s);if(!c)throw new Error(`Failed to find recipe "${s}" in cache`);const u=c.dbInfo.recipeType,d=G(s,a,r);if(!d)return;const l={...n,timestamp:t.timestamp},p=wa(d.type);let g;g=d.type===xe.input?p.getOutputNames(d.state,{thingRecipeId:a,thingDbId:i,thingVersion:o,id:r,recipeId:s,recipeType:u,recipePoolId:s}):await p.getOutputNames(d.state,{recipePoolId:s,recipeType:u,thingRecipeId:a,widgetId:r});if(-1!==g.findIndex((t=>t.name===e))){const n=_(s,a);if(!n)return;ka(a,r,e,l);const i=d.children.length;for(let o=0;o<i;o++){if(be(d.children[o]?.sourcePort).portName===e){const i=n.gates[d.children[o].childId];if(i&&!i.disabled){const c=wa(i.type);let p;const m={recipePoolId:s,recipeType:u,thingRecipeId:a,widgetId:r};p=i.type===xe.hubService?await c.getInputNames(i.state,m):c.getInputNames(i.state,m);const v=be(d.children[o].targetPort),f=p.find((e=>e.name===v.portName));f&&await Ra(!1,i.id,n,s,e,{name:f.name},d.returnOriginalEvent?t:l,g,d.id,t)}}}}},Ua=async(e,t,n,r)=>{const a=F(r);if(!a)return null;const i=_(r,n);if(!i)return i;const o=i.gates,s=i.gates[t],c=wa(s.type),u=await c.getInputNames(s.state,{recipePoolId:r,recipeType:a.dbInfo.recipeType,thingRecipeId:n,widgetId:t}),d=u.findIndex((t=>t.name===e));if(-1!==d){const e=((e,t,n)=>{for(const r in n){const a=n[r],i=a.children.length;for(let n=0;n<i;n++){const r=a.children[n],i=be(r.targetPort);if(r.childId===e&&i.portName===t)return a}}return null})(t,u[d].name,o);if(e){const t=wa(e.type);return{getValue:()=>"function"==typeof t.getValue?t.getValue():null}}}return null},Fa=(e,t,n,r,a,i)=>{const o=F(i);if(!o)throw new Error(`Failed to find recipe "${i}" in cache`);const s=G(i,n,e);if(!s)return console.warn(`Gate ${e} not found in block ${n} for recipe ${i}`),null;const c=async(o,s)=>Wa(o,t,s,e,n,r,a,i),u={id:e,type:s.type,recipePoolId:i,thingRecipeId:n,recipeType:o.dbInfo.recipeType,returnOriginalEvent:!!s.returnOriginalEvent,registerInterrupt:(t,r,a,o,s)=>ke.createInterrupt(t,i,n,e,r,a,o,s),cancelInterrupt:e=>ke.destroyInterrupt(e),nextWidget:c,nextGate:c,getParentAtPort:t=>Ua(t,e,n,i),getState:()=>Object.freeze({...s.state,...s.type===xe.input&&{customInputs:[]}}),setState:t=>{if("object"!=typeof t)return void console.warn(`Invalid state type [${typeof t}]. Expected an 'object'`);const r={...t,...s.type===xe.input&&!t.customInputs&&{customInputs:[]}},a={...s.state};s.state=r,La&&La({blockId:n,gateId:e,prevState:a,newState:{...r},recipeId:i})}};return u};ke.setInvokeChildGateCb(Ra);const _a=new o,Ga="invoked",za="state",Va=()=>{ke.destroyAllInterrupts()},Ha=async(e,t,n)=>{const r=F(e),a=G(e,t,n);if(a&&r){const i=wa(a.type);if(i&&"function"==typeof i.terminate){const a=((e,t,n,r)=>De(e,t,n,r))(e,r.dbInfo.recipeType,t,n);if(a)try{await i.terminate(a)}catch(e){console.warn(`Error terminating widget "${n}" in thing "${t}". Failing silently: `,e)}}}},Ja=async(e,t,n,r)=>{const a=F(e),i=G(e,t,n);if(i&&a){const o=wa(i.type);if(o&&"function"==typeof o.initialize){const i=((e,t,n,r)=>De(e,t,n,r,!0))(e,a.dbInfo.recipeType,t,n);if(i){const e=o.initialize;try{await e(i,r||{})}catch(e){throw console.warn(`Error initializing widget "${n}" in thing "${t}": `,e),e}}}}},qa=(e,t)=>{const n=F(t);if(n)for(const t in n.blocks){const r=n.blocks[t];for(const t in r.gates)if(t===e)return{widget:r.gates[t],thing:r}}return null},Ka=(e,t="",n="")=>`block:${t}:gate:${n||""}:${e}`,Xa=e=>{_a.emit(Ka(za),e),_a.emit(Ka(za,e.blockId,e.gateId),e)};Ta=async e=>{await _a.emit(Ka(Ga),e),await _a.emit(Ka(Ga,e.blockId,e.gateId),e)},(e=>{La=e})(Xa);var Ya=async(e,t,n,r,a)=>{const i=z(e,{id:t,authorId:r,version:n,recipeType:a});Oa();const o=F(i);return o&&(o.startedAt=Date.now(),o.retryAttempts=0,o.execCounter=0,o.status=B.STARTING,o.addLog("recipe registered")),i},Za=async e=>{const t=F(e);var n;if(!t)return null;t.addLog("terminating recipe"),Va();for(const n in t.blocks){const r=t.blocks[n];for(const t in r.gates)await Ha(e,n,t)}R[n=e]&&delete R[n]},Qa=async(e,t)=>{const n=F(e),r=[];if(n)for(const a in n.blocks){const i=n.blocks[a];if(!t||!Array.isArray(t)||t.includes(a))for(const t in i.gates)try{await Ja(e,a,t,{keepCurrentState:!0})}catch(e){r.push(t)}}return{failed:r,sendToInputWidget:(t,n,r=X)=>(async(e,t,n,r)=>{const a=F(n),i=_(n,r),o=Date.now();if(i&&a)for(const a in i.gates){const s=i.gates[a];if(s.type===xe.input&&!s.disabled){const c=s.state.inputName||"";if(c===e){const e=wa(s.type),u={...t,timestamp:o},d=Fa(a,u,r,i.id,i.version,n);if(d&&e.processEvent){const i={...d,getState:d.getState};Ta&&await Ta({recipeId:n,blockId:r,gateId:a,targetPort:Re,data:t}),Ma?await Ma(r,n,c,t):await e.processEvent(u,i)}}}}})(t,n,e,r)}},ei=e=>{fa(e)},ti=(e,t,n,r=!1)=>{const a=qa(t,e);if(a){const{widget:i,thing:o}=a,s={...i.state};i.state=n,r&&Xa({blockId:o.recipeId,gateId:t,recipeId:e,newState:{...n},prevState:s})}},ni=(e,t)=>{const n=qa(t,e);return n?n.widget.state:null},ri=async(e,t,n,r,a)=>{const i=qa(t,e);if(i)return Wa(n,r,a,t,i.thing.recipeId,i.thing.id,i.thing.version,e)};const ai=e=>{try{return JSON.parse(e)}catch(e){return null}},ii="undefined"!=typeof window,oi={protocolPrefix:4,protocolVersion:1,jsonLength:4,binaryLength:4,fromServiceId:4,toServiceId:4,sentAt:8},si={protocolPrefix:4,txtLength:4},ci=Object.values(oi).reduce(((e,t)=>e+t),0),ui=Object.values(si).reduce(((e,t)=>e+t),0),di=["width","height","colorSpace"],li=(e,t)=>{const n={},r=[];let a=0,i=Array.isArray(e)?[]:{};const o=(e,i)=>{const s=(e=>{const t="undefined"!=typeof Buffer&&e instanceof Buffer,n=e instanceof ArrayBuffer,r=e instanceof Uint8ClampedArray,a=e instanceof Uint8Array,i=e instanceof Int8Array;return t?"Buffer":n?"ArrayBuffer":r?"Uint8ClampedArray":a?"Uint8Array":i?"Int8Array":null})(e);if(!s){if(Array.isArray(e)){const t=[];for(let n=0;n<e.length;n++)t[n]=o(e[n],`${i}[${n}]`);return t}if("object"==typeof e){const t={},n=(e=>{const t=e instanceof Int16Array,n=e instanceof Uint16Array,r=e instanceof Int32Array,a=e instanceof Uint32Array,i=e instanceof Float32Array,o=e instanceof Float64Array,s=e instanceof BigInt64Array,c=e instanceof BigUint64Array;return t?"Int16Array":n?"Uint16Array":r?"Int32Array":a?"Uint32Array":i?"Float32Array":o?"Float64Array":s?"BigInt64Array":c?"BigUint64Array":null})(e);if(n)throw new Error(`Unsupported binary type [${n}] at path "${i}"`);for(const n in e)e.hasOwnProperty(n)||di.includes(n)||console.warn(`Allowing inherited property: ${n} from path: ${i}`),t[n]=o(e[n],`${i.length?`${i}.`:""}${n}`);return t}return e}n[i]={index:a,length:e.byteLength,binaryType:s},"Buffer"===t?r.push(Buffer.from(e)):"ArrayBuffer"===s?r.push(e):r.push(e.buffer),a+=e.byteLength};i=o(e,"");let s=null;if(r.length>1)if("ArrayBuffer"===t){const e=r.reduce(((e,t)=>e+t.byteLength),0),t=new Uint8Array(e);let n=0;for(let e=0;e<r.length;e++)t.set(new Uint8Array(r[e]),n),n+=r[e].byteLength;s=t.buffer}else{s=Buffer.concat(r)}else 1===r.length&&(s=r[0]);return s?{map:n,combinedData:s,sourceCopy:i}:null},pi=(e,t,n)=>{const r=t.match(/(\[\d+\])|([^[\].]+)/g)||[];let a=e;for(let e=0;e<r.length;e++){let t=r[e];const i=t.startsWith("[")&&t.endsWith("]"),o=e===r.length-1;if(i){t=t.slice(1,-1);const i=parseInt(t,10);if(!Array.isArray(a))throw new Error(`Expected an array at key "${r.slice(0,e).join(".")}" but found an object.`);o?a[i]=n:(a[i]||(a[i]=r[e+1].startsWith("[")?[]:{}),a=a[i])}else o?a[t]=n:(a[t]||(a[t]=r[e+1].startsWith("[")?[]:{}),a=a[t])}return e},gi=(e,t,n)=>{const r="undefined"!=typeof Buffer,a=t instanceof Uint8Array;for(const i in n)if(n.hasOwnProperty(i)){const{index:o,length:s,binaryType:c}=n[i];let u=null;if(r&&t instanceof Buffer)switch(c){case"Buffer":u=t.subarray(o,o+s);break;case"ArrayBuffer":u=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength).slice(o,o+s);break;case"Uint8Array":u=new Uint8Array(t.subarray(o,o+s));break;case"Uint8ClampedArray":u=new Uint8ClampedArray(t.subarray(o,o+s));break;case"Int8Array":u=new Int8Array(t.subarray(o,o+s))}else if(t instanceof ArrayBuffer||t instanceof Uint8Array)switch(c){case"Buffer":if(r){u=Buffer.from(t.slice(o,o+s));break}case"ArrayBuffer":u=a?t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength).slice(o,o+s):t.slice(o,o+s);break;case"Uint8Array":u=a?t.slice(o,o+s):new Uint8Array(t.slice(o,o+s));break;case"Uint8ClampedArray":u=new Uint8ClampedArray(t.slice(o,o+s));break;case"Int8Array":u=new Int8Array(t.slice(o,o+s))}u&&pi(e,i,u)}return e},mi=e=>d(e),vi="KMSG",fi="KCMD",yi=mi("klProtocol");var hi={encode:(e,t,n)=>{const r={json:e.json},a=li(r.json,"Buffer"),i=a?.combinedData;a&&(r.jsonBinaryMap=a.map,r.json=a.sourceCopy);const o=i?i.byteLength:0,s=JSON.stringify(r),c=Buffer.from(s),u=c.byteLength,d=oi.protocolPrefix+oi.protocolVersion+oi.jsonLength+oi.binaryLength+oi.fromServiceId+oi.toServiceId+oi.sentAt+u+o,l=Buffer.alloc(d),p=Date.now();let g=0;return l.write(vi,g),g+=oi.protocolPrefix,l.writeUInt8(1,g),g+=oi.protocolVersion,l.writeUInt32LE(u,g),g+=oi.jsonLength,l.writeUInt32LE(o,g),g+=oi.binaryLength,l.writeUInt32LE(t,g),g+=oi.fromServiceId,l.writeUInt32LE(n,g),g+=oi.toServiceId,l.writeBigInt64LE(BigInt(p),g),g+=oi.sentAt,c.copy(l,g),g+=u,i&&o&&i.copy(l,g),l},decodeHeader:e=>{let t=0;const n=e.toString("utf-8",t,oi.protocolPrefix);if(t+=oi.protocolPrefix,n!==vi)return null;if(e.byteLength<ci)return yi(`Received a Partial Header with ${e.byteLength} bytes. Waiting for more data.`),{partialHeader:!0,remaining:null};const r=e.readUInt8(t);t+=oi.protocolVersion;const a=e.readUInt32LE(t);t+=oi.jsonLength;const i=e.readUInt32LE(t);t+=oi.binaryLength;const o=e.readUInt32LE(t);t+=oi.fromServiceId;const s=e.readUInt32LE(t);t+=oi.toServiceId;const c=e.readBigInt64LE(t);t+=oi.sentAt;const u=a+i,d=e.subarray(t,t+u),l=e.subarray(0,ci);let p=null;return e.byteLength-ci-a-i>0&&(p=e.subarray(ci+a+i)),{header:{protocolVersion:r,jsonLength:a,binaryLength:i,fromServiceId:o,toServiceId:s,sentAt:new Date(Number(c)),packages:[d],headerPackage:l},remaining:p}},decodeFullKlMessage:e=>{const t=Buffer.concat(e.packages),n=t.subarray(0,e.jsonLength).toString(),r=t.subarray(e.jsonLength,e.jsonLength+e.binaryLength),a=ai(n);if(!a?.json)return yi("Invalid JSON in KL message"),null;a.jsonBinaryMap&&r.byteLength&&gi(a.json,r,a.jsonBinaryMap);const i=Buffer.concat([e.headerPackage,t]);let o=i,s=null;const c=ci+e.jsonLength+e.binaryLength;return i.byteLength>c&&(s=i.subarray(c),o=i.subarray(0,c)),{message:{json:a.json,rawMessage:o},remaining:s}},patchEncodedHeader:(e,t)=>{if(null==t.fromServiceId&&void 0===t.toServiceId)return e;if(e.byteLength<ci)return yi("Invalid Header Size"),e;let n=0;return n+=oi.protocolPrefix,n+=oi.protocolVersion,n+=oi.jsonLength,n+=oi.binaryLength,void 0!==t.fromServiceId&&e.writeUInt32LE(t.fromServiceId,n),n+=oi.fromServiceId,void 0!==t.toServiceId&&e.writeUInt32LE(t.toServiceId,n),e},encodeCommand:e=>{let t=0;const n=Buffer.from(e),r=n.byteLength,a=ui+r,i=Buffer.alloc(a);return i.write(fi,t),t+=si.protocolPrefix,i.writeUint32LE(r,t),t+=si.txtLength,n.copy(i,t),i},decodeCommand:e=>{let t=0;if(e.byteLength<ui)return{command:null};const n=e.toString("utf-8",t,si.protocolPrefix);if(t+=si.protocolPrefix,n!==fi)return{command:null};const r=e.readUInt32LE(t);t+=si.txtLength;const a=e.toString("utf-8",t,t+r),i=e.byteLength-ui-r;let o=null;i>0&&(o=e.subarray(ui+r));let s=0;return i<0&&(s=Math.abs(i)),{command:a,remainingData:o,missing:s}}};const Ii="KMSG",Si="KCMD",$i=mi("klProtocol"),wi=new TextEncoder;var bi={encode:(e,t,n)=>{const r={json:e.json},a=li(e.json,"ArrayBuffer"),i=a?.combinedData;a&&(r.jsonBinaryMap=a.map,r.json=a.sourceCopy);const o=i?i.byteLength:0,s=JSON.stringify(r),c=wi.encode(s),u=c.byteLength,d=new ArrayBuffer(oi.protocolPrefix+oi.protocolVersion+oi.jsonLength+oi.binaryLength+oi.fromServiceId+oi.toServiceId+oi.sentAt+u+o),l=new DataView(d),p=new Uint8Array(d),g=Date.now();let m=0;for(let e=0;e<4;++e)p[m++]=Ii.charCodeAt(e);return l.setUint8(m,1),m+=oi.protocolVersion,l.setUint32(m,u,!0),m+=oi.jsonLength,l.setUint32(m,o,!0),m+=oi.binaryLength,l.setUint32(m,t,!0),m+=oi.fromServiceId,l.setUint32(m,n,!0),m+=oi.toServiceId,l.setBigInt64(m,BigInt(g),!0),m+=oi.sentAt,p.set(c,m),m+=u,i&&o&&p.set(new Uint8Array(i),m),d},decodeHeader:e=>{const t=new DataView(e);let n=0,r="";for(let e=0;e<oi.protocolPrefix;++e)r+=String.fromCharCode(t.getUint8(n++));if(r!==Ii)return null;if(e.byteLength<ci)return $i.log(`Received a Partial Header with ${e.byteLength} bytes. Waiting for more data.`),{partialHeader:!0,remaining:null};const a=t.getUint8(n);n+=oi.protocolVersion;const i=t.getUint32(n,!0);n+=oi.jsonLength;const o=t.getUint32(n,!0);n+=oi.binaryLength;const s=t.getUint32(n,!0);n+=oi.fromServiceId;const c=t.getUint32(n,!0);n+=oi.toServiceId;const u=t.getBigInt64(n,!0);n+=oi.sentAt;const d=i+o,l=e.slice(n,n+d),p=new Uint8Array(e,0,ci);let g=null;if(e.byteLength-ci-i-o>0){g=new Uint8Array(e,ci+i+o).slice().buffer}return{header:{protocolVersion:a,jsonLength:i,binaryLength:o,fromServiceId:s,toServiceId:c,sentAt:new Date(Number(u)),packages:[l],headerPackage:p.slice().buffer},remaining:g}},decodeFullKlMessage:e=>{const t=e.packages.reduce(((e,t)=>e+t.byteLength),0),n=new Uint8Array(t);let r,a=0;for(const t of e.packages)r=new Uint8Array(t),n.set(r,a),a+=r.byteLength;const i=(new TextDecoder).decode(n.subarray(0,e.jsonLength)),o=n.subarray(e.jsonLength,e.jsonLength+e.binaryLength),s=ai(i);if(!s?.json)return $i.log("Invalid JSON in KL message"),null;s.jsonBinaryMap&&o.byteLength&&gi(s.json,o,s.jsonBinaryMap);const c=new Uint8Array(e.headerPackage.byteLength+n.byteLength);c.set(new Uint8Array(e.headerPackage),0),c.set(n,e.headerPackage.byteLength);let u=c,d=null;const l=ci+e.jsonLength+e.binaryLength;return c.byteLength>l&&(d=c.subarray(l),u=c.subarray(0,l)),{message:{json:s.json,...o.length?{binaryData:o.buffer}:{},rawMessage:u.buffer},remaining:d?.buffer??null}},patchEncodedHeader:(e,t)=>{if(null==t.fromServiceId&&void 0===t.toServiceId)return e;if(e.byteLength<ci)return $i("Invalid Header Size"),e;let n=0;n+=oi.protocolPrefix,n+=oi.protocolVersion,n+=oi.jsonLength,n+=oi.binaryLength;const r=new DataView(e);return void 0!==t.fromServiceId&&r.setUint32(n,t.fromServiceId,!0),n+=oi.fromServiceId,void 0!==t.toServiceId&&r.setUint32(n,t.toServiceId,!0),e},encodeCommand:e=>{let t=0;const n=wi.encode(e),r=n.byteLength,a=new ArrayBuffer(ui+r),i=new DataView(a),o=new Uint8Array(a);for(let e=0;e<4;++e)o[t++]=Si.charCodeAt(e);return i.setUint32(t,r,!0),t+=si.txtLength,o.set(n,t),a},decodeCommand:e=>{const t=new DataView(e);let n=0;if(e.byteLength<ui)return{command:null};let r="";for(let e=0;e<si.protocolPrefix;++e)r+=String.fromCharCode(t.getUint8(n++));if(r!==Si)return{command:null};const a=t.getUint32(n,!0);n+=si.txtLength;const i=e.byteLength-ui-a,o=new Uint8Array(e,n,Math.min(a,e.byteLength-ui)),s=(new TextDecoder).decode(o);let c=null;i>0&&(c=e.slice(ui+a));let u=0;return i<0&&(u=Math.abs(i)),{command:s,remainingData:c,missing:u}}};let Ni=hi;ii&&(Ni=bi);var Ai,xi=Ni;!function(e){e.FunctionNotFound="FNC_NOT_FOUND"}(Ai||(Ai={}));let Pi=Math.ceil(Date.now()/1e3);function Ci(e){const t={};let n=console.log;const r={};let a=e||String(Date.now());const i={},o=e=>!i[e],s=(e,t,n,r,a,i)=>{let s=ii?new ArrayBuffer(0):Buffer.alloc(0);const c={json:{functionName:e,args:i.success?i.success:[i],messageId:t,type:i.success?"response":"error"}};return o(r)&&(s=xi.encode(c,n,r)),a(s,{msg:c,sourceServiceId:n,targetServiceId:r})};return{setLogger:e=>{n=e},processMessage:(e,a,i,o)=>{if(!o)return!1;const c=o;if(t[c.messageId]){const e=t[c.messageId];return e&&(clearTimeout(e.timer),e.fulfilled||(e.fulfilled=!0,"response"===c.type?e.resolve(c.args):"error"===c.type&&e.reject(c.args[0])),delete t[c.messageId]),!0}if("execute"!==c.type&&n&&n(`No pending execution found for message id "${c.messageId}"`),"execute"===c.type){const t=r[c.functionName];if(t){const n=e=>{s(c.functionName,c.messageId,i.targetServiceId,i.sourceServiceId,a,e)};t({transport:e,args:c.args,reply:n,messageId:c.messageId,sourceServiceId:i.sourceServiceId,send:a})}else{const e=`Function "${c.functionName}" not found.`;n&&n(e),s(c.functionName,c.messageId,i.targetServiceId,i.sourceServiceId,a,{error:e,errCode:"FNC_NOT_FOUND"})}return!0}return!1},execute:async(e,r,i,s,c,u)=>{if(!i){const e="No send buffer function provided.";throw n&&n(e),e}Pi+=1;const d=`${a}-${Pi}-exec-${e.substring(0,10)}`,l={messageId:d,functionName:e,send:i,sourceServiceId:s,targetServiceId:c,args:r||[],fulfilled:!1,resolve:()=>{},reject:()=>{}};l.promise=new Promise(((e,t)=>{l.resolve=e,l.reject=t}));let p=ii?new ArrayBuffer(0):Buffer.alloc(0);const g={json:{functionName:e,args:r,messageId:d,type:"execute"}};o(c)&&(p=xi.encode(g,s,c)),t[d]=l,n&&n(`Calling remote function "${e}" with message id "${d}"`);const m="true"===process.env.NO_INVOKE_TIMEOUT;return u?.async?(l.fulfilled=!0,l.resolve([void 0]),delete t[d]):0===u?.timeout||m||(l.timer=setTimeout((()=>{n&&n(`Remote function ${d} timed out`);const r=t[d];r&&!r.fulfilled&&(r.fulfilled=!0,l.reject(`Function ${e} Timed out`)),delete t[d]}),u?.timeout||3e4)),i(p,{sourceServiceId:s,targetServiceId:c,msg:g}),l.promise},sendResponse:s,registerFunction:(e,t)=>{r[e]=t},getTransportSendFunction:e=>{const n=t[e];return n?n.send:null},setServiceName:e=>{a=e},getPendingExecutions:()=>t,rejectAllPending:e=>{Object.keys(t).forEach((n=>{const r=t[n];r&&!r.fulfilled&&(clearTimeout(r.timer),r.fulfilled=!0,r.reject(e),delete t[n])}))},broadcast:(e,t,r,i)=>{Pi+=1;const s=`${a}-${Pi}-multicast-${e.substring(0,10)}`;let c=ii?new ArrayBuffer(0):Buffer.alloc(0);const u={json:{functionName:e,args:t,messageId:s,type:"execute"}};let d=o(r[0].serviceId);d&&(c=xi.encode(u,i,r[0].serviceId));for(let t=0;t<r.length;t++)try{const a=r[t];n&&n(`Broadcasting function "${e}" with message id "${s}" to client [${a.serviceId}]`),0!==t&&(d=o(a.serviceId),d&&(c=xi.patchEncodedHeader(c,{toServiceId:a.serviceId}))),a.sendFn(c,{msg:u,sourceServiceId:i,targetServiceId:a.serviceId})}catch(e){n&&n(`Error broadcasting to client at index ${t}`)}},disableServiceEncoding:(e,t)=>{i[e]=t}}}let Ei,ji,ki,Di,Oi,Ti=!1;var Li=()=>{Ti=!0},Mi=(e,t)=>{if(!Ei)throw new Error("Memory connection not set.");Ei.sendBuf(e,t)},Bi=e=>ji=e,Ri=e=>Oi=e,Wi=e=>ki=e,Ui=e=>Di=e,Fi=e=>(Ei.sendCmd(e),!0);const _i=mi("klTransmissionManager"),Gi=()=>{const e=(t,n,r,a)=>{let i=n,o=null;const s=t instanceof ArrayBuffer;if(_i(`RAW: ${t.toString()}`),!i||i.partialHeaderData){let c;if(s?(c=i?.partialHeaderData?new Uint8Array([...new Uint8Array(i.partialHeaderData),...new Uint8Array(t)]).buffer:t,o=bi.decodeHeader(c)):(c=i?.partialHeaderData?Buffer.concat([i.partialHeaderData,t]):t,o=hi.decodeHeader(c)),!o){const{command:t,missing:i,remainingData:o}=s?bi.decodeCommand(c):hi.decodeCommand(c);return t?a({command:t,complete:!0,rawMessage:c}):_i(i?`ERROR: Missing ${i} bytes to complete the command. This partial command will be aborted.`:`ERROR: Invalid state, message was decoded without a header or partial header data. Discarding ${c.byteLength} bytes`),o?(_i(`${o.byteLength} bytes remain after processing command. Re-analyzing...`),e(o,n,r,a)):void 0}if(o.partialHeader)return i={firstPackageAt:Date.now(),partialHeaderData:c},r(i);if(!o.header)return _i(`ERROR: Invalid state, message was decoded without a header or partial header data. Discarding ${c.byteLength} bytes`);const u=o.header;i={firstPackageAt:Date.now(),header:{...u,totalBytesReceived:u.packages[0].byteLength,totalBytesExpected:u.binaryLength+u.jsonLength,remaining:o.remaining}},r(i)}else i.header&&i.header.totalBytesReceived<i.header.totalBytesExpected&&(i.header.packages.push(t),i.header.totalBytesReceived+=t.byteLength,r(i));if(i.header&&i.header.totalBytesReceived>=i.header.totalBytesExpected){const t=Date.now()-i.header.sentAt.getTime(),n=Date.now()-i.firstPackageAt;_i(`Received ${i.header.totalBytesReceived} of ${i.header.totalBytesExpected} expected in ${t} ms, elapsed since first package: ${n}ms`);const o=s?bi.decodeFullKlMessage(i.header):hi.decodeFullKlMessage(i.header),c=i.header.totalBytesReceived,u=i.header.remaining;r(null),o&&a({klMessage:o.message,complete:!0,sourceServiceId:i.header.fromServiceId,targetServiceId:i.header.toServiceId,rawMessage:o.message.rawMessage});let d=u;if(o?.remaining&&(d=s?u?((e,t)=>{const n=e.byteLength+t.byteLength,r=new ArrayBuffer(n),a=new Uint8Array(e),i=new Uint8Array(t),o=new Uint8Array(r);return o.set(a),o.set(i,a.length),r})(u,o.remaining):o.remaining:u?Buffer.concat([u,o.remaining]):o.remaining),d)return _i(`${d.byteLength} bytes remaining after processing message with ${c} bytes of data. Re-analyzing...`),e(d,null,r,a)}};return e};mi("ipcClient");mi("kemuWidgetService"),$(process.argv.slice(2));const zi=e=>d(`runner:${e}`),Vi=zi("connectionManager"),Hi=zi("remoteInvoke"),Ji=new Ci("kweb");Ji.setLogger(Hi);const qi=new o,Ki=new o;let Xi,Yi=null,Zi=null;const Qi={},eo=(e,t,n)=>{const r=`${e}_${t}`,a={contents:n,lastRequestedAt:Date.now(),contentsChecksum:""};return Qi[r]=a,a},to=(e,t)=>Qi[`${e}_${t}`]||null,no=async(e,t)=>{if(!Yi)return Vi("Hub Link has not been acknowledged. Cannot get services."),null;const n=[{serviceName:e,version:t}];return(await Ji.execute(ne.GetServiceContents,n,ao,Yi,0))[0]},ro=async(e,t,n=!1)=>{if(!e||!t)return null;const r=to(e,t);if(!r||n){const n=r||eo(e,t);try{const r=await no(e,t);return r&&(n.contents=r.uiContent,n.contentsChecksum=r.uiContentsChecksum||""),n.contents||null}catch(n){Vi(`Failed to fetch service contents for ${e} v${t}`,n)}}return r?.contents||null},ao=Mi,io=()=>{Vi("Disconnected from the server"),Yi=null,Ji.rejectAllPending("Disconnected from the server"),qi.emit("disconnected")},oo=()=>{Vi("Connected to the server"),qi.emit("connected")},so=()=>Zi,co=(e,t,n,r)=>`${e}_${t}_${n}_${r}`,uo=async()=>{const e=so();if(e){const t=F(e)?.blocks;if(t){const n={};for(const r in t){const a=t[r];for(const t in a.gates){const r=a.gates[t];if(r.type===xe.hubService){const t=r.state;if(t.service?.eventEmitter){const r=`${t.service.name}_${t.service.version}`;if(!n[r])try{Vi(`Re-issuing subscription for service ${t.service.name} (${t.service.version})`),n[r]=!0,await No({listener:{recipeId:e},targetService:{serviceName:t.service.name,version:t.service.version}})}catch(e){Vi(`Failed to re-issue subscription for service ${t.service.name} (${t.service.version})`,e)}}}}}}}},lo=async e=>{const t=e.args[0],n=co("broadcast",`hub_${t.type}`,(0).toString(),"");await Ki.emit(n,t)},po=async e=>{const t=e.args[0];for(const e of t.outputs||[])e.type===Z.ImageData&&ye(e.value)&&(e.value=Ne(e.value));const n=so();if(n){const r=F(n);if(r){const a=async e=>{const n=co("broadcast",t.source.serviceName,t.source.serviceVersion,e);try{await Ki.emit(n,t)}catch(t){Vi(`Failed to emit broadcast event for target ${e}`,t)}};await a("app");for(const i in r.blocks){const o=r.blocks[i];for(const r in o.gates){const i=o.gates[r];if(i.disabled)continue;const s=i.state;if(i.type===xe.hubService&&s.service?.name===t.source.serviceName&&s.service?.version===t.source.serviceVersion&&s.variantId===t.variantId){await a(r);for(const a of t.outputs||[])if(null!==a.value&&void 0!==a.value){const t={type:a.type,value:a.value,timestamp:Date.now()};Vi(`Sending data to output ${a.name} requested by messageId ${e.messageId}`),await ri(n,r,a.name,t,t)}}}}}}},go=async e=>{const t=e.args[0],{finalState:n,recipeId:r,widgetId:a}=t,i=ni(r,a);let o=i;if(n&&o&&i&&(o={...i,customState:n},ti(r,a,o,!0)),o?.service)try{const e=co("setOutputs",o.service.name,o.service.version,a);await Ki.emit(e,t.outputs)}catch(e){Vi(`Failed to emit setOutputs event for widget ${a}`,e)}for(const n of t.outputs)if(null!==n.value&&void 0!==n.value){if(n.type===Z.ImageData){if(!ye(n.value)){Vi(`Invalid ImageData value received for output ${n.name}. Expected an ImageData-like object`);continue}n.value=Ne(n.value)}const t={type:n.type,value:n.value,timestamp:Date.now()};Vi(`Sending data to output ${n.name} requested by messageId ${e.messageId}`),await ri(r,a,n.name,t,t)}e.reply({success:[]})},mo=async e=>{const t=e.args[0],{newState:n,recipeId:r,widgetId:a}=t,i=ni(r,a);if(i){const t={...i,customState:{...i.customState,...n}};return ti(r,a,t,!0),e.reply({success:[]})}},vo=async({args:e,reply:t})=>{const n=e[0],{recipeId:r,widgetId:a,path:i,key:o}=n;Vi(`Received request to set a dependency path for "${o}" on widget "${a}" in recipe "${r}"`);const s=ni(r,a);if(s){const e={...s};e.dependencies=e.dependencies||{},e.dependencies[o]={path:i},ti(r,a,e,!0)}return t({success:[]})},fo=async({args:e,reply:t})=>{const n=e[0],{recipeId:r,widgetId:a,key:i}=n;Vi(`Received request to get a dependency path for "${i}" on widget "${a}" in recipe "${r}"`);const o=ni(r,a);if(o){const e=o.dependencies?.[i]?.path;return Vi(`Returning dependency path for "${i}" on widget "${a}": "${e}"`),t({success:[e||null]})}return t({error:"Widget not found",errCode:"WIDGET_NOT_FOUND"})},yo=async()=>{if(Vi(`Requesting services on ${(new Date).toISOString()}`),!Yi)return Vi("Hub Link has not been acknowledged. Cannot get services."),[];const e=await Ji.execute(ne.GetServices,[],ao,Yi,0);Xi=e;for(const t of e){if(t.internal)continue;const e=to(t.name,t.version);if(!e||e?.contentsChecksum!==t.uiContentChecksum)try{const n=e||eo(t.name,t.version);Vi(`Service ${t.name} v${t.version} contents have changed, fetching new contents`);const r=await no(t.name,t.version);r&&(n.contents=r.uiContent,n.contentsChecksum=t.uiContentChecksum||"")}catch(e){Vi(`Failed to update service contents for ${t.name} v${t.version}`,e)}}return e},ho=()=>[...Xi||[]],Io=()=>!!Xi,So=async e=>{const{targetServiceSessionId:t}=e;if(!Yi)return void Vi("No target service session id provided");Vi(`Forwarding "onParentEvent" to service ${t}`);return await Ji.execute(ne.OnParentEvent,[e],ao,Yi,t,e.config)},$o=async e=>{if(!Yi)return Vi("Hub Link has not been acknowledged. Cannot get services."),{};const[t]=await Ji.execute(ne.GetDefaultState,[],ao,Yi,e);return t},wo=async(e,t,n,r)=>{if(!Yi)return Vi("Hub Link has not been acknowledged. Cannot get services."),null;const[a]=await Ji.execute(ne.UIEvent,[t,n],ao,Yi,e,r);return a},bo=(e,t)=>{const n=()=>{t()};return qi.on(e,n),()=>qi.off(e,n)},No=async e=>{if(Yi)return Ji.execute(ne.SubscribeToService,[e],ao,Yi,0);Vi("Hub Link has not been acknowledged. Cannot subscribe to services.")},Ao=async e=>{if(Yi)return Ji.execute(ne.UnsubscribeFromService,[e],ao,Yi,0);Vi("Hub Link has not been acknowledged. Cannot subscribe to services.")},xo=(e,t,n,r)=>{const a=co("broadcast",t,n,e);return Ki.on(a,r)},Po=(e,t,n,r)=>{const a=co("setOutputs",t,n,e);return Ki.on(a,r)},Co=async(e,t,n)=>Yi?Ji.execute(e,t,ao,Yi,0,n):(Vi("Hub Link has not been acknowledged. Cannot execute function."),null),Eo=async e=>{if(!Yi)return void Vi("Hub Link has not been acknowledged. Cannot execute function.");const t=ni(e.recipeId,e.widgetId);if(!t)throw new Error("Widget or recipe pool not found. Cannot initialize service instance.");const n=Object.keys(t.dependencies||{}).reduce(((e,n)=>(e[n]=t.dependencies?.[n]?.path||null,e)),{}),r=[{currentState:t.customState,recipeId:e.recipeId,widgetId:e.widgetId,variantId:e.variantId,recipeType:e.recipeType,currentDependencies:n}],[a]=await Ji.execute(ne.InitializeInstance,r,ao,Yi,e.sessionId);if(a){const t=ni(e.recipeId,e.widgetId);if(t){const n={...t,customState:a};ti(e.recipeId,e.widgetId,n,!0)}}},jo=async(e,t,n,r)=>{if(!Yi)return void Vi("Hub Link has not been acknowledged. Cannot execute function.");const a=ni(n,t);if(!a)throw new Error("Widget or recipe pool not found. Cannot initialize service instance.");const i=[{currentState:a.customState,recipeId:n,widgetId:t,variantId:r}];await Ji.execute(ne.TerminateInstance,i,ao,Yi,e)},ko=async(e,t,n="^",r)=>{const a=["^","~",">=",">","<=","<","="];if(!a.includes(n))throw new Error(`Invalid compare mode "${n}". Must be one of ${a.join(", ")}`);const i=Io(),o=r||!i?await yo():ho();for(const r of o)if(r.name===e){if(r.version===t)return r;if(c(r.version,`${n}${t}`))return r}return null};var Do=async()=>{Wi(oo),Ui(io),Ri((({json:e,transmission:t})=>{Ji.processMessage("websocket",ao,t,e)})),Ji.registerFunction(ne.SetState,mo),Ji.registerFunction(ne.SetOutputs,go),Ji.registerFunction(ne.BroadcastEvent,po),Ji.registerFunction(ne.HubBroadcastEvent,lo),Ji.registerFunction(re.SetDependencyPath,vo),Ji.registerFunction(re.GetDependencyPath,fo),Bi((e=>{((e,t)=>{const n=te.SocketAcknowledge,r=te.IpcAcknowledge,a=e.startsWith(n);if(e===r)return t&&t(),0;if(a){const i=e.split(a?n:r),o=parseInt(i[1]);return t&&t(o),o}})(e,(e=>{e?(Fi((e=>`${te.AcknowledgeResponse}${e}`)(e)),Vi("Hub Link acknowledged"),Yi=e,qi.emit("acknowledged"),uo()):Vi("Hub sent ACK request without service id")})),((e,t)=>{e===te.ServicesListChanged&&(t&&t())})(e,(()=>{Vi("Services list changed"),qi.emit("services-changed")}))})),await Li()},Oo=(e,t)=>{qi.on(e,t)},To=()=>({getServices:yo,getServiceContents:ro,onParentEvent:So,onCommand:bo,getDefaultState:$o,getCachedServices:ho,areServicesCached:Io,subscribeToServiceEvents:No,unsubscribeFromServiceEvents:Ao,callProcessorHandler:wo,onBroadcastEvent:xo,onSetOutputsEvent:Po,executeHubFunction:Co,initializeServiceInstance:Eo,terminateServiceInstance:jo,getCompatibleService:ko}),Lo=e=>{Zi=e},Mo=()=>Ji;const Bo=e=>{try{return JSON.parse(e)}catch(e){return null}},Ro=(e,t)=>{if(e.startsWith(te.AcknowledgeResponse)){const n=e.split(":"),r=parseInt(n[1]),a=parseInt(n[2]);return t&&t(r,isNaN(a)?void 0:a),!0}return!1},Wo=e=>d(e),Uo=Date.now();let Fo=Math.ceil(Uo/1e3);var _o=()=>Fo+=1;const Go=p(x(),"kemu-user-services"),zo="KMU-CB-v1";var Vo;!function(e){e.input="input",e.counter="counter",e.play="play",e.elapsed="elapsed",e.ifGate="ifGate",e.skipEvent="skipEvent",e.between="between",e.map="map",e.parser="parser",e.slider="slider",e.suspend="suspend",e.display="display",e.pixelfy="pixelfy",e.json="json",e.arrayItem="arrayItem",e.extractImage="extractImage",e.imageConvolution="imageConvolution",e.firstEvent="firstEvent",e.pixelDraw="pixelDraw",e.randomBetween="randomBetween",e.arrayCombine="arrayCombine",e.clock="clock",e.multiplication="multiplication",e.object="object",e.widgetGroup="widgetGroup",e.script="script",e.base64ToImageData="base64ToImageData",e.jsonParse="jsonParse",e.text="text",e.imageCrop="imageCrop",e.imageResize="imageResize",e.value="value",e.imageWarp="imageWarp",e.widgetBundle="widgetBundle",e.sequence="sequence",e.variable="variable",e.hubService="hubService"}(Vo||(Vo={}));const Ho=e=>({...e,type:Array.isArray(e.type)?e.type.map((e=>Z[e])):Z[e.type]}),Jo=async e=>{try{return await f(e,"utf-8")}catch(e){return null}},qo=e=>{if(e&&e.startsWith(zo)){const t=e.slice(9),n=decodeURI(t);return Bo(n)}return null},Ko=async(e,t,n)=>{let r=[];e.variants?.length&&(r=e.variants.map((e=>({...e,...e.inputs?{inputs:e.inputs.map(Ho)}:{},...e.outputs?{outputs:e.outputs.map(Ho)}:{}}))));const a={...e,path:t,customWidgets:[],...e.inputs?{inputs:e.inputs.map(Ho)}:{inputs:[]},...e.outputs?{outputs:e.outputs.map(Ho)}:{outputs:[]},variants:r,...e.widgetUI&&n?.widgetUIContents?{widgetUIContents:n.widgetUIContents}:{}},i=await(async(e,t,n=console.log)=>{const r=[];if(t.customWidgets?.length)for(const a of t.customWidgets){const t=await Jo(p(e,a));if(!t){n(`Error loading custom widget file ${a}`);continue}const i=t.startsWith(zo)?t:`${zo}${t}`,o=qo(i);if(!o){n(`Custom widget file "${a}" is not a valid Kemu Clipboard item`);continue}const s=Object.values(o).filter((e=>e.type===Vo.widgetGroup&&!e.groupId));if(s.length>1){n(`Custom widget file "${a}" contains more than one top level widgetGroup`);continue}const c=s[0];if(!c){n(`Custom widget file "${a}" does not contain a top level widgetGroup`);continue}const u=c.state,d={name:u.name,color:u.color,description:u.description,contents:i,rootGroupId:c.id,icon:u.icon,protocolVersion:u.protocolVersion||"2"};r.push(d)}return r})(t,e,n?.log);if(i.length?a.customWidgets=i:delete a.customWidgets,a.variants?.length)for(const e of a.variants)if(e.svgIcon)try{const n=await f(p(t,e.svgIcon),"utf-8");e.svgIcon=n}catch(t){n?.log&&n?.log(`Error loading svgIcon for variant ${e.id}: ${t}`)}return a},Xo=async e=>{try{return await y(e,h.F_OK),!0}catch{return!1}},Yo=Wo("serviceManager"),Zo={};let Qo=null;const es=e=>{if(!Qo)throw new Error('IPC config not set, call "setHubIpcConfig" first.');try{if(e.processor===ee.Javascript){Yo(`Spawning service ${e.name} with sessionId ${e.sessionId}`);const t=l.join(e.path,"processor.js"),n=[`--sessionId=${e.sessionId.toString()}`,`--ipcSpace=${Qo.appSpace}`,`--ipcId=${Qo?.id}`,`--recipePath=${Qo.recipePath||""}`];e.internal&&n.push("--internal=true");const r=N("node",[t,...n]);return r.stdout.on("data",(t=>{Yo(`[Service ${e.name}] - stdout: ${t}`)})),r.stderr.on("data",(t=>{Yo(`[Service ${e.name}] - stderr: ${t}`)})),Yo(`[Service ${e.name}] spawned with PID ${r.pid}`),r}throw`Unsupported processor type ${e.processor}`}catch(t){throw`Error spawning service ${e.name}: ${t}`}},ts=e=>{if(!e?.name)return"Missing name";if(!e?.version)return"Missing version";if(!e?.description)return"Missing description";if(!e?.processor)return"Missing processor";return[ee.Javascript,ee.Executable,ee.Python].includes(e?.processor)?null:"Invalid processor"},ns=async(e,t)=>{const n=l.join(e,"manifest.json");if(!w.existsSync(n)){const t=`Missing manifest for service ${e}. Aborting.`;return Yo(t),{error:t}}const r=await f(n,"utf-8"),a=Bo(r),i=ts(a);if(!a||i){const t=`Invalid service manifest [${e}]: ${i}. Aborting.`;return Yo(t),{error:t}}let o;if(delete a.internal,t?.singleServiceName&&a.name!==t.singleServiceName){return{error:`Skipping service ${a.name} as it does not match the singleServiceName option`}}await Promise.all([(async()=>{if(a.widgetUI)try{o=await f(l.join(e,"widgetUI.js"))}catch(e){const t=`Error loading widgetUI file ${a.name}: ${e}`;return Yo(t),{error:t}}})(),(async()=>{if(a.svgIcon){const t=await Jo(l.join(e,a.svgIcon));if(!t){return{error:`Error loading icon for service ${a.name}`}}a.svgIcon=t}})(),(async()=>{if(a.subServices?.length)for(const t of a.subServices){const n=l.join(e,t),{error:r,service:i}=await ns(n);r?Yo(`Error loading sub-service ${t}: ${r}`):i&&(i.info.parentService={name:a.name,version:a.version})}delete a.subServices})(),(async()=>{if(a.variants?.length)for(const t of a.variants)if(t.svgIcon)try{const n=await f(l.join(e,t.svgIcon),"utf-8");t.svgIcon=n}catch(e){Yo(`Error loading svgIcon for variant ${t.id}: ${e}`)}})()]);const s=_o(),c=t?.fixedSession||s;Yo(`Loaded service ${a.name} with sessionId ${c}`);const u=await Ko(a,e,{widgetUIContents:o});return rs(u),Zo[c]={info:{...u,path:e,sessionId:c},status:"loaded",childProcess:null},{service:Zo[c]}},rs=e=>{e.widgetUIContents?e.uiContentChecksum=(e=>{const t=A("sha256");return t.update(e),t.digest("hex")})(e.widgetUIContents):e.uiContentChecksum=void 0},as=e=>{try{return e.childProcess=es(e.info),e.status="started",!0}catch(t){return Yo(`Service [${e.info.name}] error: ${t}`),e.status="error",e.errorMsg="string"==typeof t?t:JSON.stringify(t),!1}},is=()=>Object.values(Zo).filter((e=>"running"===e.status)).map((e=>{const{path:t,...n}=e.info;return{...n}})),os=(e,t)=>{const n=Object.values(Zo).find((n=>n.info.name===e&&n.info.version===t));if(!n)return null;if(n.info.internal)throw`Cannot stop internal service ${e}`;if(n.childProcess){Yo(`Stopping service "${e} (v${t})"`);n.childProcess.kill("SIGINT")||Yo(`Failed to stop service ${e}`)}return n.status="stopped",Yo(`Service ${e} stopped`),n},ss=e=>e.info.internal?e.info.path:l.join(e.info.path,"..");var cs={loadServices:async(e,t)=>{if(!await Xo(e))return void Yo(`Failed to load services from "${e}". Directory does not exist.`);const n=w.readdirSync(e,{withFileTypes:!0}).filter((e=>e.isDirectory())).map((e=>e.name));Yo(`Found ${n.length} services in "${e}"`);for(let r=0;r<n.length;r++){const a=n[r],i=l.join(e,a),{error:o,service:s}=await ns(`${i}${t?.internalServices?"":"/dist"}`,t);o&&Yo(`Failed to load service ${i}. Please check logs`),s&&t?.internalServices&&(s.info.internal=!0)}},launchServices:async e=>{if(Yo("Initializing services"),!Qo)throw new Error('IPC config not set, call "setHubIpcConfig" first.');for(const t in Zo){const n=Zo[t];e.noSpawningList&&e.noSpawningList.includes(n.info.name)?Yo(`Service ${n.info.name} is in the noSpawningList. Skipping.`):as(n)}Yo("Services initialized")},setServiceStatus:(e,t)=>{const n=Zo[e];return n?(n.status=t,!0):(Yo(`Service with serviceId ${e} not found`),!1)},getActiveServices:is,getMatchingService:(e,t)=>{const n=Object.values(Zo).filter((e=>"running"===e.status));for(const r of n)if(r.info.name===e){if(r.info.version===t)return r;if(u(r.info.version,t,">="))return r}return null},getServiceBySessionId:e=>Zo[e]||null,killAllServices:()=>{for(const e in Zo){const t=Zo[e];if(t.childProcess)try{Yo(`Killing service ${t.info.name} with PID ${t.childProcess.pid}`),t.childProcess.kill()}catch(e){Yo(`Error killing service ${t.info.name}: ${e}`)}}},addDevService:async(e,t,n)=>{const r={info:{...await Ko(t,t.path),sessionId:e},status:n,startedAt:new Date,devMode:!0,childProcess:null};Zo[e]=r,rs(Zo[e].info)},setServiceManifest:(e,t,n)=>{const r=Zo[e];if(!r)return Yo(`Service with sessionId ${e} not found`),!1;const a=ts(t);if(a)return Yo(`Invalid manifest for service ${r.info.name}: ${a}`),!1;rs(t),r.info={...r.info,...t},n&&(r.status=n)},getMatchingDevService:(e,t,n)=>{const r=Object.values(Zo).filter((e=>e.devMode));for(const a of r)if(a.info.name===e&&a.status===n&&a.info.version===t)return a;return null},getInternalServices:()=>is().filter((e=>e.internal)),getAllServices:()=>Object.values(Zo),stopService:os,uninstallService:async(e,t)=>{Yo(`Uninstalling service ${e} v${t}`);const n=os(e,t);if(!n)return!1;Yo(`Service ${e} stopped. Removing from disk...`);const r=ss(n),a=Go;return r.startsWith(a)?(await I(r,{recursive:!0,force:!0}),Yo(`Service ${e} successfully removed from disk`),(e=>{const t=Zo[e];delete Zo[e]})(n.info.sessionId),!0):(Yo(`Service ${e} is not installed in the user services directory. Aborting.`),!1)},getAllServiceVersions:e=>Object.values(Zo).filter((t=>t.info.name===e)),setHubIpcConfig:e=>{Qo={...e}},loadAndLaunch:async(e,t,n)=>{const r=g(e,t),{error:a,service:i}=await ns(r);if(a||!i)return{error:a};try{i.info.internal=!!n,i.childProcess=es(i.info),i.status="started"}catch(e){Yo(`Error launching service ${i.info.name}: ${e}`),i.status="error",i.errorMsg="string"==typeof e?e:JSON.stringify(e)}return{service:i}},getServiceRootDirectory:ss};var us={id:"widgets",retry:1500,silent:!0,rawBuffer:!0,appspace:"kemu.",encoding:"hex"};const ds=Object.values({protocolPrefix:4,protocolVersion:1,jsonLength:4,binaryLength:4,fromServiceId:4,toServiceId:4,sentAt:8}).reduce(((e,t)=>e+t),0);v.config={...v.config,...us};const ls=Wo("ipcServer");let ps,gs,ms,vs,fs={};const ys=Gi(),hs=e=>{fs[e]&&(ls(`Client disconnected [${e}]`),delete fs[e],gs&&gs(e))};var Is=e=>(e?.ipcId&&(v.config.id=e.ipcId),e?.ipcAppSpace&&(v.config.appspace=e.ipcAppSpace),new Promise((e=>{v.serve((()=>{ls("IPC Server Initiated"),v.server.on("data",((e,t)=>{const n=fs[t.id];n?(ls(`IPC Socket [${t.id}] data ${e.byteLength} bytes`),ys(e,n.activeMessage,(e=>n.activeMessage=e),(e=>{if(!e.complete)return;const n=e=>{t.write(e)};if(e.command)return ls(`Received command from client [${t.id}]: ${e.command}`),void(ms&&ms(t.id,e.command,n));e.klMessage&&vs&&vs({send:n,transmission:{sourceServiceId:e.sourceServiceId??-1,targetServiceId:e.targetServiceId??-1,rawMessage:e.rawMessage},json:e.klMessage.json})}))):ls(`Received data from unknown client [${t.id}]. Ignoring.`)})),v.server.on("connect",(e=>{const t=_o();ls(`New client connected. Registered as "${t}"`),e.id=t,fs[t]={socket:e,activeMessage:null,disconnectHandler:()=>hs(t)},e.on("close",fs[t].disconnectHandler),ps&&ps(t)})),v.server.on("disconnect",(e=>{hs(e.id)})),v.server.on("error",(e=>{console.log(`IPC Server Error: ${e}`)})),e()})),v.server.start()}))),Ss=e=>{ps=e},$s=e=>{gs=e},ws=e=>vs=e,bs=(e,t)=>{const n=fs[e];if(!n)return ls(`Cannot send message to unknown client [${e}]`),!1;if(t.length>=ds)return ls("Message is too long to be a command. Use sendMessage instead."),!1;const r=hi.encodeCommand(t);return n.socket.write(r),!0},Ns=(e,t)=>{const n=fs[e];return!!n&&(delete fs[e],n.socket.id=t,fs[t]=n,n.socket.removeListener("close",n.disconnectHandler),n.disconnectHandler=()=>hs(t),n.socket.on("close",n.disconnectHandler),!0)},As=e=>{ms=e};const xs=Wo("websocketServer"),Ps={},Cs=Gi();let Es,js,ks,Ds,Os;var Ts=e=>{Os=new P({port:e,maxPayload:104857600}),Os.on("connection",(e=>{const t=_o();xs(`New client connected. Registered as "${t}"`),e.id=t,Ps[t]={socket:e,activeMessage:null},Es&&Es(t),e.on("message",(t=>{if(t instanceof Buffer){const n=Ps[e.id];Cs(t,n.activeMessage,(e=>n.activeMessage=e),(t=>{if(!t.complete)return;const r=t=>{e.send(t),xs(`Writing ${t.byteLength} bytes to socket [${n.socket.id}]: ${t.toString()}`)};if(t.command)return xs(`Received command from client [${n.socket.id}]: ${t.command}`),void(ks&&ks(n.socket.id,t.command,r));t.klMessage&&Ds&&Ds({send:r,transmission:{sourceServiceId:t.sourceServiceId??-1,targetServiceId:t.targetServiceId??-1,rawMessage:t.rawMessage},json:t.klMessage.json})}))}})),e.on("close",(()=>{xs(`Client disconnected: ${e.id}`),js&&js(e.id),delete Ps[e.id]})),e.on("error",(()=>{xs(`Error on client connection: ${e.id}`)}))})),console.log(`WebSocket server is running on port ${e}`)},Ls=e=>{Es=e},Ms=e=>{js=e},Bs=e=>{ks=e},Rs=(e,t)=>{const n=Ps[e];if(!n)return xs(`Cannot send message to unknown client [${e}]`),!1;if(t.length>=ds)return xs("Message is too long to be a command. Use sendMessage instead."),!1;const r=hi.encodeCommand(t);return n.socket.send(r),!0},Ws=e=>Ds=e;const Us=Wo("stopService"),Fs=async e=>{const t=e.args[0];if(!t)return e.reply({error:"No service name provided"});const n=cs.getAllServiceVersions(t);Us(`Stopping ${n.length} services with name: ${t}`);for(const e of n)await cs.stopService(e.info.name,e.info.version);const r=n.map((e=>`${e.info.name}@${e.info.version}`));e.reply({success:[r]})},_s=Wo("removeService"),Gs=async e=>{const t=e.args[0],n=e.args[1];if(!t)return e.reply({error:"No service name provided"});let r=cs.getAllServiceVersions(t);n&&(r=r.filter((e=>e.info.version===n))),_s(`Removing ${r.length} service(s) with name: ${t}`);for(const e of r)await cs.uninstallService(e.info.name,e.info.version);const a=r.map((e=>`${e.info.name}@${e.info.version}`));e.reply({success:[a]})},zs=Wo("launchService"),Vs=async e=>{const t=e.args[0],n=e.args[1];if(!t)return e.reply({error:"No service name provided"});if(!n)return e.reply({error:"No service version provided"});const r=`${t}@${n}/dist`;try{zs(`Loading service ${t}@${n} from ${Go}`);const{error:a,service:i}=await cs.loadAndLaunch(Go,r,!1);if(a||!i)return e.reply({error:`Failed to launch service ${t}@${n}: ${a||"error-not-provided"}`});if("error"===i.status)return e.reply({error:`Error launching service: "${i.errorMsg||"unknown-error"}"`});const o=Date.now(),s=3e4,c=async()=>{const r=i.status;return"running"===r?(zs(`Service ${t}@${n} loaded and started`),e.reply({success:[]})):(zs(`Service ${t}@${n} not yet started, status: ${r}`),"stopped"===r||"error"===r?e.reply({error:`Error launching service: "${i.errorMsg||"failed to initiate"}"`}):Date.now()-o>s?e.reply({error:"Timeout waiting for service to start"}):(zs("Retrying in 1 second..."),void setTimeout(c,1e3)))};c()}catch(r){return zs(`Error loading service ${t}@${n}: ${r?.message||r}`),e.reply({error:r?.message||"There was an error loading the service"})}},Hs=Wo("getMatchingServices"),Js=async e=>{const t=e.args[0],n=[],r=[];Hs(`Checking for matching services: ${t.map((e=>e.name)).join(", ")}`);for(const{name:e,version:a}of t){const t=cs.getMatchingService(e,a);t?n.push({name:e,version:a,installationPath:cs.getServiceRootDirectory(t)}):r.push({name:e,version:a})}Hs(`Found ${n.length} available services and ${r.length} missing services.`),e.reply({success:[{available:n,missing:r}]})},qs=Wo("getServiceContents"),Ks=({reply:e,args:t})=>{const[n]=t;qs(`Received GetServiceContents request for service ${n.serviceName} v${n.version}`);const r=cs.getMatchingService(n.serviceName,n.version);if(r){return e({success:[{serviceName:r.info.name,serviceVersion:r.info.version,uiContent:r.info.widgetUIContents,uiContentsChecksum:r.info.uiContentChecksum}]})}qs(`Service ${n.serviceName} v${n.version} not found`),e({error:`Service ${n.serviceName} v${n.version} not found`})},Xs=Wo("activeClients");let Ys={},Zs={};const Qs=(e,t)=>`${e}_${t}`,ec=e=>Ys[e]||null,tc=(e,t)=>{const n=Qs(e,t);return Zs[n]||[]},nc=()=>{for(const e in Ys){const t=Ys[e];if(t.transport===ae.WS){const e=hi.encodeCommand(te.ServicesListChanged);t.send(e)}}},rc=(e,t,n,r,a)=>{const i=[];Ys[e]={serviceSessionId:e,transport:t,isDevClient:!!a,broadcastSubscriptions:i,send:n,extraInfo:r,addSubscription:t=>{if(!i.some((e=>e.targetService.serviceName===t.serviceName&&e.targetService.version===t.version))){i.push({targetService:t});const r=Qs(t.serviceName,t.version);Zs[r]=Zs[r]||[];return Zs[r].some((t=>t.serviceId===e))||Zs[r].push({sendFn:n,serviceId:e}),!0}return!1},removeSubscription:t=>{const n=i.findIndex((e=>e.targetService.serviceName===t.serviceName));if(-1!==n){i.splice(n,1);const r=Qs(t.serviceName,t.version),a=Zs[r]?.findIndex((t=>t.serviceId===e));if(-1!==a&&(Zs[r].splice(a,1),!Zs[r].length)){const e=cs.getMatchingService(t.serviceName,t.version);if(e?.info.eventEmitter&&"running"===e.status){const t=ec(e.info.sessionId);t?.extraInfo.ipcSocketId&&bs(t?.extraInfo.ipcSocketId,te.BroadcastEnd)}}}},removeAllSubscriptions:()=>{for(const t of i){const n=Qs(t.targetService.serviceName,t.targetService.version),r=Zs[n].findIndex((t=>t.serviceId===e));-1!==r&&Zs[n].splice(r,1)}i.length=0}},t===ae.IPC&&(nc(),ic(e))},ac=()=>{const e=Object.values(Ys);for(const t of e)if(t.transport===ae.IPC){const e=t.extraInfo.ipcSocketId,n=cs.getServiceBySessionId(t.serviceSessionId);if(n?.info.eventEmitter){tc(n.info.name,n.info.version).length||e&&bs(e,te.BroadcastEnd)}}},ic=e=>{const t=cs.getServiceBySessionId(e);if(t?.info.eventEmitter){if(tc(t.info.name,t.info.version).length){const t=ec(e);t?.extraInfo.ipcSocketId&&bs(t?.extraInfo.ipcSocketId,te.BroadcastStart)}}},oc=e=>{const t=Ys[e];delete Ys[e],t.transport===ae.IPC?nc():(t.removeAllSubscriptions(),ac())},sc=Wo("ipc:handleIpcClientCommand"),cc=(e,t,n)=>{!Ro(t,((t,r)=>{if(!t)return void sc(`Ignoring ACK response from IPC service ${e} with no service id`);sc(`Received ACK from IPC service ${t}. Marking as running.`);const a=cs.setServiceStatus(r||t,"running");r&&t&&e!==r&&Ns(e,r),a?rc(r||t,ae.IPC,n,{ipcSocketId:r}):bs(e,te.SendManifest)}))&&sc(`Received unknown command [${t}] from service ${e}`)},uc=Wo("nativeApi"),dc=e=>new Promise(((t,n)=>{j(e,((e,r,a)=>{const i=a.includes("User cancelled")||a.includes("User canceled");if(a&&!i)return n(a);t(r)}))})),lc={chooseDirectoryDialog:async e=>{const t=`\n var app = Application.currentApplication(); \n app.includeStandardAdditions = true; \n var chosenFolder = app.chooseFolder({ \n withPrompt: "${e.args[0].title||"Please select a directory"}" \n }); \n\n chosenFolder.toString();\n `;uc("Showing chooseDirectoryDialog");const n=await dc(`osascript -l JavaScript -e '${t.trim()}'`);return uc(`Chosen directory: ${n}`),e.reply({success:[String(n).trim()]})},chooseFileDialog:async e=>{const t=e.args[0],n=`\n var app = Application.currentApplication(); \n app.includeStandardAdditions = true; \n var chosenFile = app.chooseFile({ \n withPrompt: "${t.title||"Please select a file"}",\n multipleSelectionsAllowed: ${t.allowMultiple?"true":"false"},\n }); \n\n chosenFile.toString();\n `;uc("Showing chooseFileDialog");const r=await dc(`osascript -l JavaScript -e '${n.trim()}'`);return uc(`Chosen file: ${r}`),e.reply({success:[String(r).trim()]})}},pc={chooseDirectoryDialog:async e=>{e.reply({error:"Not Supported"})},chooseFileDialog:async e=>{e.reply({error:"Not Supported"})}};let gc;gc="win32"===E.platform()?pc:lc;var mc=gc;const vc=Wo("getUniqueId"),fc=({reply:e,sourceServiceId:t})=>{vc(`Generating unique id for service "${t}"`);return e({success:[k()]})},yc=m(C(import.meta.url)),hc=Wo("hub"),Ic=new Ci("hub");Ic.setLogger(hc);const Sc=(e,t)=>{const{transmission:n}=t;if(0!==n.targetServiceId){const r=ec(n.targetServiceId);if(!r)return hc(`Service [${e}] ${n.sourceServiceId} is sending data to an unknown service ["${n.targetServiceId}"]`),!0;r.transport,ae.IPC;const a=t.json?.messageId;return hc(`Forwarding message from ${n.sourceServiceId} to ${n.targetServiceId}, msgId: ${a}`),r.send(n.rawMessage,{sourceServiceId:n.sourceServiceId,targetServiceId:n.targetServiceId,msg:{json:t.json}}),!0}return!1},$c=({sourceServiceId:e,args:t})=>{const n=cs.getServiceBySessionId(e);if(n){const r=tc(n.info.name,n.info.version),a=tc(n.info.name,"*");if(!r.length&&!a.length)return;const i=[...r,...a],o=t[0],s={outputs:o.outputs,variantId:o.variantId,source:{serviceName:n.info.name,serviceVersion:n.info.version,sessionId:e}};Ic.broadcast(ne.BroadcastEvent,[s],i,0)}},wc=e=>{const{send:t,transmission:n,json:r}=e;hc(`Raw message Id received from WS: ${r?.messageId}`);Sc(ae.WS,e)||Ic.processMessage(ae.WS,t,n,r)},bc=e=>{const t=(n=e,`${te.SocketAcknowledge}${n}`);var n;Rs(e,t)},Nc=(e,t,n)=>{!Ro(t,(t=>{if(hc(`Received ACK from WS service ${t}. Marking as running.`),e!==t)throw new Error(`Received ACK from service ${t} but expected ${e}`);rc(t,ae.WS,n,{websocketId:e})}))&&hc(`Received unknown command [${t}] from service ${e}`)},Ac=e=>{hc(`WS Client ${e} disconnected`),oc(e)},xc=async({sourceServiceId:e,args:t,transport:n,send:r})=>{if(n!==ae.IPC){var a;hc(`Received manifest from non IPC service ${e}.`)}else{const n=t[0];if(n.devMode){const t=cs.getMatchingDevService(n.name,n.version,"stopped");if(t){hc(`Found matching previous service ${t.info.name} (${t.info.version}). Reactivating previous client with session id ${t.info.sessionId}`);const i=ec(t.info.sessionId);if(!i)return void hc(`Could not find previous client instance for ${t.info.name} (${t.info.version}). Aborting manifest injection`);i.send=r,Ys[a=e]?delete Ys[a]:Xs(`Could not find source client with session id ${a}`),Ns(e,t.info.sessionId);const o=await Ko(n,n.path);t.info={...t.info,...o},hc(`Updating manifest for dev service ${t.info.sessionId}`),cs.setServiceManifest(t.info.sessionId,o,"running"),hc(`Asking service ${e} to assume previous session id ${t.info.sessionId}`),bs(t.info.sessionId,(e=>`${te.AssumeSession}${e}`)(t.info.sessionId)),(e=>{const t=Ys[e];t?t.isDevClient?(t.disconnected=!1,t.transport===ae.IPC&&(nc(),ic(e))):Xs(`Client with session id ${e} is not a dev client`):Xs(`Could not find source client with session id ${e}`)})(t.info.sessionId)}else{cs.addDevService(e,n,"running");const t=ec(e);t?t.isDevClient=!0:rc(e,ae.IPC,r,{ipcSocketId:e},!0)}return}hc(`Received manifest from non dev service ${e}. Ignoring...`)}};var Pc=async e=>{hc("Starting Kemu Hub...");const t=e?.ipc?.appSpace||"kemu.",n=e?.ipc?.id||"widgets";Ic.registerFunction(ne.GetServiceContents,Ks),Ic.registerFunction(ne.GetServices,(({transport:e,sourceServiceId:t,reply:n})=>{if(hc(`Received GetServices request from ${e} [${t}]`),e===ae.WS){n({success:cs.getActiveServices().map((e=>{const{widgetUIContents:t,...n}=e;return{...n}}))})}})),Ic.registerFunction(ne.UnsubscribeFromService,(({transport:e,reply:t,args:n,sourceServiceId:r})=>{if(e===ae.WS){const[e]=n,a=ec(r);if(!a)return t({error:`Session id "${r}" not found`});hc(`Service ${r} unsubscribing from "${e.targetService.serviceName} (${e.targetService.version})"`),t({success:[]}),a?.removeSubscription({serviceName:e.targetService.serviceName,version:e.targetService.version})}})),Ic.registerFunction(ne.SubscribeToService,(({transport:e,reply:t,args:n,sourceServiceId:r})=>{if(e===ae.WS){const[e]=n,a=ec(r),i=e.targetService;if(!a)return t({error:`Session id "${r}" not found`});if(hc(`Service ${r} subscribing to "${i.serviceName} (${i.version})"`),"hub"===i.serviceName)return a.addSubscription(i),void t({success:[]});if(!a.addSubscription(i))return hc(`Service ${r} already subscribed to "${i.serviceName} (${i.version})", ignoring request.`),t({success:[]});const o=cs.getMatchingService(i.serviceName,i.version);if(!o)return hc(`Service ${i.serviceName} ${i.version} not active yet`),t({success:[]});if(!o.info.eventEmitter)return hc(`Service ${i.serviceName} ${i.version} does not have an event emitter, removing subscription`),a.removeSubscription(i),t({error:`Service "${i.serviceName} (${i.version})" does not produce events`});const s=ec(o.info.sessionId);return s?.extraInfo.ipcSocketId&&(hc(`Sending Broadcast START command to service ${o.info.sessionId}`),bs(s?.extraInfo.ipcSocketId,te.BroadcastStart)),t({success:[]})}})),Ic.registerFunction(ne.BroadcastEvent,$c),Ic.registerFunction(ne.ServiceManifest,xc),Ic.registerFunction("stopService",Fs),Ic.registerFunction("removeService",Gs),Ic.registerFunction("launchService",Vs),Ic.registerFunction("getMatchingServices",Js),Ic.registerFunction(ne.ChooseDirectoryDialog,mc.chooseDirectoryDialog),Ic.registerFunction(ne.ChooseFileDialog,mc.chooseFileDialog),Ic.registerFunction(ne.GetUniqueId,fc),ws((e=>{const{send:t,transmission:n,json:r}=e;hc(`Raw message Id received from IPC: ${r?.messageId}`);Sc(ae.IPC,e)||Ic.processMessage(ae.IPC,t,n,r)})),Ws(wc),Ls(bc),Bs(Nc),Ms(Ac),As(cc),Ss((e=>{const t=(n=e,`${te.IpcAcknowledge}${n}`);var n;bs(e,t)})),$s((e=>{hc(`IPC socket [${e}] disconnected`);const t=ec(e);if(t){hc(`Found matching service for disconnected socket. SessionId: ${t.serviceSessionId}`);const e=cs.getServiceBySessionId(t.serviceSessionId);cs.setServiceStatus(t.serviceSessionId,"stopped"),e?.devMode?(t.disconnected=!0,nc()):oc(t.serviceSessionId)}})),await Is({ipcAppSpace:t,ipcId:n}),e?.ws?.disabled||await Ts(e?.ws?.port||8080);const r=l.resolve(yc,"defaultServices"),a=process.env.DEV_SESSION_ID;cs.setHubIpcConfig({recipePath:e?.recipeRootPath,appSpace:t,id:n}),e?.noDefaultServices||await cs.loadServices(r,{fixedSession:a?parseInt(a):void 0,singleServiceName:process.env.DEV_SINGLE_SERVICE_NAME,internalServices:!0}),await Xo(Go)||await S(Go,{recursive:!0}),null!==e?.servicesInstallPath&&await cs.loadServices(e?.servicesInstallPath||Go,{internalServices:!1,singleServiceName:process.env.DEV_SINGLE_SERVICE_NAME});const i=process.env.DEV_NO_SPAWN_LIST?.split(",");await cs.launchServices({noSpawningList:i||[]}),hc("Kemu Hub started")},Cc=e=>{if(e===ae.WS)return{handleWebsocketConnectionEvent:bc,handleWebsocketClientDisconnectionEvent:Ac,handleWebsocketMessage:wc,handleWebsocketClientCommand:Nc,getRemoteInvoke:()=>Ic}},Ec=(e=[])=>{let t;const n=new Promise((n=>{const r=()=>{if(cs.getAllServices().every((e=>"running"===e.status))){if(e.every((e=>"running"===cs.getMatchingService(e.name,e.version)?.status)))return n()}t=setTimeout(r,100)};r()}));return n.abort=()=>{t&&clearTimeout(t)},n};let jc;const kc=zi("run"),Dc=To(),Oc=1e3,Tc=$(process.argv.slice(2));global.ImageData=L,Nt({createCanvas:(e,t)=>M(e,t)});const Lc={createImageDataLike:(e,t,n,r="srgb")=>{let a;return a=e instanceof Uint8ClampedArray?e:new Uint8ClampedArray(e),{data:a,width:t,height:n,colorSpace:r,_kemuType:Z.ImageData}}};var Mc={start:async n=>{const r=n?.recipePath||Tc.recipePath||process.env.KEMU_EDGE_RECIPE_PATH;if(!r)throw new Error("`recipePath` not provided. Please specify it in the config object, via a command line argument [--recipePath] or as an environment variable [KEMU_EDGE_RECIPE_PATH].");const a=r.endsWith(".json"),i=a?D(r):r,o=a?r:O(i,"recipe.json"),s=(e=>{try{return JSON.parse(e||"")}catch(e){return null}})(await e(T(o),"utf-8"));if(!s)throw new Error("Failed to parse recipe file");await ba();const c={id:s.id||String(Date.now()),version:1,author:""};(e=>{ir=e})(console);const u=Cc(ae.WS),d=(e,t)=>{if(t)u?.handleWebsocketMessage({send:p,transmission:{rawMessage:e,sourceServiceId:t.sourceServiceId,targetServiceId:t.targetServiceId},json:t.msg?.json});else{const t=e instanceof Buffer?e.toString():e;u?.handleWebsocketClientCommand(Oc,t,p)}},l=(Ei={instanceServiceId:Oc,sendBuf:d,sendCmd:d,triggerOnCommand:(...e)=>ji(...e),triggerOnConnected:()=>ki(),triggerOnDisconnected:()=>Di(),triggerOnMessageReceived:(...e)=>Oi(...e)},Ei);const p=(e,t)=>{if(t)l.triggerOnMessageReceived({send:d,transmission:{rawMessage:e,sourceServiceId:t.sourceServiceId,targetServiceId:t.targetServiceId},json:t.msg.json});else{const t=e instanceof Buffer?e.toString():e;l.triggerOnCommand(t)}},g=Mo(),m=u.getRemoteInvoke();g.disableServiceEncoding(0,!0),m.disableServiceEncoding(Oc,!0);const v=Object.values(s.blocks[X].gates).filter((e=>e.type===xe.hubService&&e.state.service)),f=v.map((e=>{const t=e.state.service;return{name:t.name,version:t.version}})),y=O(i,"services"),h=await t(y).then((()=>!0)).catch((()=>!1));await Pc({recipeRootPath:i,servicesInstallPath:h?O(i,"services"):null,noDefaultServices:!0,ws:{disabled:!0},ipc:{appSpace:"kemu-runner.",id:c.id}}),kc("Waiting for services to run"),await Ec(f),kc("All services are running"),ei(Dc);const I=await Ya(s,"runner",c.version,c.author,Sn.Desktop);return jc=I,Lo(I),await Do(),new Promise(((e,t)=>{var n;Oo("acknowledged",(async()=>{await Dc.getServices();const{failed:n,sendToInputWidget:r}=await Qa(I);if(n.length>0){const e=`Some widgets failed to initialize: ${n.join(", ")}`;return t(e)}kc("Recipe started"),e({sendToInputWidget:r})})),l.triggerOnConnected(),l.triggerOnCommand((n=Oc,`${te.SocketAcknowledge}${n}`))}))},terminate:async()=>{jc&&await Za(jc)}};void 0===typeof process.env.BLOCKS_INSTALL_DIR&&console.warn("Missing `BLOCKS_INSTALL_DIR` env var");process.env.BLOCKS_INSTALL_DIR;export{Z as DataType,Mc as default,Lc as utils};