UNPKG

multyx-client

Version:

Framework designed to simplify the creation of multiplayer browser games by addressing the complexities of managing server-client communication, shared state, and input handling

1 lines 26.3 kB
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Multyx=e():t.Multyx=e()}(self,(()=>(()=>{"use strict";var t={376:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.Controller=void 0;const i=s(210);e.Controller=class{constructor(t){this.listening=new Set,this.ws=t,this.preventDefault=!1,this.keys={},this.mouse={x:NaN,y:NaN,down:!1,centerX:0,centerY:0,scaleX:1,scaleY:1},document.addEventListener("keydown",(t=>{this.preventDefault&&t.preventDefault;const e=t.key.toLowerCase();this.keys[e]&&this.listening.has("keyhold")&&this.relayInput("keyhold",{code:e}),this.keys[t.code]&&this.listening.has("keyhold")&&this.relayInput("keyhold",{code:t.code}),this.listening.has(e)&&!this.keys[e]&&this.relayInput("keydown",{code:t.key}),this.listening.has(t.code)&&!this.keys[t.code]&&this.relayInput("keydown",{code:t.code}),this.keys[e]=!0,this.keys[t.code]=!0})),document.addEventListener("keyup",(t=>{this.preventDefault&&t.preventDefault;const e=t.key.toLowerCase();delete this.keys[e],delete this.keys[t.code],this.listening.has(e)&&this.relayInput("keyup",{code:e}),this.listening.has(t.code)&&this.relayInput("keyup",{code:t.code})})),document.addEventListener("mousedown",(t=>{if(this.preventDefault&&t.preventDefault,this.mouseGetter){const t=this.mouseGetter();this.mouse.x=t.x,this.mouse.y=t.y}else this.mouse.x=(t.clientX-this.mouse.centerX)/this.mouse.scaleX,this.mouse.y=(t.clientY-this.mouse.centerY)/this.mouse.scaleY;this.mouse.down=!0,this.listening.has("mousedown")&&this.relayInput("mousedown",{x:this.mouse.x,y:this.mouse.y})})),document.addEventListener("mouseup",(t=>{if(this.preventDefault&&t.preventDefault,this.mouseGetter){const t=this.mouseGetter();this.mouse.x=t.x,this.mouse.y=t.y}else this.mouse.x=(t.clientX-this.mouse.centerX)/this.mouse.scaleX,this.mouse.y=(t.clientY-this.mouse.centerY)/this.mouse.scaleY;this.mouse.down=!1,this.listening.has("mouseup")&&this.relayInput("mouseup",{x:this.mouse.x,y:this.mouse.y})})),document.addEventListener("mousemove",(t=>{if(this.preventDefault&&t.preventDefault,this.mouseGetter){const t=this.mouseGetter();this.mouse.x=t.x,this.mouse.y=t.y}else this.mouse.x=(t.clientX-this.mouse.centerX)/this.mouse.scaleX,this.mouse.y=(t.clientY-this.mouse.centerY)/this.mouse.scaleY;this.listening.has("mousemove")&&this.relayInput("mousemove",{x:this.mouse.x,y:this.mouse.y})}))}mapCanvasPosition(t,e){var s,i,o,n,r,l,h,a,u,c,p,d,f,m,g,y;const b="top"in e,v="bottom"in e,w="left"in e,x="right"in e,M=e.anchor,S=t.getBoundingClientRect(),j=(t,...e)=>{const s=t?"Cannot include value for ":"Must include value for ",i=1==e.length?e[0]:e.slice(0,-1).join(", ")+(t?" and ":" or ")+e.slice(-1)[0],o=M?" if anchoring at "+M:" if not anchoring";console.error(s+i+o)},k=S.width/S.height,E=S.height/S.width;if((Number.isNaN(k)||Number.isNaN(E))&&console.error("Canvas element bounding box is flat, canvas must be present on the screen"),M){if("center"==M){if(b&&v&&e.top!==-e.bottom||w&&x&&e.left!==-e.right)return j(!0,"top","bottom","left","right");b?(e.left=w?e.left:x?-e.right:-Math.abs(k*e.top),e.right=w?-e.left:x?e.right:Math.abs(k*e.top),e.bottom=-e.top):v?(e.left=w?e.left:x?-e.right:-Math.abs(k*e.bottom),e.right=w?-e.left:x?e.right:Math.abs(k*e.bottom),e.top=-e.bottom):w?(e.top=b?e.top:v?-e.bottom:-Math.abs(E*e.left),e.bottom=b?-e.top:v?e.bottom:Math.abs(E*e.left),e.right=-e.left):x&&(e.top=b?e.top:v?-e.bottom:-Math.abs(E*e.right),e.bottom=b?-e.top:v?e.bottom:Math.abs(E*e.right),e.left=-e.right)}else if("bottom"==M){if(!w&&!x&&!b)return j(!1,"left","right","top");if(e.bottom)return j(!0,"bottom");e.bottom=0,w?(null!==(s=e.top)&&void 0!==s||(e.top=Math.abs(E*e.left*2)),null!==(i=e.right)&&void 0!==i||(e.right=-e.left)):x?(null!==(o=e.top)&&void 0!==o||(e.top=Math.abs(E*e.right*2)),null!==(n=e.left)&&void 0!==n||(e.left=-e.right)):(e.left=-Math.abs(k*e.top/2),e.right=-e.left)}else if("top"==M){if(!w&&!x&&!v)return j(!1,"left","right","bottom");if(e.top)return j(!0,"top");e.top=0,w?(null!==(r=e.bottom)&&void 0!==r||(e.bottom=Math.abs(E*e.left*2)),null!==(l=e.right)&&void 0!==l||(e.right=-e.left)):x?(null!==(h=e.bottom)&&void 0!==h||(e.bottom=Math.abs(E*e.right*2)),null!==(a=e.left)&&void 0!==a||(e.left=-e.right)):(e.left=-Math.abs(k*e.bottom/2),e.right=-e.left)}else if("left"==M){if(!b&&!v&&!x)return j(!1,"top","bottom","right");if(w)return j(!0,"left");e.left=0,b?(null!==(u=e.right)&&void 0!==u||(e.right=-Math.abs(k*e.top*2)),null!==(c=e.bottom)&&void 0!==c||(e.bottom=-e.top)):v?(null!==(p=e.right)&&void 0!==p||(e.right=Math.abs(k*e.bottom*2)),null!==(d=e.top)&&void 0!==d||(e.top=-e.bottom)):(e.top=-Math.abs(E*e.right/2),e.bottom=-e.top)}else if("right"==M){if(!b&&!v&&!w)return j(!1,"top","bottom","left");if(x)return j(!0,"right");e.right=0,b?(null!==(f=e.left)&&void 0!==f||(e.left=-Math.abs(k*e.top*2)),null!==(m=e.bottom)&&void 0!==m||(e.bottom=-e.top)):v?(null!==(g=e.left)&&void 0!==g||(e.left=Math.abs(k*e.bottom*2)),null!==(y=e.top)&&void 0!==y||(e.top=-e.bottom)):(e.top=-Math.abs(E*e.right/2),e.bottom=-e.top)}else if("topleft"==M){if(!x&&!v)return j(!1,"right","bottom");if(w||b)return j(!0,"left","top");e.left=e.top=0,x?e.bottom=Math.abs(E*e.right):e.right=Math.abs(k*e.bottom)}else if("topright"==M){if(!w&&!v)return j(!1,"left","bottom");if(x||b)return j(!0,"right","top");e.right=e.top=0,w?e.bottom=Math.abs(E*e.left):e.left=Math.abs(k*e.bottom)}else if("bottomleft"==M){if(!x&&!b)return j(!1,"right","top");if(v||w)return j(!0,"bottom","left");e.left=e.bottom=0,x?e.top=Math.abs(E*e.right):e.right=Math.abs(k*e.top)}else if("bottomright"==M){if(!b&&!w)return j(!1,"top","left");if(x||v)return j(!0,"bottom","right");e.right=e.bottom=0,w?e.top=Math.abs(E*e.left):e.left=Math.abs(k*e.top)}}else{if(!b&&!v)return j(!1,"top","bottom");if(v?b||(e.top=e.bottom-t.height):e.bottom=e.top+t.height,!w&&!x)return j(!1,"left","right");x?w||(e.left=e.right-t.width):e.right=e.left+t.width}const C=t.getContext("2d");C.setTransform(1,0,0,1,0,0),t.width=Math.floor(Math.abs(e.right-e.left)),t.height=Math.floor(Math.abs(e.bottom-e.top)),e.right<e.left&&C.scale(-1,1),e.top>e.bottom&&C.scale(1,-1),C.translate(-e.left,-e.top)}mapMousePosition(t,e,s=document.body,i=1,o=i){const n=window.innerWidth/(s instanceof HTMLCanvasElement?s.width:s.clientWidth),r=window.innerHeight/(s instanceof HTMLCanvasElement?s.height:s.clientHeight),l=s.getBoundingClientRect();this.mouse.centerX=l.left+t*n,this.mouse.centerY=l.top+e*r,this.mouse.scaleX=i*n,this.mouse.scaleY=o*r}mapMouseToCanvas(t){const e=t.getContext("2d").getTransform(),s=t.getBoundingClientRect(),i=s.width/t.width,o=s.height/t.height;this.mouse.centerX=s.left+e.e*i,this.mouse.centerY=s.top+e.f*o,this.mouse.scaleX=i*e.a,this.mouse.scaleY=o*e.d}setMouseAs(t){this.mouseGetter=t}relayInput(t,e){if(1!==this.ws.readyState)throw new Error("Websocket connection is "+(2==this.ws.readyState?"closing":"closed"));this.ws.send(i.Message.Native(Object.assign({instruction:"input",input:t},e?{data:e}:{})))}}},34:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.MultyxClientValue=e.MultyxClientObject=e.MultyxClientList=void 0,e.IsMultyxClientItem=function(t){return t instanceof i.default||t instanceof o.default||t instanceof n.default};const i=s(70);e.MultyxClientList=i.default;const o=s(614);e.MultyxClientObject=o.default;const n=s(501);e.MultyxClientValue=n.default},70:(t,e,s)=>{var i;Object.defineProperty(e,"__esModule",{value:!0});const o=s(34),n=s(787),r=s(735),l=s(210);class h{addEditCallback(t){this.editCallbacks.push(t)}get value(){var t;const e=[];for(let s=0;s<this.length;s++)e[s]=null===(t=this.get(s))||void 0===t?void 0:t.value;return e}get length(){return this.list.length}set length(t){this.list.length=t}handleShiftOperation(t,e){const s=t>=0?e>=0?"right":"left":0==e?"reverse":e<0?"length":"unknown";switch(s){case"reverse":for(let t=0;t<Math.floor(this.length/2);t++){const e=this.list[t];this.list[t]=this.list[this.length-1-t],this.list[this.length-1-t]=e}break;case"left":for(let s=t;s<this.length;s++)s+e<0||(this.list[s+e]=this.list[s]);break;case"right":for(let s=this.length-1;s>=t;s--)this.list[s+e]=this.list[s];break;case"length":this.length+=e;break;default:this.multyx.options.verbose&&console.error("Unknown shift operation: "+s)}}constructor(t,e,s=[],o){this.editCallbacks=[],this.toString=()=>this.value.toString(),this.valueOf=()=>this.value,this[i]=()=>this.value,this.list=[],this.propertyPath=s,this.multyx=t,this.editable=o;const r=e instanceof n.EditWrapper;e instanceof h&&(e=e.value),e instanceof n.EditWrapper&&(e=e.value);for(let t=0;t<e.length;t++)this.set(t,r?new n.EditWrapper(e[t]):e[t]);return new Proxy(this,{has:(t,e)=>"number"==typeof e?t.has(e):e in t,get:(t,e)=>e in t?t[e]:(isNaN(parseInt(e))||(e=parseInt(e)),t.get(e)),set:(t,e,s)=>e in t?(t[e]=s,!0):!!t.set(e,s),deleteProperty:(t,e)=>"number"==typeof e&&t.delete(e)})}has(t){return t>=0&&t<this.length}get(t){if("number"==typeof t)return this.list[t];if(0==t.length)return this;if(1==t.length)return this.list[parseInt(t[0])];const e=this.list[parseInt(t[0])];return!e||e instanceof o.MultyxClientValue?void 0:e.get(t.slice(1))}recursiveSet(t,e){if(0==t.length)return this.multyx.options.verbose&&console.error(`Attempting to edit MultyxClientList with no path. Setting '${this.propertyPath.join(".")}' to ${e}`),!1;if("shift"==t[0]&&e instanceof n.EditWrapper)return this.handleShiftOperation(parseInt(t[1]),e.value),!0;if(1==t.length)return this.set(parseInt(t[0]),e);let s=this.get(parseInt(t[0]));return(s instanceof o.MultyxClientValue||null==s)&&(this.set(parseInt(t[0]),new n.EditWrapper({})),s=this.get(parseInt(t[0]))),s.set(t.slice(1),e)}set(t,e){if(Array.isArray(t))return this.recursiveSet(t,e);const s=this.get(t),i=e instanceof n.EditWrapper,l=i||this.editable;if((i||(0,o.IsMultyxClientItem)(e))&&(e=e.value),void 0===e)return this.delete(t,i);if(this.list[t]instanceof o.MultyxClientValue&&"object"!=typeof e)return this.list[t].set(i?new n.EditWrapper(e):e);if(!l)return this.multyx.options.verbose&&console.error(`Attempting to set property that is not editable. Setting '${this.propertyPath.join(".")+"."+t}' to ${e}`),!1;this.list[t]=new((0,r.default)(e))(this.multyx,i?new n.EditWrapper(e):e,[...this.propertyPath,t.toString()],this.editable);const h=Symbol.for("_"+this.propertyPath.join(".")+"."+t);this.multyx.events.has(h)&&this.multyx[n.Done].push(...this.multyx.events.get(h).map((e=>()=>e(this.list[t]))));for(const e of this.editCallbacks)this.multyx[n.Add]((()=>e(t,this.get(t),s)));return!0}delete(t,e=!1){const s=this.get(t);if("string"==typeof t&&(t=parseInt(t)),!this.editable&&!e)return this.multyx.options.verbose&&console.error(`Attempting to delete property that is not editable. Deleting '${this.propertyPath.join(".")+"."+t}'`),!1;delete this.list[t];for(const e of this.editCallbacks)this.multyx[n.Add]((()=>e(t,void 0,s)));return e||this.multyx.ws.send(l.Message.Native({instruction:"edit",path:[...this.propertyPath,t.toString()],value:void 0})),!0}await(t){if(this.has(t))return Promise.resolve(this.get(t));const e=Symbol.for("_"+this.propertyPath.join(".")+"."+t);return new Promise((t=>this.multyx.on(e,t)))}push(...t){for(const e of t)this.set(this.length,e);return this.length}pop(){if(0===this.length)return null;const t=this.get(this.length);return this.delete(this.length),t}unshift(...t){for(let e=this.length-1;e>=0;e--)e>=t.length?this.set(e,this.get(e-t.length)):this.set(e,t[e]);return this.length}shift(){if(0==this.length)return;this.length--;const t=this.get(0);for(let t=0;t<this.length;t++)this.set(t,this.get(t+1));return t}splice(t,e,...s){void 0===e&&(e=this.length-t);let i=s.length-e;if(i>0)for(let s=this.length-1;s>=t+e;s--)this.set(s+i,this.get(s));else if(i<0){for(let s=t+e;s<this.length;s++)this.set(s+i,this.get(s));const s=this.length;for(let t=s+i;t<s;t++)this.set(t,void 0)}for(let e=t;e<s.length;e++)this.set(e,s[e])}filter(t){const e=[];for(let s=0;s<this.length;s++)e.push(t(this.get(s),s,this));let s=0;for(let t=0;t<e.length;t++)e[t]&&s&&this.set(t-s,this.get(t)),e[t]||s--}map(t){const e=[];for(let s=0;s<this.length;s++)e.push(t(this.get(s),s,this))}flat(){for(let t=0;t<this.length;t++){const e=this.get(t);if(e instanceof h)for(let s=0;s<e.length;s++)t++,this.set(t,e[s])}}reduce(t,e){for(let s=0;s<this.length;s++)e=t(e,this.get(s),s,this);return e}reduceRight(t,e){for(let s=this.length-1;s>=0;s--)e=t(e,this.get(s),s,this);return e}reverse(){let t=this.length-1;for(let e=0;e<t;e++){const s=this.get(e),i=this.get(t);this.set(e,i),this.set(t,s)}return this}forEach(t){for(let e=0;e<this.length;e++)t(this.get(e),e,this)}every(t){for(let e=0;e<this.length;e++)if(!t(this.get(e),e,this))return!1;return!0}some(t){for(let e=0;e<this.length;e++)if(t(this.get(e),e,this))return!0;return!1}find(t){for(let e=0;e<this.length;e++)if(t(this.get(e),e,this))return this.get(e)}findIndex(t){for(let e=0;e<this.length;e++)if(t(this.get(e),e,this))return e;return-1}entries(){const t=[];for(let e=0;e<this.length;e++)t.push([this.get(e),e]);return t}keys(){return Array(this.length).fill(0).map(((t,e)=>e))}[n.Unpack](t){var e;for(let s=0;s<this.length;s++)null===(e=this.get(s))||void 0===e||e[n.Unpack](t[s])}[Symbol.iterator](){const t=[];for(let e=0;e<this.length;e++)t[e]=this.get(e);return t[Symbol.iterator]()}}i=Symbol.toPrimitive,e.default=h},614:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0});const i=s(210),o=s(787),n=s(34),r=s(735),l=s(501);class h{get value(){const t={};for(const e in this.object)t[e]=this.object[e];return t}addEditCallback(t){this.editCallbacks.push(t)}[o.Edit](t,e){1!=t.length?(0==t.length&&this.multyx.options.verbose&&console.error("Update path is empty. Attempting to edit MultyxClientObject with no path."),this.has(t[0])||this.set(t[0],new o.EditWrapper({})),this.get(t[0])[o.Edit](t.slice(1),e)):this.set(t[0],new o.EditWrapper(e))}constructor(t,e,s=[],i){this.editCallbacks=[],this.object={},this.propertyPath=s,this.multyx=t,this.editable=i;const n=e instanceof o.EditWrapper;e instanceof h&&(e=e.value),e instanceof o.EditWrapper&&(e=e.value);for(const t in e)this.set(t,n?new o.EditWrapper(e[t]):e[t]);if(this.constructor===h)return new Proxy(this,{has:(t,e)=>t.has(e),get:(t,e)=>e in t?t[e]:t.get(e),set:(t,e,s)=>e in t?(t[e]=s,!0):t.set(e,s),deleteProperty:(t,e)=>t.delete(e,!1)})}has(t){return t in this.object}get(t){if("string"==typeof t)return this.object[t];if(0==t.length)return this;if(1==t.length)return this.object[t[0]];const e=this.object[t[0]];return!e||e instanceof l.default?void 0:e.get(t.slice(1))}recursiveSet(t,e){if(0==t.length)return this.multyx.options.verbose&&console.error(`Attempting to edit MultyxClientObject with no path. Setting '${this.propertyPath.join(".")}' to ${e}`),!1;if(1==t.length)return this.set(t[0],e);let s=this.get(t[0]);return(s instanceof l.default||null==s)&&(isNaN(parseInt(t[1]))?(this.set(t[0],new o.EditWrapper({})),s=this.get(t[0])):(this.set(t[0],new o.EditWrapper([])),s=this.get(t[0]))),s.set(t.slice(1),e)}set(t,e){if(Array.isArray(t))return this.recursiveSet(t,e);const s=e instanceof o.EditWrapper,i=s||this.editable;if((s||(0,n.IsMultyxClientItem)(e))&&(e=e.value),void 0===e)return this.delete(t,s);if(this.object[t]instanceof l.default&&"object"!=typeof e)return this.object[t].set(s?new o.EditWrapper(e):e);if(!i)return this.multyx.options.verbose&&console.error(`Attempting to set property that is not editable. Setting '${this.propertyPath.join(".")+"."+t}' to ${e}`),!1;this.object[t]=new((0,r.default)(e))(this.multyx,s?new o.EditWrapper(e):e,[...this.propertyPath,t],this.editable);const h=Symbol.for("_"+this.propertyPath.join(".")+"."+t);return this.multyx.events.has(h)&&this.multyx[o.Done].push(...this.multyx.events.get(h).map((e=>()=>e(this.object[t])))),!0}delete(t,e=!1){return this.editable||e?(delete this.object[t],e||this.multyx.ws.send(i.Message.Native({instruction:"edit",path:[...this.propertyPath,t],value:void 0})),!0):(this.multyx.options.verbose&&console.error(`Attempting to delete property that is not editable. Deleting '${this.propertyPath.join(".")+"."+t}'`),!1)}keys(){return Object.keys(this.object)}values(){return Object.values(this.object)}entries(){const t=[];for(let e in this.object)t.push([e,this.get(e)]);return t}await(t){if(this.has(t))return Promise.resolve(this.get(t));const e=Symbol.for("_"+this.propertyPath.join(".")+"."+t);return new Promise((t=>this.multyx.on(e,t)))}[o.Unpack](t){var e;for(const s in t)null===(e=this.object[s])||void 0===e||e[o.Unpack](t[s])}}e.default=h},735:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(t){return Array.isArray(t)?s(70).default:"object"==typeof t?s(614).default:s(501).default}},501:(t,e,s)=>{var i;Object.defineProperty(e,"__esModule",{value:!0});const o=s(210),n=s(787);class r{get value(){return this.readModifiers.reduce(((t,e)=>e(t)),this._value)}set value(t){this._value=t}addReadModifier(t){this.readModifiers.push(t)}addEditCallback(t){this.editCallbacks.push(t)}[n.Edit](t,e){0==t.length&&this.set(new n.EditWrapper(e))}constructor(t,e,s=[],o){this.readModifiers=[],this.editCallbacks=[],this.toString=()=>this.value.toString(),this.valueOf=()=>this.value,this[i]=()=>this.value,this.propertyPath=s,this.editable=o,this.multyx=t,this.constraints={},this.set(e);const r=Symbol.for("_"+this.propertyPath.join("."));this.multyx.events.has(r)&&this.multyx[n.Done].push(...this.multyx.events.get(r).map((t=>()=>t(this.value))))}set(t){if(t instanceof n.EditWrapper){const e=this.value;return this.value=t.value,this.editCallbacks.forEach((s=>s(t.value,e))),!0}if(!this.editable)return this.multyx.options.verbose&&console.error(`Attempting to set property that is not editable. Setting '${this.propertyPath.join(".")}' to ${t}`),!1;let e=t;for(const s in this.constraints)if(e=(0,this.constraints[s])(e),null===e)return this.multyx.options.verbose&&console.error(`Attempting to set property that failed on constraint. Setting '${this.propertyPath.join(".")}' to ${t}, stopped by constraint '${s}'`),!1;return this.value===e?(this.value=e,!0):(this.value=e,this.multyx.ws.send(o.Message.Native({instruction:"edit",path:this.propertyPath,value:e})),!0)}bindElement(t){this.addEditCallback(((e,s)=>{e!==s&&(t.innerText=e.toString())}))}[n.Unpack](t){for(const[e,s]of Object.entries(t)){const t=(0,n.BuildConstraint)(e,s);t&&(this.constraints[e]=t)}}}i=Symbol.toPrimitive,e.default=r},210:(t,e)=>{function s(t){let e,s;if("edit"==t.instruction?(e=0,s=[t.path.join("."),JSON.stringify(t.value)]):"input"==t.instruction?(e=1,s=[t.input,JSON.stringify(t.data)]):"resp"==t.instruction&&(e=2,s=[t.name,JSON.stringify(t.response)]),!s)return"";let i=e;for(let t=0;t<s.length;t++)i+=s[t].replace(/;/g,";_"),t<s.length-1&&(i+=";,");return JSON.stringify([i])}Object.defineProperty(e,"__esModule",{value:!0}),e.Message=void 0,e.UncompressUpdate=function(t){const[e,...s]=t.split(/;,/),i=e[0],o=e.slice(1).replace(/;_/g,";"),n=s.map((t=>t.replace(/;_/g,";"))).map((t=>"undefined"==t?void 0:JSON.parse(t)));return"0"==i?{instruction:"edit",team:!1,path:o.split("."),value:n[0]}:"1"==i?{instruction:"edit",team:!0,path:o.split("."),value:n[0]}:"2"==i?{instruction:"self",property:"controller",data:JSON.parse(o)}:"3"==i?{instruction:"self",property:"uuid",data:JSON.parse(o)}:"4"==i?{instruction:"self",property:"constraint",data:JSON.parse(o)}:"9"==i?{instruction:"self",property:"space",data:JSON.parse(o)}:"5"==i?{instruction:"resp",name:o,response:n[0]}:"6"==i?{instruction:"conn",uuid:o,publicData:n[0]}:"7"==i?{instruction:"dcon",clientUUID:o}:"8"==i?{instruction:"init",client:JSON.parse(o),tps:n[0],constraintTable:n[1],clients:n[2],teams:n[3],space:n[4]}:void 0},e.CompressUpdate=s;class i{constructor(t,e,s=!1){this.name=t,this.data=e,this.time=Date.now(),this.native=s}static BundleOperations(t,e){return Array.isArray(e)||(e=[e]),JSON.stringify(new i("_",{operations:e,deltaTime:t}))}static Native(t){return s(t)}static Parse(t){var e,s;const o=JSON.parse(t);return Array.isArray(o)?new i("_",o,!0):new i(null!==(e=o.name)&&void 0!==e?e:"",null!==(s=o.data)&&void 0!==s?s:"",!1)}static Create(t,e){if(0==t.length)throw new Error("Multyx message cannot have empty name");if("_"==t[0]&&(t="_"+t),"function"==typeof e)throw new Error("Multyx data must be JSON storable");return JSON.stringify(new i(t,e))}}e.Message=i},944:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.DefaultOptions=void 0,e.DefaultOptions={port:8443,secure:!1,uri:"localhost",verbose:!1,logUpdateFrame:!1}},787:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.EditWrapper=e.Edit=e.Add=e.Done=e.Unpack=void 0,e.Interpolate=function(t,e,s){let i={value:t[e],time:Date.now()},o={value:t[e],time:Date.now()};Object.defineProperty(t,e,{get:()=>{const t=o.time-i.time;let e=s[0],n=s[0];for(const i of s)t>i.time&&i.time>e.time&&(e=i),t<i.time&&i.time<n.time&&(n=i);const r=(t-e.time)/(n.time-e.time),l=e.progress+r*(n.progress-e.progress);return Number.isNaN(l)?i.value:o.value*l+i.value*(1-l)},set:t=>Date.now()-o.time<10?(o.value=t,!0):(i=Object.assign({},o),o={value:t,time:Date.now()},!0)})},e.BuildConstraint=function(t,e){return"min"==t?t=>t>=e[0]?t:e[0]:"max"==t?t=>t<=e[0]?t:e[0]:"int"==t?t=>Math.floor(t):"ban"==t?t=>e.includes(t)?null:t:"disabled"==t?t=>e[0]?null:t:t=>t},e.Unpack=Symbol("unpack"),e.Done=Symbol("done"),e.Add=Symbol("add"),e.Edit=Symbol("edit"),e.EditWrapper=class{constructor(t){this.value=t}}}},e={};function s(i){var o=e[i];if(void 0!==o)return o.exports;var n=e[i]={exports:{}};return t[i](n,n.exports,s),n.exports}var i={};return(()=>{var t,e=i;const o=s(210),n=s(787),r=s(376),l=s(34),h=s(944);class a{constructor(e={},s){var i;this[t]=[],this.options=Object.assign(Object.assign({},h.DefaultOptions),e);const n=`ws${this.options.secure?"s":""}://${this.options.uri.split("/")[0]}:${this.options.port}/${null!==(i=this.options.uri.split("/")[1])&&void 0!==i?i:""}`;this.ws=new WebSocket(n),this.ping=0,this.space="default",this.events=new Map,this.self={},this.tps=0,this.all={},this.teams=new l.MultyxClientObject(this,{},[],!0),this.clients={},this.controller=new r.Controller(this.ws),null==s||s(),this.ws.onmessage=t=>{var e,s,i,n;const r=o.Message.Parse(t.data);this.ping=2*(Date.now()-r.time),r.native?(this.parseNativeEvent(r),null===(e=this.events.get(a.Native))||void 0===e||e.forEach((t=>t(r)))):(null===(s=this.events.get(r.name))||void 0===s||s.forEach((t=>{const e=t(r.data);void 0!==e&&this.send(r.name,e)})),null===(i=this.events.get(a.Custom))||void 0===i||i.forEach((t=>t(r)))),null===(n=this.events.get(a.Any))||void 0===n||n.forEach((t=>t(r)))}}on(t,e){var s;const i=null!==(s=this.events.get(t))&&void 0!==s?s:[];i.push(e),this.events.set(t,i)}send(t,e){"_"===t[0]&&(t="_"+t);const s={instruction:"resp",name:t,response:e};this.ws.send(o.Message.Native(s))}await(t,e){return this.send(t,e),new Promise((e=>this.events.set(Symbol.for("_"+t),[e])))}loop(t,e){if(e)this.on(a.Start,(()=>setInterval(t,Math.round(1e3/e))));else{const e=()=>{t(),requestAnimationFrame(e)};this.on(a.Start,(()=>requestAnimationFrame(e)))}}[(t=n.Done,n.Add)](t){this[n.Done].push(t)}parseNativeEvent(t){var e,s,i,r;t.data=t.data.map(o.UncompressUpdate),this.options.logUpdateFrame&&console.log(t.data);for(const o of t.data)switch(o.instruction){case"init":this.initialize(o);for(const t of null!==(e=this.events.get(a.Start))&&void 0!==e?e:[])this[n.Done].push((()=>t(o)));this.events.has(a.Start)&&(this.events.get(a.Start).length=0);break;case"edit":if(1==o.path.length)o.team?this.teams.set(o.path[0],new n.EditWrapper(o.value)):this.clients[o.path[0]]=new l.MultyxClientObject(this,new n.EditWrapper(o.value),[o.path[0]],!1);else{const t=o.team?this.teams.get(o.path[0]):this.clients[o.path[0]];if(!t)return;t.set(o.path.slice(1),new n.EditWrapper(o.value))}for(const t of null!==(s=this.events.get(a.Edit))&&void 0!==s?s:[])this[n.Done].push((()=>t(o)));break;case"self":this.parseSelf(o);break;case"conn":this.clients[o.uuid]=new l.MultyxClientObject(this,o.data,[o.uuid],!1);for(const t of null!==(i=this.events.get(a.Connection))&&void 0!==i?i:[])this[n.Done].push((()=>t(this.clients[o.uuid])));break;case"dcon":for(const t of null!==(r=this.events.get(a.Disconnect))&&void 0!==r?r:[]){const e=this.clients[o.client].value;this[n.Done].push((()=>t(e)))}delete this.clients[o.client];break;case"resp":{const t=this.events.get(Symbol.for("_"+o.name))[0];this.events.delete(Symbol.for("_"+o.name)),this[n.Done].push((()=>t(o.response)));break}default:this.options.verbose&&console.error("Server error: Unknown native Multyx instruction")}this[n.Done].forEach((t=>t())),this[n.Done].length=0}initialize(t){this.tps=t.tps,this.uuid=t.client.uuid,this.joinTime=t.client.joinTime,this.controller.listening=new Set(t.client.controller);for(const e of Object.keys(t.teams))this.teams[e]=new n.EditWrapper(t.teams[e]);this.all=this.teams.all,this.clients={};for(const[e,s]of Object.entries(t.clients))e!=this.uuid&&(this.clients[e]=new l.MultyxClientObject(this,new n.EditWrapper(s),[e],!1));const e=new l.MultyxClientObject(this,new n.EditWrapper(t.client.self),[this.uuid],!0);this.self=e,this.clients[this.uuid]=e;for(const[e,s]of Object.entries(t.constraintTable))(this.uuid==e?this.self:this.teams[e])[n.Unpack](s)}parseSelf(t){if("controller"==t.property)this.controller.listening=new Set(t.data);else if("uuid"==t.property)this.uuid=t.data;else if("constraint"==t.property){let e=this.uuid==t.data.path[0]?this.self:this.teams[t.data.path[0]];for(const s of t.data.path.slice(1))e=null==e?void 0:e[s];if(void 0===e)return;e[n.Unpack]({[t.data.name]:t.data.args})}else"space"==t.property&&(this.space=t.data,this.updateSpace())}updateSpace(){"default"!=this.space?document.querySelectorAll("[data-multyx-space]").forEach((t=>{t.style.display=t.dataset.multyxSpace==this.space?"block":"none",t.style.pointerEvents=t.dataset.multyxSpace==this.space?"auto":"none"})):document.querySelectorAll("[data-multyx-space]").forEach((t=>{t.style.display="block",t.style.pointerEvents="auto"}))}}a.Start=Symbol("start"),a.Connection=Symbol("connection"),a.Disconnect=Symbol("disconnect"),a.Edit=Symbol("edit"),a.Native=Symbol("native"),a.Custom=Symbol("custom"),a.Any=Symbol("any"),e.default=a})(),i.default})()));