@transitive-sdk/utils-web 0.10.2 → 0.11.0
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.
- package/client/hooks.jsx +79 -64
- package/client/react-web-component/index.js +12 -0
- package/client/shared.jsx +84 -20
- package/dist/utils-web.js +1530 -15
- package/dist/utils-web.js.map +7 -0
- package/docs/client.md +60 -19
- package/esbuild.js +4 -6
- package/package.json +1 -1
package/dist/utils-web.js
CHANGED
|
@@ -1,15 +1,1530 @@
|
|
|
1
|
-
var tn=Object.create;var Ne=Object.defineProperty;var rn=Object.getOwnPropertyDescriptor;var sn=Object.getOwnPropertyNames;var nn=Object.getPrototypeOf,on=Object.prototype.hasOwnProperty;var v=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),Dt=(t,e)=>{for(var r in e)Ne(t,r,{get:e[r],enumerable:!0})},Re=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of sn(e))!on.call(t,n)&&n!==r&&Ne(t,n,{get:()=>e[n],enumerable:!(s=rn(e,n))||s.enumerable});return t},A=(t,e,r)=>(Re(t,e,"default"),r&&Re(r,e,"default")),D=(t,e,r)=>(r=t!=null?tn(nn(t)):{},Re(e||!t||!t.__esModule?Ne(r,"default",{value:t,enumerable:!0}):r,t)),an=t=>Re(Ne({},"__esModule",{value:!0}),t);var Je=v((Fi,Ae)=>{(function(){"use strict";var t={}.hasOwnProperty,e="[native code]";function r(){for(var s=[],n=0;n<arguments.length;n++){var o=arguments[n];if(o){var i=typeof o;if(i==="string"||i==="number")s.push(o);else if(Array.isArray(o)){if(o.length){var a=r.apply(null,o);a&&s.push(a)}}else if(i==="object"){if(o.toString!==Object.prototype.toString&&!o.toString.toString().includes("[native code]")){s.push(o.toString());continue}for(var l in o)t.call(o,l)&&o[l]&&s.push(l)}}}return s.join(" ")}typeof Ae<"u"&&Ae.exports?(r.default=r,Ae.exports=r):typeof define=="function"&&typeof define.amd=="object"&&define.amd?define("classnames",[],function(){return r}):window.classNames=r})()});var Jt=v((zi,Wt)=>{Wt.exports=()=>{try{return require("react-web-component-style-loader/exports").styleElements}catch{return[]}}});var Qt=v((Qi,zt)=>{zt.exports=function(e){if(!e.attributes)return{};let r={},s,o=[...e.attributes].map(i=>({[i.name]:i.value}));for(s of o){let i=Object.keys(s)[0],a=i.replace(/-([a-z])/g,l=>l[1].toUpperCase());r[a]=s[i]}return r}});var Yt=v((Ki,Kt)=>{var gn=require("react"),mn=require("react-dom"),bn=require("react-shadow-dom-retarget-events"),yn=Jt(),En=Qt(),vn={attachedCallback:"webComponentAttached",connectedCallback:"webComponentConnected",disconnectedCallback:"webComponentDisconnected",adoptedCallback:"webComponentAdopted"};Kt.exports={create:(t,e,r=!0,s=void 0)=>{let n=class extends HTMLElement{instance=null;callConstructorHook(){this.instance.webComponentConstructed&&this.instance.webComponentConstructed.apply(this.instance,[this])}callLifeCycleHook(o,i=[]){let a=vn[o];a&&this.instance&&this.instance[a]&&this.instance[a].apply(this.instance,i)}connectedCallback(){let o=this,i=o;if(r){let a=o.attachShadow({mode:"open"});i=document.createElement("div"),yn().forEach(c=>{a.appendChild(c.cloneNode(a))}),a.appendChild(i),bn(a)}mn.render(gn.createElement(t,En(o)),i,function(){o.instance=this,o.callConstructorHook(),o.callLifeCycleHook("connectedCallback")})}disconnectedCallback(){this.callLifeCycleHook("disconnectedCallback")}adoptedCallback(o,i){this.callLifeCycleHook("adoptedCallback",[o,i])}call(o,i){return s?.current?.[o]?.call(s?.current,i)}getConfig(){return this.instance.state.config}};return customElements.define(e,n),n}}});var ge=v((Zi,Zt)=>{var xn=typeof process=="object"&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?(...t)=>console.error("SEMVER",...t):()=>{};Zt.exports=xn});var Ze=v((ea,er)=>{var $n="2.0.0",wn=Number.MAX_SAFE_INTEGER||9007199254740991,Tn=16;er.exports={SEMVER_SPEC_VERSION:$n,MAX_LENGTH:256,MAX_SAFE_INTEGER:wn,MAX_SAFE_COMPONENT_LENGTH:Tn}});var Ce=v((W,tr)=>{var{MAX_SAFE_COMPONENT_LENGTH:et}=Ze(),On=ge();W=tr.exports={};var In=W.re=[],d=W.src=[],p=W.t={},Rn=0,b=(t,e,r)=>{let s=Rn++;On(s,e),p[t]=s,d[s]=e,In[s]=new RegExp(e,r?"g":void 0)};b("NUMERICIDENTIFIER","0|[1-9]\\d*");b("NUMERICIDENTIFIERLOOSE","[0-9]+");b("NONNUMERICIDENTIFIER","\\d*[a-zA-Z-][a-zA-Z0-9-]*");b("MAINVERSION",`(${d[p.NUMERICIDENTIFIER]})\\.(${d[p.NUMERICIDENTIFIER]})\\.(${d[p.NUMERICIDENTIFIER]})`);b("MAINVERSIONLOOSE",`(${d[p.NUMERICIDENTIFIERLOOSE]})\\.(${d[p.NUMERICIDENTIFIERLOOSE]})\\.(${d[p.NUMERICIDENTIFIERLOOSE]})`);b("PRERELEASEIDENTIFIER",`(?:${d[p.NUMERICIDENTIFIER]}|${d[p.NONNUMERICIDENTIFIER]})`);b("PRERELEASEIDENTIFIERLOOSE",`(?:${d[p.NUMERICIDENTIFIERLOOSE]}|${d[p.NONNUMERICIDENTIFIER]})`);b("PRERELEASE",`(?:-(${d[p.PRERELEASEIDENTIFIER]}(?:\\.${d[p.PRERELEASEIDENTIFIER]})*))`);b("PRERELEASELOOSE",`(?:-?(${d[p.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${d[p.PRERELEASEIDENTIFIERLOOSE]})*))`);b("BUILDIDENTIFIER","[0-9A-Za-z-]+");b("BUILD",`(?:\\+(${d[p.BUILDIDENTIFIER]}(?:\\.${d[p.BUILDIDENTIFIER]})*))`);b("FULLPLAIN",`v?${d[p.MAINVERSION]}${d[p.PRERELEASE]}?${d[p.BUILD]}?`);b("FULL",`^${d[p.FULLPLAIN]}$`);b("LOOSEPLAIN",`[v=\\s]*${d[p.MAINVERSIONLOOSE]}${d[p.PRERELEASELOOSE]}?${d[p.BUILD]}?`);b("LOOSE",`^${d[p.LOOSEPLAIN]}$`);b("GTLT","((?:<|>)?=?)");b("XRANGEIDENTIFIERLOOSE",`${d[p.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);b("XRANGEIDENTIFIER",`${d[p.NUMERICIDENTIFIER]}|x|X|\\*`);b("XRANGEPLAIN",`[v=\\s]*(${d[p.XRANGEIDENTIFIER]})(?:\\.(${d[p.XRANGEIDENTIFIER]})(?:\\.(${d[p.XRANGEIDENTIFIER]})(?:${d[p.PRERELEASE]})?${d[p.BUILD]}?)?)?`);b("XRANGEPLAINLOOSE",`[v=\\s]*(${d[p.XRANGEIDENTIFIERLOOSE]})(?:\\.(${d[p.XRANGEIDENTIFIERLOOSE]})(?:\\.(${d[p.XRANGEIDENTIFIERLOOSE]})(?:${d[p.PRERELEASELOOSE]})?${d[p.BUILD]}?)?)?`);b("XRANGE",`^${d[p.GTLT]}\\s*${d[p.XRANGEPLAIN]}$`);b("XRANGELOOSE",`^${d[p.GTLT]}\\s*${d[p.XRANGEPLAINLOOSE]}$`);b("COERCE",`(^|[^\\d])(\\d{1,${et}})(?:\\.(\\d{1,${et}}))?(?:\\.(\\d{1,${et}}))?(?:$|[^\\d])`);b("COERCERTL",d[p.COERCE],!0);b("LONETILDE","(?:~>?)");b("TILDETRIM",`(\\s*)${d[p.LONETILDE]}\\s+`,!0);W.tildeTrimReplace="$1~";b("TILDE",`^${d[p.LONETILDE]}${d[p.XRANGEPLAIN]}$`);b("TILDELOOSE",`^${d[p.LONETILDE]}${d[p.XRANGEPLAINLOOSE]}$`);b("LONECARET","(?:\\^)");b("CARETTRIM",`(\\s*)${d[p.LONECARET]}\\s+`,!0);W.caretTrimReplace="$1^";b("CARET",`^${d[p.LONECARET]}${d[p.XRANGEPLAIN]}$`);b("CARETLOOSE",`^${d[p.LONECARET]}${d[p.XRANGEPLAINLOOSE]}$`);b("COMPARATORLOOSE",`^${d[p.GTLT]}\\s*(${d[p.LOOSEPLAIN]})$|^$`);b("COMPARATOR",`^${d[p.GTLT]}\\s*(${d[p.FULLPLAIN]})$|^$`);b("COMPARATORTRIM",`(\\s*)${d[p.GTLT]}\\s*(${d[p.LOOSEPLAIN]}|${d[p.XRANGEPLAIN]})`,!0);W.comparatorTrimReplace="$1$2$3";b("HYPHENRANGE",`^\\s*(${d[p.XRANGEPLAIN]})\\s+-\\s+(${d[p.XRANGEPLAIN]})\\s*$`);b("HYPHENRANGELOOSE",`^\\s*(${d[p.XRANGEPLAINLOOSE]})\\s+-\\s+(${d[p.XRANGEPLAINLOOSE]})\\s*$`);b("STAR","(<|>)?=?\\s*\\*");b("GTE0","^\\s*>=\\s*0.0.0\\s*$");b("GTE0PRE","^\\s*>=\\s*0.0.0-0\\s*$")});var Le=v((ta,rr)=>{var Nn=["includePrerelease","loose","rtl"],An=t=>t?typeof t!="object"?{loose:!0}:Nn.filter(e=>t[e]).reduce((e,r)=>(e[r]=!0,e),{}):{};rr.exports=An});var ir=v((ra,or)=>{var sr=/^[0-9]+$/,nr=(t,e)=>{let r=sr.test(t),s=sr.test(e);return r&&s&&(t=+t,e=+e),t===e?0:r&&!s?-1:s&&!r?1:t<e?-1:1},Sn=(t,e)=>nr(e,t);or.exports={compareIdentifiers:nr,rcompareIdentifiers:Sn}});var be=v((sa,ur)=>{var Pe=ge(),{MAX_LENGTH:ar,MAX_SAFE_INTEGER:qe}=Ze(),{re:lr,t:cr}=Ce(),Cn=Le(),{compareIdentifiers:me}=ir(),tt=class t{constructor(e,r){if(r=Cn(r),e instanceof t){if(e.loose===!!r.loose&&e.includePrerelease===!!r.includePrerelease)return e;e=e.version}else if(typeof e!="string")throw new TypeError(`Invalid Version: ${e}`);if(e.length>ar)throw new TypeError(`version is longer than ${ar} characters`);Pe("SemVer",e,r),this.options=r,this.loose=!!r.loose,this.includePrerelease=!!r.includePrerelease;let s=e.trim().match(r.loose?lr[cr.LOOSE]:lr[cr.FULL]);if(!s)throw new TypeError(`Invalid Version: ${e}`);if(this.raw=e,this.major=+s[1],this.minor=+s[2],this.patch=+s[3],this.major>qe||this.major<0)throw new TypeError("Invalid major version");if(this.minor>qe||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>qe||this.patch<0)throw new TypeError("Invalid patch version");s[4]?this.prerelease=s[4].split(".").map(n=>{if(/^[0-9]+$/.test(n)){let o=+n;if(o>=0&&o<qe)return o}return n}):this.prerelease=[],this.build=s[5]?s[5].split("."):[],this.format()}format(){return this.version=`${this.major}.${this.minor}.${this.patch}`,this.prerelease.length&&(this.version+=`-${this.prerelease.join(".")}`),this.version}toString(){return this.version}compare(e){if(Pe("SemVer.compare",this.version,this.options,e),!(e instanceof t)){if(typeof e=="string"&&e===this.version)return 0;e=new t(e,this.options)}return e.version===this.version?0:this.compareMain(e)||this.comparePre(e)}compareMain(e){return e instanceof t||(e=new t(e,this.options)),me(this.major,e.major)||me(this.minor,e.minor)||me(this.patch,e.patch)}comparePre(e){if(e instanceof t||(e=new t(e,this.options)),this.prerelease.length&&!e.prerelease.length)return-1;if(!this.prerelease.length&&e.prerelease.length)return 1;if(!this.prerelease.length&&!e.prerelease.length)return 0;let r=0;do{let s=this.prerelease[r],n=e.prerelease[r];if(Pe("prerelease compare",r,s,n),s===void 0&&n===void 0)return 0;if(n===void 0)return 1;if(s===void 0)return-1;if(s===n)continue;return me(s,n)}while(++r)}compareBuild(e){e instanceof t||(e=new t(e,this.options));let r=0;do{let s=this.build[r],n=e.build[r];if(Pe("prerelease compare",r,s,n),s===void 0&&n===void 0)return 0;if(n===void 0)return 1;if(s===void 0)return-1;if(s===n)continue;return me(s,n)}while(++r)}inc(e,r){switch(e){case"premajor":this.prerelease.length=0,this.patch=0,this.minor=0,this.major++,this.inc("pre",r);break;case"preminor":this.prerelease.length=0,this.patch=0,this.minor++,this.inc("pre",r);break;case"prepatch":this.prerelease.length=0,this.inc("patch",r),this.inc("pre",r);break;case"prerelease":this.prerelease.length===0&&this.inc("patch",r),this.inc("pre",r);break;case"major":(this.minor!==0||this.patch!==0||this.prerelease.length===0)&&this.major++,this.minor=0,this.patch=0,this.prerelease=[];break;case"minor":(this.patch!==0||this.prerelease.length===0)&&this.minor++,this.patch=0,this.prerelease=[];break;case"patch":this.prerelease.length===0&&this.patch++,this.prerelease=[];break;case"pre":if(this.prerelease.length===0)this.prerelease=[0];else{let s=this.prerelease.length;for(;--s>=0;)typeof this.prerelease[s]=="number"&&(this.prerelease[s]++,s=-2);s===-1&&this.prerelease.push(0)}r&&(this.prerelease[0]===r?isNaN(this.prerelease[1])&&(this.prerelease=[r,0]):this.prerelease=[r,0]);break;default:throw new Error(`invalid increment argument: ${e}`)}return this.format(),this.raw=this.version,this}};ur.exports=tt});var J=v((na,hr)=>{var fr=be(),Ln=(t,e,r)=>new fr(t,r).compare(new fr(e,r));hr.exports=Ln});var pr=v((oa,dr)=>{"use strict";dr.exports=function(t){t.prototype[Symbol.iterator]=function*(){for(let e=this.head;e;e=e.next)yield e.value}}});var mr=v((ia,gr)=>{"use strict";gr.exports=O;O.Node=Z;O.create=O;function O(t){var e=this;if(e instanceof O||(e=new O),e.tail=null,e.head=null,e.length=0,t&&typeof t.forEach=="function")t.forEach(function(n){e.push(n)});else if(arguments.length>0)for(var r=0,s=arguments.length;r<s;r++)e.push(arguments[r]);return e}O.prototype.removeNode=function(t){if(t.list!==this)throw new Error("removing node which does not belong to this list");var e=t.next,r=t.prev;return e&&(e.prev=r),r&&(r.next=e),t===this.head&&(this.head=e),t===this.tail&&(this.tail=r),t.list.length--,t.next=null,t.prev=null,t.list=null,e};O.prototype.unshiftNode=function(t){if(t!==this.head){t.list&&t.list.removeNode(t);var e=this.head;t.list=this,t.next=e,e&&(e.prev=t),this.head=t,this.tail||(this.tail=t),this.length++}};O.prototype.pushNode=function(t){if(t!==this.tail){t.list&&t.list.removeNode(t);var e=this.tail;t.list=this,t.prev=e,e&&(e.next=t),this.tail=t,this.head||(this.head=t),this.length++}};O.prototype.push=function(){for(var t=0,e=arguments.length;t<e;t++)qn(this,arguments[t]);return this.length};O.prototype.unshift=function(){for(var t=0,e=arguments.length;t<e;t++)Dn(this,arguments[t]);return this.length};O.prototype.pop=function(){if(this.tail){var t=this.tail.value;return this.tail=this.tail.prev,this.tail?this.tail.next=null:this.head=null,this.length--,t}};O.prototype.shift=function(){if(this.head){var t=this.head.value;return this.head=this.head.next,this.head?this.head.prev=null:this.tail=null,this.length--,t}};O.prototype.forEach=function(t,e){e=e||this;for(var r=this.head,s=0;r!==null;s++)t.call(e,r.value,s,this),r=r.next};O.prototype.forEachReverse=function(t,e){e=e||this;for(var r=this.tail,s=this.length-1;r!==null;s--)t.call(e,r.value,s,this),r=r.prev};O.prototype.get=function(t){for(var e=0,r=this.head;r!==null&&e<t;e++)r=r.next;if(e===t&&r!==null)return r.value};O.prototype.getReverse=function(t){for(var e=0,r=this.tail;r!==null&&e<t;e++)r=r.prev;if(e===t&&r!==null)return r.value};O.prototype.map=function(t,e){e=e||this;for(var r=new O,s=this.head;s!==null;)r.push(t.call(e,s.value,this)),s=s.next;return r};O.prototype.mapReverse=function(t,e){e=e||this;for(var r=new O,s=this.tail;s!==null;)r.push(t.call(e,s.value,this)),s=s.prev;return r};O.prototype.reduce=function(t,e){var r,s=this.head;if(arguments.length>1)r=e;else if(this.head)s=this.head.next,r=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=0;s!==null;n++)r=t(r,s.value,n),s=s.next;return r};O.prototype.reduceReverse=function(t,e){var r,s=this.tail;if(arguments.length>1)r=e;else if(this.tail)s=this.tail.prev,r=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=this.length-1;s!==null;n--)r=t(r,s.value,n),s=s.prev;return r};O.prototype.toArray=function(){for(var t=new Array(this.length),e=0,r=this.head;r!==null;e++)t[e]=r.value,r=r.next;return t};O.prototype.toArrayReverse=function(){for(var t=new Array(this.length),e=0,r=this.tail;r!==null;e++)t[e]=r.value,r=r.prev;return t};O.prototype.slice=function(t,e){e=e||this.length,e<0&&(e+=this.length),t=t||0,t<0&&(t+=this.length);var r=new O;if(e<t||e<0)return r;t<0&&(t=0),e>this.length&&(e=this.length);for(var s=0,n=this.head;n!==null&&s<t;s++)n=n.next;for(;n!==null&&s<e;s++,n=n.next)r.push(n.value);return r};O.prototype.sliceReverse=function(t,e){e=e||this.length,e<0&&(e+=this.length),t=t||0,t<0&&(t+=this.length);var r=new O;if(e<t||e<0)return r;t<0&&(t=0),e>this.length&&(e=this.length);for(var s=this.length,n=this.tail;n!==null&&s>e;s--)n=n.prev;for(;n!==null&&s>t;s--,n=n.prev)r.push(n.value);return r};O.prototype.splice=function(t,e,...r){t>this.length&&(t=this.length-1),t<0&&(t=this.length+t);for(var s=0,n=this.head;n!==null&&s<t;s++)n=n.next;for(var o=[],s=0;n&&s<e;s++)o.push(n.value),n=this.removeNode(n);n===null&&(n=this.tail),n!==this.head&&n!==this.tail&&(n=n.prev);for(var s=0;s<r.length;s++)n=Pn(this,n,r[s]);return o};O.prototype.reverse=function(){for(var t=this.head,e=this.tail,r=t;r!==null;r=r.prev){var s=r.prev;r.prev=r.next,r.next=s}return this.head=e,this.tail=t,this};function Pn(t,e,r){var s=e===t.head?new Z(r,null,e,t):new Z(r,e,e.next,t);return s.next===null&&(t.tail=s),s.prev===null&&(t.head=s),t.length++,s}function qn(t,e){t.tail=new Z(e,t.tail,null,t),t.head||(t.head=t.tail),t.length++}function Dn(t,e){t.head=new Z(e,null,t.head,t),t.tail||(t.tail=t.head),t.length++}function Z(t,e,r,s){if(!(this instanceof Z))return new Z(t,e,r,s);this.list=s,this.value=t,e?(e.next=this,this.prev=e):this.prev=null,r?(r.prev=this,this.next=r):this.next=null}try{pr()(O)}catch{}});var xr=v((aa,vr)=>{"use strict";var Fn=mr(),ee=Symbol("max"),H=Symbol("length"),ne=Symbol("lengthCalculator"),Ee=Symbol("allowStale"),te=Symbol("maxAge"),U=Symbol("dispose"),br=Symbol("noDisposeOnSet"),S=Symbol("lruList"),G=Symbol("cache"),Er=Symbol("updateAgeOnGet"),rt=()=>1,nt=class{constructor(e){if(typeof e=="number"&&(e={max:e}),e||(e={}),e.max&&(typeof e.max!="number"||e.max<0))throw new TypeError("max must be a non-negative number");let r=this[ee]=e.max||1/0,s=e.length||rt;if(this[ne]=typeof s!="function"?rt:s,this[Ee]=e.stale||!1,e.maxAge&&typeof e.maxAge!="number")throw new TypeError("maxAge must be a number");this[te]=e.maxAge||0,this[U]=e.dispose,this[br]=e.noDisposeOnSet||!1,this[Er]=e.updateAgeOnGet||!1,this.reset()}set max(e){if(typeof e!="number"||e<0)throw new TypeError("max must be a non-negative number");this[ee]=e||1/0,ye(this)}get max(){return this[ee]}set allowStale(e){this[Ee]=!!e}get allowStale(){return this[Ee]}set maxAge(e){if(typeof e!="number")throw new TypeError("maxAge must be a non-negative number");this[te]=e,ye(this)}get maxAge(){return this[te]}set lengthCalculator(e){typeof e!="function"&&(e=rt),e!==this[ne]&&(this[ne]=e,this[H]=0,this[S].forEach(r=>{r.length=this[ne](r.value,r.key),this[H]+=r.length})),ye(this)}get lengthCalculator(){return this[ne]}get length(){return this[H]}get itemCount(){return this[S].length}rforEach(e,r){r=r||this;for(let s=this[S].tail;s!==null;){let n=s.prev;yr(this,e,s,r),s=n}}forEach(e,r){r=r||this;for(let s=this[S].head;s!==null;){let n=s.next;yr(this,e,s,r),s=n}}keys(){return this[S].toArray().map(e=>e.key)}values(){return this[S].toArray().map(e=>e.value)}reset(){this[U]&&this[S]&&this[S].length&&this[S].forEach(e=>this[U](e.key,e.value)),this[G]=new Map,this[S]=new Fn,this[H]=0}dump(){return this[S].map(e=>De(this,e)?!1:{k:e.key,v:e.value,e:e.now+(e.maxAge||0)}).toArray().filter(e=>e)}dumpLru(){return this[S]}set(e,r,s){if(s=s||this[te],s&&typeof s!="number")throw new TypeError("maxAge must be a number");let n=s?Date.now():0,o=this[ne](r,e);if(this[G].has(e)){if(o>this[ee])return oe(this,this[G].get(e)),!1;let l=this[G].get(e).value;return this[U]&&(this[br]||this[U](e,l.value)),l.now=n,l.maxAge=s,l.value=r,this[H]+=o-l.length,l.length=o,this.get(e),ye(this),!0}let i=new ot(e,r,o,n,s);return i.length>this[ee]?(this[U]&&this[U](e,r),!1):(this[H]+=i.length,this[S].unshift(i),this[G].set(e,this[S].head),ye(this),!0)}has(e){if(!this[G].has(e))return!1;let r=this[G].get(e).value;return!De(this,r)}get(e){return st(this,e,!0)}peek(e){return st(this,e,!1)}pop(){let e=this[S].tail;return e?(oe(this,e),e.value):null}del(e){oe(this,this[G].get(e))}load(e){this.reset();let r=Date.now();for(let s=e.length-1;s>=0;s--){let n=e[s],o=n.e||0;if(o===0)this.set(n.k,n.v);else{let i=o-r;i>0&&this.set(n.k,n.v,i)}}}prune(){this[G].forEach((e,r)=>st(this,r,!1))}},st=(t,e,r)=>{let s=t[G].get(e);if(s){let n=s.value;if(De(t,n)){if(oe(t,s),!t[Ee])return}else r&&(t[Er]&&(s.value.now=Date.now()),t[S].unshiftNode(s));return n.value}},De=(t,e)=>{if(!e||!e.maxAge&&!t[te])return!1;let r=Date.now()-e.now;return e.maxAge?r>e.maxAge:t[te]&&r>t[te]},ye=t=>{if(t[H]>t[ee])for(let e=t[S].tail;t[H]>t[ee]&&e!==null;){let r=e.prev;oe(t,e),e=r}},oe=(t,e)=>{if(e){let r=e.value;t[U]&&t[U](r.key,r.value),t[H]-=r.length,t[G].delete(r.key),t[S].removeNode(e)}},ot=class{constructor(e,r,s,n,o){this.key=e,this.value=r,this.length=s,this.now=n,this.maxAge=o||0}},yr=(t,e,r,s)=>{let n=r.value;De(t,n)&&(oe(t,r),t[Ee]||(n=void 0)),n&&e.call(s,n.value,n.key,t)};vr.exports=nt});var wr=v((la,$r)=>{var Bn=J(),Mn=(t,e,r)=>Bn(t,e,r)===0;$r.exports=Mn});var Or=v((ca,Tr)=>{var kn=J(),jn=(t,e,r)=>kn(t,e,r)!==0;Tr.exports=jn});var it=v((ua,Ir)=>{var Gn=J(),_n=(t,e,r)=>Gn(t,e,r)>0;Ir.exports=_n});var Nr=v((fa,Rr)=>{var Un=J(),Hn=(t,e,r)=>Un(t,e,r)>=0;Rr.exports=Hn});var Sr=v((ha,Ar)=>{var Vn=J(),Xn=(t,e,r)=>Vn(t,e,r)<0;Ar.exports=Xn});var Lr=v((da,Cr)=>{var Wn=J(),Jn=(t,e,r)=>Wn(t,e,r)<=0;Cr.exports=Jn});var qr=v((pa,Pr)=>{var zn=wr(),Qn=Or(),Kn=it(),Yn=Nr(),Zn=Sr(),eo=Lr(),to=(t,e,r,s)=>{switch(e){case"===":return typeof t=="object"&&(t=t.version),typeof r=="object"&&(r=r.version),t===r;case"!==":return typeof t=="object"&&(t=t.version),typeof r=="object"&&(r=r.version),t!==r;case"":case"=":case"==":return zn(t,r,s);case"!=":return Qn(t,r,s);case">":return Kn(t,r,s);case">=":return Yn(t,r,s);case"<":return Zn(t,r,s);case"<=":return eo(t,r,s);default:throw new TypeError(`Invalid operator: ${e}`)}};Pr.exports=to});var jr=v((ga,kr)=>{var ve=Symbol("SemVer ANY"),ct=class t{static get ANY(){return ve}constructor(e,r){if(r=ro(r),e instanceof t){if(e.loose===!!r.loose)return e;e=e.value}lt("comparator",e,r),this.options=r,this.loose=!!r.loose,this.parse(e),this.semver===ve?this.value="":this.value=this.operator+this.semver.version,lt("comp",this)}parse(e){let r=this.options.loose?Dr[Fr.COMPARATORLOOSE]:Dr[Fr.COMPARATOR],s=e.match(r);if(!s)throw new TypeError(`Invalid comparator: ${e}`);this.operator=s[1]!==void 0?s[1]:"",this.operator==="="&&(this.operator=""),s[2]?this.semver=new Br(s[2],this.options.loose):this.semver=ve}toString(){return this.value}test(e){if(lt("Comparator.test",e,this.options.loose),this.semver===ve||e===ve)return!0;if(typeof e=="string")try{e=new Br(e,this.options)}catch{return!1}return at(e,this.operator,this.semver,this.options)}intersects(e,r){if(!(e instanceof t))throw new TypeError("a Comparator is required");if((!r||typeof r!="object")&&(r={loose:!!r,includePrerelease:!1}),this.operator==="")return this.value===""?!0:new Mr(e.value,r).test(this.value);if(e.operator==="")return e.value===""?!0:new Mr(this.value,r).test(e.semver);let s=(this.operator===">="||this.operator===">")&&(e.operator===">="||e.operator===">"),n=(this.operator==="<="||this.operator==="<")&&(e.operator==="<="||e.operator==="<"),o=this.semver.version===e.semver.version,i=(this.operator===">="||this.operator==="<=")&&(e.operator===">="||e.operator==="<="),a=at(this.semver,"<",e.semver,r)&&(this.operator===">="||this.operator===">")&&(e.operator==="<="||e.operator==="<"),l=at(this.semver,">",e.semver,r)&&(this.operator==="<="||this.operator==="<")&&(e.operator===">="||e.operator===">");return s||n||o&&i||a||l}};kr.exports=ct;var ro=Le(),{re:Dr,t:Fr}=Ce(),at=qr(),lt=ge(),Br=be(),Mr=ut()});var ut=v((ma,Hr)=>{var ft=class t{constructor(e,r){if(r=no(r),e instanceof t)return e.loose===!!r.loose&&e.includePrerelease===!!r.includePrerelease?e:new t(e.raw,r);if(e instanceof ht)return this.raw=e.value,this.set=[[e]],this.format(),this;if(this.options=r,this.loose=!!r.loose,this.includePrerelease=!!r.includePrerelease,this.raw=e,this.set=e.split(/\s*\|\|\s*/).map(s=>this.parseRange(s.trim())).filter(s=>s.length),!this.set.length)throw new TypeError(`Invalid SemVer Range: ${e}`);if(this.set.length>1){let s=this.set[0];if(this.set=this.set.filter(n=>!_r(n[0])),this.set.length===0)this.set=[s];else if(this.set.length>1){for(let n of this.set)if(n.length===1&&co(n[0])){this.set=[n];break}}}this.format()}format(){return this.range=this.set.map(e=>e.join(" ").trim()).join("||").trim(),this.range}toString(){return this.range}parseRange(e){e=e.trim();let s=`parseRange:${Object.keys(this.options).join(",")}:${e}`,n=Gr.get(s);if(n)return n;let o=this.options.loose,i=o?P[C.HYPHENRANGELOOSE]:P[C.HYPHENRANGE];e=e.replace(i,vo(this.options.includePrerelease)),N("hyphen replace",e),e=e.replace(P[C.COMPARATORTRIM],io),N("comparator trim",e,P[C.COMPARATORTRIM]),e=e.replace(P[C.TILDETRIM],ao),e=e.replace(P[C.CARETTRIM],lo),e=e.split(/\s+/).join(" ");let a=o?P[C.COMPARATORLOOSE]:P[C.COMPARATOR],l=e.split(" ").map(h=>uo(h,this.options)).join(" ").split(/\s+/).map(h=>Eo(h,this.options)).filter(this.options.loose?h=>!!h.match(a):()=>!0).map(h=>new ht(h,this.options)),c=l.length,f=new Map;for(let h of l){if(_r(h))return[h];f.set(h.value,h)}f.size>1&&f.has("")&&f.delete("");let u=[...f.values()];return Gr.set(s,u),u}intersects(e,r){if(!(e instanceof t))throw new TypeError("a Range is required");return this.set.some(s=>Ur(s,r)&&e.set.some(n=>Ur(n,r)&&s.every(o=>n.every(i=>o.intersects(i,r)))))}test(e){if(!e)return!1;if(typeof e=="string")try{e=new oo(e,this.options)}catch{return!1}for(let r=0;r<this.set.length;r++)if(xo(this.set[r],e,this.options))return!0;return!1}};Hr.exports=ft;var so=xr(),Gr=new so({max:1e3}),no=Le(),ht=jr(),N=ge(),oo=be(),{re:P,t:C,comparatorTrimReplace:io,tildeTrimReplace:ao,caretTrimReplace:lo}=Ce(),_r=t=>t.value==="<0.0.0-0",co=t=>t.value==="",Ur=(t,e)=>{let r=!0,s=t.slice(),n=s.pop();for(;r&&s.length;)r=s.every(o=>n.intersects(o,e)),n=s.pop();return r},uo=(t,e)=>(N("comp",t,e),t=po(t,e),N("caret",t),t=fo(t,e),N("tildes",t),t=mo(t,e),N("xrange",t),t=yo(t,e),N("stars",t),t),q=t=>!t||t.toLowerCase()==="x"||t==="*",fo=(t,e)=>t.trim().split(/\s+/).map(r=>ho(r,e)).join(" "),ho=(t,e)=>{let r=e.loose?P[C.TILDELOOSE]:P[C.TILDE];return t.replace(r,(s,n,o,i,a)=>{N("tilde",t,s,n,o,i,a);let l;return q(n)?l="":q(o)?l=`>=${n}.0.0 <${+n+1}.0.0-0`:q(i)?l=`>=${n}.${o}.0 <${n}.${+o+1}.0-0`:a?(N("replaceTilde pr",a),l=`>=${n}.${o}.${i}-${a} <${n}.${+o+1}.0-0`):l=`>=${n}.${o}.${i} <${n}.${+o+1}.0-0`,N("tilde return",l),l})},po=(t,e)=>t.trim().split(/\s+/).map(r=>go(r,e)).join(" "),go=(t,e)=>{N("caret",t,e);let r=e.loose?P[C.CARETLOOSE]:P[C.CARET],s=e.includePrerelease?"-0":"";return t.replace(r,(n,o,i,a,l)=>{N("caret",t,n,o,i,a,l);let c;return q(o)?c="":q(i)?c=`>=${o}.0.0${s} <${+o+1}.0.0-0`:q(a)?o==="0"?c=`>=${o}.${i}.0${s} <${o}.${+i+1}.0-0`:c=`>=${o}.${i}.0${s} <${+o+1}.0.0-0`:l?(N("replaceCaret pr",l),o==="0"?i==="0"?c=`>=${o}.${i}.${a}-${l} <${o}.${i}.${+a+1}-0`:c=`>=${o}.${i}.${a}-${l} <${o}.${+i+1}.0-0`:c=`>=${o}.${i}.${a}-${l} <${+o+1}.0.0-0`):(N("no pr"),o==="0"?i==="0"?c=`>=${o}.${i}.${a}${s} <${o}.${i}.${+a+1}-0`:c=`>=${o}.${i}.${a}${s} <${o}.${+i+1}.0-0`:c=`>=${o}.${i}.${a} <${+o+1}.0.0-0`),N("caret return",c),c})},mo=(t,e)=>(N("replaceXRanges",t,e),t.split(/\s+/).map(r=>bo(r,e)).join(" ")),bo=(t,e)=>{t=t.trim();let r=e.loose?P[C.XRANGELOOSE]:P[C.XRANGE];return t.replace(r,(s,n,o,i,a,l)=>{N("xRange",t,s,n,o,i,a,l);let c=q(o),f=c||q(i),u=f||q(a),h=u;return n==="="&&h&&(n=""),l=e.includePrerelease?"-0":"",c?n===">"||n==="<"?s="<0.0.0-0":s="*":n&&h?(f&&(i=0),a=0,n===">"?(n=">=",f?(o=+o+1,i=0,a=0):(i=+i+1,a=0)):n==="<="&&(n="<",f?o=+o+1:i=+i+1),n==="<"&&(l="-0"),s=`${n+o}.${i}.${a}${l}`):f?s=`>=${o}.0.0${l} <${+o+1}.0.0-0`:u&&(s=`>=${o}.${i}.0${l} <${o}.${+i+1}.0-0`),N("xRange return",s),s})},yo=(t,e)=>(N("replaceStars",t,e),t.trim().replace(P[C.STAR],"")),Eo=(t,e)=>(N("replaceGTE0",t,e),t.trim().replace(P[e.includePrerelease?C.GTE0PRE:C.GTE0],"")),vo=t=>(e,r,s,n,o,i,a,l,c,f,u,h,x)=>(q(s)?r="":q(n)?r=`>=${s}.0.0${t?"-0":""}`:q(o)?r=`>=${s}.${n}.0${t?"-0":""}`:i?r=`>=${r}`:r=`>=${r}${t?"-0":""}`,q(c)?l="":q(f)?l=`<${+c+1}.0.0-0`:q(u)?l=`<${c}.${+f+1}.0-0`:h?l=`<=${c}.${f}.${u}-${h}`:t?l=`<${c}.${f}.${+u+1}-0`:l=`<=${l}`,`${r} ${l}`.trim()),xo=(t,e,r)=>{for(let s=0;s<t.length;s++)if(!t[s].test(e))return!1;if(e.prerelease.length&&!r.includePrerelease){for(let s=0;s<t.length;s++)if(N(t[s].semver),t[s].semver!==ht.ANY&&t[s].semver.prerelease.length>0){let n=t[s].semver;if(n.major===e.major&&n.minor===e.minor&&n.patch===e.patch)return!0}return!1}return!0}});var Wr=v((ba,Xr)=>{var dt=be(),$o=ut(),Vr=it(),wo=(t,e)=>{t=new $o(t,e);let r=new dt("0.0.0");if(t.test(r)||(r=new dt("0.0.0-0"),t.test(r)))return r;r=null;for(let s=0;s<t.set.length;++s){let n=t.set[s],o=null;n.forEach(i=>{let a=new dt(i.semver.version);switch(i.operator){case">":a.prerelease.length===0?a.patch++:a.prerelease.push(0),a.raw=a.format();case"":case">=":(!o||Vr(a,o))&&(o=a);break;case"<":case"<=":break;default:throw new Error(`Unexpected operation: ${i.operator}`)}}),o&&(!r||Vr(r,o))&&(r=o)}return r&&t.test(r)?r:null};Xr.exports=wo});var zr=v((Jr,Fe)=>{(function(t,e){"use strict";typeof define=="function"&&define.amd?define(e):typeof Fe=="object"&&Fe.exports?Fe.exports=e():t.log=e()})(Jr,function(){"use strict";var t=function(){},e="undefined",r=typeof window!==e&&typeof window.navigator!==e&&/Trident\/|MSIE /.test(window.navigator.userAgent),s=["trace","debug","info","warn","error"];function n(m,w){var I=m[w];if(typeof I.bind=="function")return I.bind(m);try{return Function.prototype.bind.call(I,m)}catch{return function(){return Function.prototype.apply.apply(I,[m,arguments])}}}function o(){console.log&&(console.log.apply?console.log.apply(console,arguments):Function.prototype.apply.apply(console.log,[console,arguments])),console.trace&&console.trace()}function i(m){return m==="debug"&&(m="log"),typeof console===e?!1:m==="trace"&&r?o:console[m]!==void 0?n(console,m):console.log!==void 0?n(console,"log"):t}function a(m,w){for(var I=0;I<s.length;I++){var T=s[I];this[T]=I<m?t:this.methodFactory(T,m,w)}this.log=this.debug}function l(m,w,I){return function(){typeof console!==e&&(a.call(this,w,I),this[m].apply(this,arguments))}}function c(m,w,I){return i(m)||l.apply(this,arguments)}function f(m,w,I){var T=this,V;w=w??"WARN";var L="loglevel";typeof m=="string"?L+=":"+m:typeof m=="symbol"&&(L=void 0);function X(E){var M=(s[E]||"silent").toUpperCase();if(!(typeof window===e||!L)){try{window.localStorage[L]=M;return}catch{}try{window.document.cookie=encodeURIComponent(L)+"="+M+";"}catch{}}}function _(){var E;if(!(typeof window===e||!L)){try{E=window.localStorage[L]}catch{}if(typeof E===e)try{var M=window.document.cookie,Y=M.indexOf(encodeURIComponent(L)+"=");Y!==-1&&(E=/^([^;]+)/.exec(M.slice(Y))[1])}catch{}return T.levels[E]===void 0&&(E=void 0),E}}function K(){if(!(typeof window===e||!L)){try{window.localStorage.removeItem(L);return}catch{}try{window.document.cookie=encodeURIComponent(L)+"=; expires=Thu, 01 Jan 1970 00:00:00 UTC"}catch{}}}T.name=m,T.levels={TRACE:0,DEBUG:1,INFO:2,WARN:3,ERROR:4,SILENT:5},T.methodFactory=I||c,T.getLevel=function(){return V},T.setLevel=function(E,M){if(typeof E=="string"&&T.levels[E.toUpperCase()]!==void 0&&(E=T.levels[E.toUpperCase()]),typeof E=="number"&&E>=0&&E<=T.levels.SILENT){if(V=E,M!==!1&&X(E),a.call(T,E,m),typeof console===e&&E<T.levels.SILENT)return"No console available for logging"}else throw"log.setLevel() called with invalid level: "+E},T.setDefaultLevel=function(E){w=E,_()||T.setLevel(E,!1)},T.resetLevel=function(){T.setLevel(w,!1),K()},T.enableAll=function(E){T.setLevel(T.levels.TRACE,E)},T.disableAll=function(E){T.setLevel(T.levels.SILENT,E)};var j=_();j==null&&(j=w),T.setLevel(j,!1)}var u=new f,h={};u.getLogger=function(w){if(typeof w!="symbol"&&typeof w!="string"||w==="")throw new TypeError("You must supply a name when creating a logger.");var I=h[w];return I||(I=h[w]=new f(w,u.getLevel(),u.methodFactory)),I};var x=typeof window!==e?window.log:void 0;return u.noConflict=function(){return typeof window!==e&&window.log===u&&(window.log=x),u},u.getLoggers=function(){return h},u.default=u,u})});var Kr=v((ya,Qr)=>{"use strict";Qr.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}});var pt=v((Ea,Zr)=>{var xe=Kr(),Yr={};for(let t of Object.keys(xe))Yr[xe[t]]=t;var g={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};Zr.exports=g;for(let t of Object.keys(g)){if(!("channels"in g[t]))throw new Error("missing channels property: "+t);if(!("labels"in g[t]))throw new Error("missing channel labels property: "+t);if(g[t].labels.length!==g[t].channels)throw new Error("channel and label counts mismatch: "+t);let{channels:e,labels:r}=g[t];delete g[t].channels,delete g[t].labels,Object.defineProperty(g[t],"channels",{value:e}),Object.defineProperty(g[t],"labels",{value:r})}g.rgb.hsl=function(t){let e=t[0]/255,r=t[1]/255,s=t[2]/255,n=Math.min(e,r,s),o=Math.max(e,r,s),i=o-n,a,l;o===n?a=0:e===o?a=(r-s)/i:r===o?a=2+(s-e)/i:s===o&&(a=4+(e-r)/i),a=Math.min(a*60,360),a<0&&(a+=360);let c=(n+o)/2;return o===n?l=0:c<=.5?l=i/(o+n):l=i/(2-o-n),[a,l*100,c*100]};g.rgb.hsv=function(t){let e,r,s,n,o,i=t[0]/255,a=t[1]/255,l=t[2]/255,c=Math.max(i,a,l),f=c-Math.min(i,a,l),u=function(h){return(c-h)/6/f+1/2};return f===0?(n=0,o=0):(o=f/c,e=u(i),r=u(a),s=u(l),i===c?n=s-r:a===c?n=1/3+e-s:l===c&&(n=2/3+r-e),n<0?n+=1:n>1&&(n-=1)),[n*360,o*100,c*100]};g.rgb.hwb=function(t){let e=t[0],r=t[1],s=t[2],n=g.rgb.hsl(t)[0],o=1/255*Math.min(e,Math.min(r,s));return s=1-1/255*Math.max(e,Math.max(r,s)),[n,o*100,s*100]};g.rgb.cmyk=function(t){let e=t[0]/255,r=t[1]/255,s=t[2]/255,n=Math.min(1-e,1-r,1-s),o=(1-e-n)/(1-n)||0,i=(1-r-n)/(1-n)||0,a=(1-s-n)/(1-n)||0;return[o*100,i*100,a*100,n*100]};function To(t,e){return(t[0]-e[0])**2+(t[1]-e[1])**2+(t[2]-e[2])**2}g.rgb.keyword=function(t){let e=Yr[t];if(e)return e;let r=1/0,s;for(let n of Object.keys(xe)){let o=xe[n],i=To(t,o);i<r&&(r=i,s=n)}return s};g.keyword.rgb=function(t){return xe[t]};g.rgb.xyz=function(t){let e=t[0]/255,r=t[1]/255,s=t[2]/255;e=e>.04045?((e+.055)/1.055)**2.4:e/12.92,r=r>.04045?((r+.055)/1.055)**2.4:r/12.92,s=s>.04045?((s+.055)/1.055)**2.4:s/12.92;let n=e*.4124+r*.3576+s*.1805,o=e*.2126+r*.7152+s*.0722,i=e*.0193+r*.1192+s*.9505;return[n*100,o*100,i*100]};g.rgb.lab=function(t){let e=g.rgb.xyz(t),r=e[0],s=e[1],n=e[2];r/=95.047,s/=100,n/=108.883,r=r>.008856?r**(1/3):7.787*r+16/116,s=s>.008856?s**(1/3):7.787*s+16/116,n=n>.008856?n**(1/3):7.787*n+16/116;let o=116*s-16,i=500*(r-s),a=200*(s-n);return[o,i,a]};g.hsl.rgb=function(t){let e=t[0]/360,r=t[1]/100,s=t[2]/100,n,o,i;if(r===0)return i=s*255,[i,i,i];s<.5?n=s*(1+r):n=s+r-s*r;let a=2*s-n,l=[0,0,0];for(let c=0;c<3;c++)o=e+1/3*-(c-1),o<0&&o++,o>1&&o--,6*o<1?i=a+(n-a)*6*o:2*o<1?i=n:3*o<2?i=a+(n-a)*(2/3-o)*6:i=a,l[c]=i*255;return l};g.hsl.hsv=function(t){let e=t[0],r=t[1]/100,s=t[2]/100,n=r,o=Math.max(s,.01);s*=2,r*=s<=1?s:2-s,n*=o<=1?o:2-o;let i=(s+r)/2,a=s===0?2*n/(o+n):2*r/(s+r);return[e,a*100,i*100]};g.hsv.rgb=function(t){let e=t[0]/60,r=t[1]/100,s=t[2]/100,n=Math.floor(e)%6,o=e-Math.floor(e),i=255*s*(1-r),a=255*s*(1-r*o),l=255*s*(1-r*(1-o));switch(s*=255,n){case 0:return[s,l,i];case 1:return[a,s,i];case 2:return[i,s,l];case 3:return[i,a,s];case 4:return[l,i,s];case 5:return[s,i,a]}};g.hsv.hsl=function(t){let e=t[0],r=t[1]/100,s=t[2]/100,n=Math.max(s,.01),o,i;i=(2-r)*s;let a=(2-r)*n;return o=r*n,o/=a<=1?a:2-a,o=o||0,i/=2,[e,o*100,i*100]};g.hwb.rgb=function(t){let e=t[0]/360,r=t[1]/100,s=t[2]/100,n=r+s,o;n>1&&(r/=n,s/=n);let i=Math.floor(6*e),a=1-s;o=6*e-i,i&1&&(o=1-o);let l=r+o*(a-r),c,f,u;switch(i){default:case 6:case 0:c=a,f=l,u=r;break;case 1:c=l,f=a,u=r;break;case 2:c=r,f=a,u=l;break;case 3:c=r,f=l,u=a;break;case 4:c=l,f=r,u=a;break;case 5:c=a,f=r,u=l;break}return[c*255,f*255,u*255]};g.cmyk.rgb=function(t){let e=t[0]/100,r=t[1]/100,s=t[2]/100,n=t[3]/100,o=1-Math.min(1,e*(1-n)+n),i=1-Math.min(1,r*(1-n)+n),a=1-Math.min(1,s*(1-n)+n);return[o*255,i*255,a*255]};g.xyz.rgb=function(t){let e=t[0]/100,r=t[1]/100,s=t[2]/100,n,o,i;return n=e*3.2406+r*-1.5372+s*-.4986,o=e*-.9689+r*1.8758+s*.0415,i=e*.0557+r*-.204+s*1.057,n=n>.0031308?1.055*n**(1/2.4)-.055:n*12.92,o=o>.0031308?1.055*o**(1/2.4)-.055:o*12.92,i=i>.0031308?1.055*i**(1/2.4)-.055:i*12.92,n=Math.min(Math.max(0,n),1),o=Math.min(Math.max(0,o),1),i=Math.min(Math.max(0,i),1),[n*255,o*255,i*255]};g.xyz.lab=function(t){let e=t[0],r=t[1],s=t[2];e/=95.047,r/=100,s/=108.883,e=e>.008856?e**(1/3):7.787*e+16/116,r=r>.008856?r**(1/3):7.787*r+16/116,s=s>.008856?s**(1/3):7.787*s+16/116;let n=116*r-16,o=500*(e-r),i=200*(r-s);return[n,o,i]};g.lab.xyz=function(t){let e=t[0],r=t[1],s=t[2],n,o,i;o=(e+16)/116,n=r/500+o,i=o-s/200;let a=o**3,l=n**3,c=i**3;return o=a>.008856?a:(o-16/116)/7.787,n=l>.008856?l:(n-16/116)/7.787,i=c>.008856?c:(i-16/116)/7.787,n*=95.047,o*=100,i*=108.883,[n,o,i]};g.lab.lch=function(t){let e=t[0],r=t[1],s=t[2],n;n=Math.atan2(s,r)*360/2/Math.PI,n<0&&(n+=360);let i=Math.sqrt(r*r+s*s);return[e,i,n]};g.lch.lab=function(t){let e=t[0],r=t[1],n=t[2]/360*2*Math.PI,o=r*Math.cos(n),i=r*Math.sin(n);return[e,o,i]};g.rgb.ansi16=function(t,e=null){let[r,s,n]=t,o=e===null?g.rgb.hsv(t)[2]:e;if(o=Math.round(o/50),o===0)return 30;let i=30+(Math.round(n/255)<<2|Math.round(s/255)<<1|Math.round(r/255));return o===2&&(i+=60),i};g.hsv.ansi16=function(t){return g.rgb.ansi16(g.hsv.rgb(t),t[2])};g.rgb.ansi256=function(t){let e=t[0],r=t[1],s=t[2];return e===r&&r===s?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(r/255*5)+Math.round(s/255*5)};g.ansi16.rgb=function(t){let e=t%10;if(e===0||e===7)return t>50&&(e+=3.5),e=e/10.5*255,[e,e,e];let r=(~~(t>50)+1)*.5,s=(e&1)*r*255,n=(e>>1&1)*r*255,o=(e>>2&1)*r*255;return[s,n,o]};g.ansi256.rgb=function(t){if(t>=232){let o=(t-232)*10+8;return[o,o,o]}t-=16;let e,r=Math.floor(t/36)/5*255,s=Math.floor((e=t%36)/6)/5*255,n=e%6/5*255;return[r,s,n]};g.rgb.hex=function(t){let r=(((Math.round(t[0])&255)<<16)+((Math.round(t[1])&255)<<8)+(Math.round(t[2])&255)).toString(16).toUpperCase();return"000000".substring(r.length)+r};g.hex.rgb=function(t){let e=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];let r=e[0];e[0].length===3&&(r=r.split("").map(a=>a+a).join(""));let s=parseInt(r,16),n=s>>16&255,o=s>>8&255,i=s&255;return[n,o,i]};g.rgb.hcg=function(t){let e=t[0]/255,r=t[1]/255,s=t[2]/255,n=Math.max(Math.max(e,r),s),o=Math.min(Math.min(e,r),s),i=n-o,a,l;return i<1?a=o/(1-i):a=0,i<=0?l=0:n===e?l=(r-s)/i%6:n===r?l=2+(s-e)/i:l=4+(e-r)/i,l/=6,l%=1,[l*360,i*100,a*100]};g.hsl.hcg=function(t){let e=t[1]/100,r=t[2]/100,s=r<.5?2*e*r:2*e*(1-r),n=0;return s<1&&(n=(r-.5*s)/(1-s)),[t[0],s*100,n*100]};g.hsv.hcg=function(t){let e=t[1]/100,r=t[2]/100,s=e*r,n=0;return s<1&&(n=(r-s)/(1-s)),[t[0],s*100,n*100]};g.hcg.rgb=function(t){let e=t[0]/360,r=t[1]/100,s=t[2]/100;if(r===0)return[s*255,s*255,s*255];let n=[0,0,0],o=e%1*6,i=o%1,a=1-i,l=0;switch(Math.floor(o)){case 0:n[0]=1,n[1]=i,n[2]=0;break;case 1:n[0]=a,n[1]=1,n[2]=0;break;case 2:n[0]=0,n[1]=1,n[2]=i;break;case 3:n[0]=0,n[1]=a,n[2]=1;break;case 4:n[0]=i,n[1]=0,n[2]=1;break;default:n[0]=1,n[1]=0,n[2]=a}return l=(1-r)*s,[(r*n[0]+l)*255,(r*n[1]+l)*255,(r*n[2]+l)*255]};g.hcg.hsv=function(t){let e=t[1]/100,r=t[2]/100,s=e+r*(1-e),n=0;return s>0&&(n=e/s),[t[0],n*100,s*100]};g.hcg.hsl=function(t){let e=t[1]/100,s=t[2]/100*(1-e)+.5*e,n=0;return s>0&&s<.5?n=e/(2*s):s>=.5&&s<1&&(n=e/(2*(1-s))),[t[0],n*100,s*100]};g.hcg.hwb=function(t){let e=t[1]/100,r=t[2]/100,s=e+r*(1-e);return[t[0],(s-e)*100,(1-s)*100]};g.hwb.hcg=function(t){let e=t[1]/100,s=1-t[2]/100,n=s-e,o=0;return n<1&&(o=(s-n)/(1-n)),[t[0],n*100,o*100]};g.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]};g.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]};g.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]};g.gray.hsl=function(t){return[0,0,t[0]]};g.gray.hsv=g.gray.hsl;g.gray.hwb=function(t){return[0,100,t[0]]};g.gray.cmyk=function(t){return[0,0,0,t[0]]};g.gray.lab=function(t){return[t[0],0,0]};g.gray.hex=function(t){let e=Math.round(t[0]/100*255)&255,s=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(s.length)+s};g.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]}});var ts=v((va,es)=>{var Be=pt();function Oo(){let t={},e=Object.keys(Be);for(let r=e.length,s=0;s<r;s++)t[e[s]]={distance:-1,parent:null};return t}function Io(t){let e=Oo(),r=[t];for(e[t].distance=0;r.length;){let s=r.pop(),n=Object.keys(Be[s]);for(let o=n.length,i=0;i<o;i++){let a=n[i],l=e[a];l.distance===-1&&(l.distance=e[s].distance+1,l.parent=s,r.unshift(a))}}return e}function Ro(t,e){return function(r){return e(t(r))}}function No(t,e){let r=[e[t].parent,t],s=Be[e[t].parent][t],n=e[t].parent;for(;e[n].parent;)r.unshift(e[n].parent),s=Ro(Be[e[n].parent][n],s),n=e[n].parent;return s.conversion=r,s}es.exports=function(t){let e=Io(t),r={},s=Object.keys(e);for(let n=s.length,o=0;o<n;o++){let i=s[o];e[i].parent!==null&&(r[i]=No(i,e))}return r}});var ss=v((xa,rs)=>{var gt=pt(),Ao=ts(),ie={},So=Object.keys(gt);function Co(t){let e=function(...r){let s=r[0];return s==null?s:(s.length>1&&(r=s),t(r))};return"conversion"in t&&(e.conversion=t.conversion),e}function Lo(t){let e=function(...r){let s=r[0];if(s==null)return s;s.length>1&&(r=s);let n=t(r);if(typeof n=="object")for(let o=n.length,i=0;i<o;i++)n[i]=Math.round(n[i]);return n};return"conversion"in t&&(e.conversion=t.conversion),e}So.forEach(t=>{ie[t]={},Object.defineProperty(ie[t],"channels",{value:gt[t].channels}),Object.defineProperty(ie[t],"labels",{value:gt[t].labels});let e=Ao(t);Object.keys(e).forEach(s=>{let n=e[s];ie[t][s]=Lo(n),ie[t][s].raw=Co(n)})});rs.exports=ie});var cs=v(($a,ls)=>{"use strict";var ns=(t,e)=>(...r)=>`\x1B[${t(...r)+e}m`,os=(t,e)=>(...r)=>{let s=t(...r);return`\x1B[${38+e};5;${s}m`},is=(t,e)=>(...r)=>{let s=t(...r);return`\x1B[${38+e};2;${s[0]};${s[1]};${s[2]}m`},Me=t=>t,as=(t,e,r)=>[t,e,r],ae=(t,e,r)=>{Object.defineProperty(t,e,{get:()=>{let s=r();return Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0}),s},enumerable:!0,configurable:!0})},mt,le=(t,e,r,s)=>{mt===void 0&&(mt=ss());let n=s?10:0,o={};for(let[i,a]of Object.entries(mt)){let l=i==="ansi16"?"ansi":i;i===e?o[l]=t(r,n):typeof a=="object"&&(o[l]=t(a[e],n))}return o};function Po(){let t=new Map,e={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};e.color.gray=e.color.blackBright,e.bgColor.bgGray=e.bgColor.bgBlackBright,e.color.grey=e.color.blackBright,e.bgColor.bgGrey=e.bgColor.bgBlackBright;for(let[r,s]of Object.entries(e)){for(let[n,o]of Object.entries(s))e[n]={open:`\x1B[${o[0]}m`,close:`\x1B[${o[1]}m`},s[n]=e[n],t.set(o[0],o[1]);Object.defineProperty(e,r,{value:s,enumerable:!1})}return Object.defineProperty(e,"codes",{value:t,enumerable:!1}),e.color.close="\x1B[39m",e.bgColor.close="\x1B[49m",ae(e.color,"ansi",()=>le(ns,"ansi16",Me,!1)),ae(e.color,"ansi256",()=>le(os,"ansi256",Me,!1)),ae(e.color,"ansi16m",()=>le(is,"rgb",as,!1)),ae(e.bgColor,"ansi",()=>le(ns,"ansi16",Me,!0)),ae(e.bgColor,"ansi256",()=>le(os,"ansi256",Me,!0)),ae(e.bgColor,"ansi16m",()=>le(is,"rgb",as,!0)),e}Object.defineProperty(ls,"exports",{enumerable:!0,get:Po})});var fs=v((wa,us)=>{"use strict";us.exports={stdout:!1,stderr:!1}});var ds=v((Ta,hs)=>{"use strict";var qo=(t,e,r)=>{let s=t.indexOf(e);if(s===-1)return t;let n=e.length,o=0,i="";do i+=t.substr(o,s-o)+e+r,o=s+n,s=t.indexOf(e,o);while(s!==-1);return i+=t.substr(o),i},Do=(t,e,r,s)=>{let n=0,o="";do{let i=t[s-1]==="\r";o+=t.substr(n,(i?s-1:s)-n)+e+(i?`\r
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
`);return o!==-1&&(e=Uo(e,n,s,o)),s+e+n},bt,ws=(t,...e)=>{let[r]=e;if(!ke(r)||!ke(r.raw))return e.join(" ");let s=e.slice(1),n=[r.raw[0]];for(let o=1;o<r.length;o++)n.push(String(s[o-1]).replace(/[{}\\]/g,"\\$&"),String(r.raw[o]));return bt===void 0&&(bt=ys()),bt(t,n.join(""))};Object.defineProperties(je.prototype,ce);var _e=je();_e.supportsColor=yt;_e.stderr=je({level:Et?Et.level:0});_e.stderr.supportsColor=Et;Ts.exports=_e});var Rs=v((Ra,Is)=>{Is.exports={rosReleases:{kinetic:{rosVersion:1,ubuntuCodename:"xenial"},melodic:{rosVersion:1,ubuntuCodename:"bionic"},noetic:{rosVersion:1,ubuntuCodename:"focal"},dashing:{rosVersion:2},eloquent:{rosVersion:2},foxy:{rosVersion:2},galactic:{rosVersion:2},humble:{rosVersion:2},iron:{rosVersion:2},rolling:{rosVersion:2}}}});var He=v((Na,js)=>{var Xo=J(),Ns=Wr(),ue={get:require("lodash/get"),set:require("lodash/set"),unset:require("lodash/unset"),forEach:require("lodash/forEach"),map:require("lodash/map"),isEmpty:require("lodash/isEmpty"),eq:require("lodash/isEqual"),isPlainObject:require("lodash/isPlainObject"),merge:require("lodash/merge")},fe=zr(),we=Os(),Wo=Rs();fe.setAll=t=>Object.values(fe.getLoggers()).forEach(e=>e.setLevel(t));var As={warn:we.yellow,error:we.red,info:we.green,debug:we.gray},Jo=t=>As[t]?As[t](t):t,zo=fe.methodFactory;fe.methodFactory=(t,e,r)=>{let s=zo(t,e,r);if(typeof window<"u"){let o=`${r} ${t}`;return(...i)=>s(`[${o}]`,...i)}let n=`${r} ${Jo(t)}`;return(...o)=>s(`[${we.blue(new Date().toISOString())} ${n}]`,...o)};var Qo=fe.getLogger,Ko=t=>JSON.parse(JSON.stringify(t)),Yo=t=>JSON.parse(atob(t.split(".")[1])),Zo=t=>{try{return JSON.parse(t)}catch{return null}},Ss=(t,e,r)=>{t&&(r(t),t[e]?.forEach(s=>Ss(s,e,r)))},Cs=(t,e,r,s=[])=>{r(t,s);let n=e[0];if(n){let o=t[n];o&&Cs(o,e.slice(1),r,s.concat(n))}},ei=t=>new Promise(e=>{setTimeout(e,t)}),Ls=(t,e=[],r={})=>(ue.forEach(t,(s,n)=>{let o=e.concat(String(n));(ue.isPlainObject(s)||s instanceof Array)&&s!==null?Ls(s,o,r):r[Bs(o)]=s}),r),Ps=(t,e,r,s=[],n={})=>{if(e.length==0||e[0]=="#"){r(t,s,n);return}let o=e[0];if(o){for(let i in t)if(i==o||o=="*"||o.startsWith("+")){let a=o.startsWith("+")&&o.length>1?Object.assign({},n,{[o.slice(1)]:i}):n;Ps(t[i],e.slice(1),r,s.concat([i]),a)}}},qs=(t,e,r)=>{if(e.length==0)return t;let s=e.shift();e.length==0?t[s]=r:(t[s]||(t[s]={}),qs(t[s],e,r))},Ds=t=>t.replace(/%/g,"%25").replace(/\//g,"%2F"),Fs=t=>t.replace(/%25/g,"%").replace(/%2F/g,"/"),Bs=t=>{let e=r=>r.startsWith("+")?"+":r;return`/${t.map(e).map(Ds).join("/")}`},re=t=>{let e=t.split("/").map(Fs);return e.length>0&&e[0].length==0&&e.shift(),e.length>0&&e.at(-1).length==0&&e.pop(),e},Ms=(t,e)=>{let r=(o,i)=>{if(o.length==0||o[0][0]=="#"||i.length==0)return!0;if(o[0]==i[0])return r(o.slice(1),i.slice(1));if(o[0][0]=="+"){let a=r(o.slice(1),i.slice(1));return a&&Object.assign({[o[0].slice(1)]:i[0]},a)}return!1},s=re(t),n=re(e);return r(s,n)},ti=(t,e)=>{let r=re(e),s=re(t);return ks(r,s)&&r.length<s.length},ks=(t,e)=>t.length==0?!0:t[0]==e[0]&&ks(t.slice(1),e.slice(1)),ri=t=>{let e=t.split(":");return{organization:e[0],client:e[1],sub:e.slice(2)}},si=t=>{let e=re(t);return{organization:e[0],device:e[1],capabilityScope:e[2],capabilityName:e[3],capability:`${e[2]}/${e[3]}`,version:e[4],sub:e.slice(5)}},ni=t=>t.length==0?null:JSON.parse(t.toString("utf-8")),oi=(t,e,r,s=1e3)=>{let n=[],o=a=>{e.forEach(l=>Ms(`${l}/#`,a)&&n.push(a))};t.on("message",o),e.forEach(a=>{typeof a=="string"?t.subscribe(`${a}/#`):console.warn("Ignoring",a,"since it is not a string.")});let i=typeof Buffer<"u"?Buffer.alloc(0):null;setTimeout(()=>{t.removeListener("message",o),e.forEach(l=>t.unsubscribe(`${l}/#`));let a=n.length;console.log(`clearing ${a} retained messages from ${e}`),n.forEach(l=>{t.publish(l,i,{retain:!0})}),r&&r(a)},s)},ii=()=>Math.random().toString(36).slice(2),Ue=(t,e)=>Xo(Ns(t),Ns(e)),ai=(t,e=void 0,r={})=>{if(!t)return e?ue.set({},e,t):t;let s=Object.keys(t).filter(i=>(!r.maxVersion||Ue(i,r.maxVersion)<=0)&&(!r.minVersion||Ue(r.minVersion,i)<=0)).sort(Ue),n={},o=e&&re(e);return s.forEach(i=>{let a=o?ue.get(t[i],o):t[i];ue.merge(n,a)}),o?ue.set({},o,n):n},li=["B","KB","MB","GB","TB"],ci=t=>{if(!t)return"--";let e=0;for(;t>1024;)t/=1024,e++;return`${t.toFixed(2)} ${li[e]}`},ui=t=>{if(!t)return"--";let e={};t>3600&&(e.h=Math.floor(t/3600),t=t%3600),t>60&&(e.m=Math.floor(t/60),t=t%60),e.s=Math.floor(t);let r="";return e.h>0&&(r+=`${e.h}h `),e.m>0&&(r+=`${e.m}m `),!e.h&&(r+=`${e.s}s`),r.trim()};js.exports={parseMQTTUsername:ri,parseMQTTTopic:si,pathToTopic:Bs,topicToPath:re,toFlatObject:Ls,topicMatch:Ms,mqttParsePayload:ni,getRandomId:ii,versionCompare:Ue,loglevel:fe,getLogger:Qo,mergeVersions:ai,mqttClearRetained:oi,isSubTopicOf:ti,clone:Ko,setFromPath:qs,forMatchIterator:Ps,encodeTopicElement:Ds,decodeTopicElement:Fs,constants:Wo,visit:Ss,wait:ei,formatBytes:ci,formatDuration:ui,tryJSONParse:Zo,decodeJWT:Yo,visitAncestor:Cs}});var Tt=v((Aa,Us)=>{var k={get:require("lodash/get"),set:require("lodash/set"),unset:require("lodash/unset"),forEach:require("lodash/forEach"),map:require("lodash/map"),isEmpty:require("lodash/isEmpty"),eq:require("lodash/isEqual"),isPlainObject:require("lodash/isPlainObject"),merge:require("lodash/merge")},{topicToPath:Te,pathToTopic:fi,toFlatObject:hi,topicMatch:Gs,forMatchIterator:di}=He(),wt=(t,e)=>{if(!e||e.length==0)return;k.unset(t,e);let r=e.slice(0,-1),s=r.length==0?t:k.get(t,r);return k.isEmpty(s)?wt(t,r):e},pi=(t,e)=>(k.forEach(e,(r,s)=>{let n=Te(s);r==null?wt(t,n):k.set(t,n,r)}),t),_s=(t,e)=>{if(e.length==0)return;let r=e[0];if(r)for(let s in t)s!=r&&r!="*"&&!r.startsWith("+")?delete t[s]:_s(t[s],e.slice(1))},$t=class{#e={};#t=[];#r=[];constructor(e={}){this.#e=e}updateFromArray(e,r,s={}){let n=k.get(this.#e,e);if(r==null){if(n==null)return{};wt(this.#e,e)}else{if(k.eq(n,r))return{};k.set(this.#e,e,r)}let o=fi(e),i={[o]:r},a;if(r instanceof Object){let l=hi(r);a={},k.forEach(l,(c,f)=>{a[`${o}${f}`]=c})}else a=i;return this.#t.forEach(l=>l(i,s)),this.#r.forEach(l=>l(a,s)),a}update(e,r,s){if(typeof e=="string")return this.updateFromTopic(e,r,s);if(e instanceof Array)return this.updateFromArray(e,r,s);throw new Error("unrecognized path expression")}updateFromTopic(e,r,s){return this.updateFromArray(Te(e),r,s)}updateFromModifier(e,r){return k.map(e,(s,n)=>this.updateFromTopic(n,s,r))}subscribe(e){e instanceof Function?this.#t.push(e):console.warn("DataCache.subscribe expects a function as argument. Did you mean to use subscribePath?")}subscribePath(e,r){this.#t.push((s,n)=>{k.forEach(s,(o,i)=>{let a=Gs(e,i);a&&r(o,i,a,n)})})}subscribePathFlat(e,r){this.#r.push((s,n)=>{k.forEach(s,(o,i)=>{let a=Gs(e,i);a&&r(o,i,a,n)})})}unsubscribe(e){this.#t=this.#t.filter(r=>r!=e)}get(e=[]){return e.length==0?this.#e:k.get(this.#e,e)}getByTopic(e){return this.get(Te(e))}filter(e){let r=JSON.parse(JSON.stringify(this.get()));return _s(r,e),r}filterByTopic(e){return this.filter(Te(e))}forMatch(e,r){let s=Te(e);this.forPathMatch(s,r)}forPathMatch(e,r){di(this.get(),e,r)}};Us.exports={DataCache:$t,updateObject:pi}});var At=v((Ca,Ws)=>{"use strict";var{mqttParsePayload:gi,topicMatch:Ot,topicToPath:z,pathToTopic:Oe,toFlatObject:It,getLogger:mi,mergeVersions:bi,parseMQTTTopic:yi,isSubTopicOf:Sa,versionCompare:Ei,encodeTopicElement:vi,visitAncestor:xi}=He(),{DataCache:Hs}=Tt(),Q=require("lodash"),R=mi("MqttSync"),Rt="$SYS/broker/uptime",he="$_",$i=()=>{},wi=t=>typeof t=="object"?JSON.parse(JSON.stringify(t)):t,Vs=t=>t.endsWith("/#")?t:t.endsWith("/")?t.concat("#"):t.concat("/#"),Xs=t=>t.replace(/\/\//g,"/"),Nt=class{data=new Hs;subscribedPaths={};publishedPaths={};publishedMessages=new Hs;publishQueue=new Map;heartbeatWaitersOnce=[];heartbeats=0;beforeDisconnectHooks=[];constructor({mqttClient:e,onChange:r,ignoreRetain:s,migrate:n,onReady:o,sliceTopic:i,onHeartbeatGranted:a}){this.mqtt=e,this.mqtt.on("message",(l,c,f)=>{let u=c&&c.toString();if(R.debug("got message",l,u.slice(0,180),u.length>180?`... (${u.length} bytes)`:"",f.retain),l==Rt)this.heartbeats>0&&(this.heartbeatWaitersOnce.forEach(h=>h()),this.heartbeatWaitersOnce=[]),this.heartbeats==1&&!n&&o&&o(),this.heartbeats++;else if(f.retain||s){let h=z(l);R.debug("processing message",l,h),i&&(h=h.slice(i),l=Oe(h));let x=gi(c);if(this.isPublished(l))this.publishedMessages.updateFromArray([...h,he],x),this.data.update(l,x,{external:!0});else if(this.isSubscribed(l)){R.debug("applying received update",l);let m=this.data.update(l,x);r&&Object.keys(m).length>0&&r(m)}}}),this.mqtt.subscribe(Rt,{rap:!0},(l,c)=>{R.debug(Rt,{granted:c}),c.length>0&&a?.()}),n?.length>0&&this.migrate(n,()=>{R.debug("done migrating",o),o&&this.waitForHeartbeatOnce(o)})}publishAtLevel(e,r,s){R.debug(`publishingAtLevel ${s}`,e,r),s>0?Q.forEach(r,(n,o)=>{let i=`${e}/${vi(o)}`;R.debug(`publishing ${i}`),this.publishAtLevel(i,n,s-1)}):this.mqtt.publish(e,JSON.stringify(r),{retain:!0},n=>{n&&R.warn("Error when publishing migration result",n)})}migrate(e,r=void 0){let s=e.length;if(s==0){r&&r();return}let n=()=>--s==0&&r&&r();e.forEach(({topic:o,newVersion:i,transform:a=void 0,flat:l=!1,level:c=0})=>{R.debug("migrating",o,i);let{organization:f,device:u,capability:h,sub:x}=yi(o),m=`/${f}/${u}/${h}`,w=x.length==0?"/#":Oe(x),I=`${m}/+${w}`;this.subscribe(I,T=>{if(T){R.warn("Error during migration",T),n();return}this.waitForHeartbeatOnce(()=>{R.debug("got heartbeat",o,I);let V=this.data.getByTopic(m);if(!V){this.unsubscribe(I),n();return}let L=bi(V,w,{maxVersion:i}),X=Q.get(L,z(w)),_=a?a(X):X,K=Xs(`${m}/${i}/${w}`);if(R.debug("publishing merged",K),l){let j=It(_),E=z(K);Q.forEach(j,(M,Y)=>{let We=Oe(E.concat(z(Y)));this.mqtt.publish(We,JSON.stringify(M),{retain:!0},qt=>{qt&&R.warn(`Error when publishing migration result for ${Y}`,qt)})})}else this.publishAtLevel(K,_,c);this.unsubscribe(I),this.waitForHeartbeatOnce(()=>{let E=Object.keys(V).filter(M=>Ei(M,i)<0).map(M=>Xs(`${m}/${M}/${w}`));R.debug({prefixesToClear:E}),this.clear(E),n()})})})})}clear(e,r=void 0,s={}){let n=[],o=a=>{e.forEach(l=>Ot(`${l}/#`,a)&&(!s.filter||s.filter(a))&&n.push(a))};this.mqtt.on("message",o),e.forEach(a=>{typeof a=="string"?this.mqtt.subscribe(`${a}/#`):R.warn("Ignoring",a,"since it is not a string.")});let i=typeof Buffer<"u"?Buffer.alloc(0):null;this.waitForHeartbeatOnce(()=>{this.mqtt.removeListener("message",o),e.forEach(l=>this.mqtt.unsubscribe(`${l}/#`));let a=n.length;R.debug(`clearing ${a} retained messages from ${e}`),n.forEach(l=>{this.mqtt.publish(l,i,{retain:!0})}),r&&r(a)})}waitForHeartbeatOnce(e){setTimeout(()=>this.heartbeatWaitersOnce.push(e),1)}isSubscribed(e){return Object.keys(this.subscribedPaths).some(r=>Ot(r,e))}isPublished(e){return Object.keys(this.publishedPaths).some(r=>Ot(r,e)&&!this.publishedPaths[r].atomic)}subscribe(e,r=$i){if(e=Vs(e),R.debug("subscribing to",e),this.subscribedPaths[e]){R.debug("already subscribed to",e),r();return}this.mqtt.subscribe(e,{rap:!0},(s,n)=>{R.debug("subscribe",e,"granted:",n),n&&n.some(o=>o.topic==e&&o.qos<128)?(this.subscribedPaths[e]=1,r(null)):r(`not permitted to subscribe to topic ${e}, ${JSON.stringify(n)}`)})}unsubscribe(e){this.subscribedPaths[e]&&(this.mqtt.unsubscribe(e),delete this.subscribedPaths[e])}_actuallyPublish(e,r){return this.mqtt.connected?(R.debug("actually publishing",e),this.mqtt.publish(e,r==null?null:JSON.stringify(r),{retain:!0}),!0):(R.warn("not connected, not publishing",e),!1)}_processQueue_rec(e){if(this.publishQueue.size>0){let[r,s]=this.publishQueue.entries().next().value;this._actuallyPublish(r,s)?(this.publishQueue.delete(r),this._processQueue_rec(e)):setTimeout(()=>this._processQueue_rec(e),5e3)}else e()}_processQueue(){this._processing||(this._processing=!0,this._processQueue_rec(()=>this._processing=!1))}setThrottle(e){this._processQueueThrottled=Q.throttle(this._processQueue.bind(this),e)}clearThrottle(){delete this._processQueueThrottled}addToQueue(e,r){this.publishQueue.set(e,r)}_enqueue(e,r){R.debug("enqueuing",e),this.addToQueue(e,r),this._processQueueThrottled?this._processQueueThrottled():this._processQueue();let s=z(e);this.publishedMessages.updateFromArray([...s,he],r==null?null:wi(r))}publish(e,r={atomic:!1}){if(e=Vs(e),Q.isEqual(this.publishedPaths[e],r))return!1;if(this.publishedPaths[e]=r,r.atomic)return this.data.subscribePath(e,(s,n,o,i)=>{if(i?.external)return;R.debug("processing change (atomic)",n,e);let a=e.slice(0,e.length-2),l=Oe(z(n).slice(0,z(a).length));this._enqueue(l,this.data.getByTopic(l))}),!0;this.mqtt.subscribe(e),this.data.subscribePath(e,(s,n,o,i)=>{if(i?.external)return;R.debug("processing change",n);let a=z(n),l=this.publishedMessages.get(a);Q.each(l,(f,u)=>{if(u==he)return!0;let h=Object.keys(It(f)).filter(x=>x.endsWith(he));R.debug("flat->atomic: ",{toClear:h},u),h.forEach(x=>{let m=x.slice(0,-(he.length+1)),w=`${n}/${u}/${m}`;this._enqueue(w,null)})});let c=this.publishedMessages.get();return xi(c,a.slice(0,-1),(f,u)=>{let h=f[he];if(h&&Q.isObject(h)){R.debug("atomic->flat",{oldVal:h});let x=Oe(u);this._enqueue(x,null);let m=It(h);Q.each(m,(w,I)=>{let T=`${x}${I}`;this._enqueue(T,w)})}}),this._enqueue(n,s),!0})}beforeDisconnect(){this.beforeDisconnectHooks.forEach(e=>e(this))}onBeforeDisconnect(e){this.beforeDisconnectHooks.push(e)}};Ws.exports=Nt});var pe={};Dt(pe,{Code:()=>Ai,ErrorBoundary:()=>Pt,InlineCode:()=>Si,LevelBadge:()=>Ni,MqttSync:()=>zs,Timer:()=>Ci,TimerContext:()=>en,TransitiveCapability:()=>Li,createWebComponent:()=>qi,fetchJson:()=>Ks,parseCookie:()=>Qs,useCapability:()=>Lt,useMqttSync:()=>Ct,useTopics:()=>Ii,useTransitive:()=>Oi});module.exports=an(pe);var $=D(require("react"));var ze=D(require("react")),Qe=require("react"),ln=require("react/jsx-runtime"),cn=["xxl","xl","lg","md","sm","xs"],un="xs",Ft=ze.createContext({prefixes:{},breakpoints:cn,minBreakpoint:un}),{Consumer:Bi,Provider:Mi}=Ft;function Se(t,e){let{prefixes:r}=(0,Qe.useContext)(Ft);return t||r[e]||e}var Bt=D(require("react")),Mt=require("react/jsx-runtime"),fn=["as","disabled"];function hn(t,e){if(t==null)return{};var r={},s=Object.keys(t),n,o;for(o=0;o<s.length;o++)n=s[o],!(e.indexOf(n)>=0)&&(r[n]=t[n]);return r}function dn(t){return!t||t.trim()==="#"}function Ke({tagName:t,disabled:e,href:r,target:s,rel:n,role:o,onClick:i,tabIndex:a=0,type:l}){t||(r!=null||s!=null||n!=null?t="a":t="button");let c={tagName:t};if(t==="button")return[{type:l||"button",disabled:e},c];let f=h=>{if((e||t==="a"&&dn(r))&&h.preventDefault(),e){h.stopPropagation();return}i?.(h)},u=h=>{h.key===" "&&(h.preventDefault(),f(h))};return t==="a"&&(r||(r="#"),e&&(r=void 0)),[{role:o??"button",disabled:void 0,tabIndex:e?void 0:a,href:r,target:t==="a"?s:void 0,"aria-disabled":e||void 0,rel:t==="a"?n:void 0,onClick:f,onKeyDown:u},c]}var pn=Bt.forwardRef((t,e)=>{let{as:r,disabled:s}=t,n=hn(t,fn),[o,{tagName:i}]=Ke(Object.assign({tagName:r,disabled:s},n));return(0,Mt.jsx)(i,Object.assign({},n,o,{ref:e}))});pn.displayName="Button";var kt=D(Je()),jt=D(require("react"));var Gt=require("react/jsx-runtime"),_t=jt.forwardRef(({bsPrefix:t,bg:e="primary",pill:r=!1,text:s,className:n,as:o="span",...i},a)=>{let l=Se(t,"badge");return(0,Gt.jsx)(o,{ref:a,...i,className:(0,kt.default)(n,l,r&&"rounded-pill",s&&`text-${s}`,e&&`bg-${e}`)})});_t.displayName="Badge";var se=_t;var Ut=D(Je()),Ht=D(require("react"));var Vt=require("react/jsx-runtime"),Xt=Ht.forwardRef(({as:t,bsPrefix:e,variant:r="primary",size:s,active:n=!1,disabled:o=!1,className:i,...a},l)=>{let c=Se(e,"btn"),[f,{tagName:u}]=Ke({tagName:t,disabled:o,...a});return(0,Vt.jsx)(u,{...f,...a,ref:l,disabled:o,className:(0,Ut.default)(i,c,n&&"active",r&&`${c}-${r}`,s&&`${c}-${s}`,a.href&&o&&"disabled")})});Xt.displayName="Button";var Ye=Xt;var Zs=D(Yt());var y={};Dt(y,{MqttSync:()=>zs,fetchJson:()=>Ks,parseCookie:()=>Qs});A(y,D(He()));A(y,D(Tt()));var Js=D(At()),zs=Js.default,Qs=t=>t.split(";").map(e=>e.split("=")).reduce((e,r)=>(e[decodeURIComponent(r[0].trim())]=r[1]&&decodeURIComponent(r[1].trim()),e),{}),Ks=(t,e,r={})=>{fetch(t,{method:r.method||(r.body?"post":"get"),mode:"cors",cache:"no-cache",headers:{"Content-Type":"application/json",...r.headers},redirect:"follow",referrerPolicy:"no-referrer",body:r.body?JSON.stringify(r.body):void 0}).then(s=>{let n=!s.ok&&`fetching ${t} failed: ${s.status} ${s.statusText}`;s.json().then(o=>e(n,o)).catch(o=>{throw new Error(o)})}).catch(s=>e(`error: ${s}`))};var B=D(require("react")),Xe=D(require("lodash")),Ys=D(require("mqtt-browser"));var Ti=At(),F=(0,y.getLogger)("utils-web/hooks");F.setLevel("info");F.setLevel("debug");var Ct=({jwt:t,id:e,mqttUrl:r})=>{let[s,n]=(0,B.useState)("connecting"),[o,i]=(0,B.useState)(),[a,l]=(0,B.useState)({}),[c,f]=(0,B.useState)(!1);return(0,B.useEffect)(()=>{let u=(0,y.decodeJWT)(t),h=Ys.default.connect(r,{username:JSON.stringify({id:e,payload:u}),password:t});return h.on("connect",()=>{F.debug("connected");let x=new Ti({mqttClient:h,ignoreRetain:!0,onHeartbeatGranted:()=>f(!0)});i(x),n("connected"),x.data.subscribe(Xe.default.throttle(()=>l((0,y.clone)(x.data.get())),50))}),h.on("error",x=>{F.error(x),n(`error: ${x}`)}),()=>{F.info("cleaning up useMQTTSync"),o&&o.beforeDisconnect?(o.beforeDisconnect(),o.waitForHeartbeatOnce(()=>h.end())):h.end()}},[t,e]),{status:s,ready:c,StatusComponent:()=>B.default.createElement("div",null,s),mqttSync:o,data:a}},Oi=({jwt:t,id:e,host:r,ssl:s,capability:n,versionNS:o})=>{let[i,a]=n.split("/"),{device:l}=(0,y.decodeJWT)(t),c=[e,l,i,a],f=(0,y.pathToTopic)(c),u=[...c,o],h=(0,y.pathToTopic)(u),x=`${s&&JSON.parse(s)?"wss":"ws"}://mqtt.${r}`;return{...Ct({jwt:t,id:e,mqttUrl:x}),device:l,prefixPath:c,prefix:f,prefixPathVersion:u,prefixVersion:h}},Ii=({jwt:t,host:e="transitiverobotics.com",ssl:r=!0,topics:s=[]})=>{let[n,o]=(0,B.useState)();!Xe.default.isEqual(n,s)&&o(s);let{device:i,id:a,capability:l}=(0,y.decodeJWT)(t);if(i=="_fleet"){F.warn("useTopics only works for device JWTs, not _fleet ones");return}let c=`/${a}/${i}/@transitive-robotics/_robot-agent/+/status`,{mqttSync:f,data:u,status:h,ready:x,StatusComponent:m}=Ct({jwt:t,id:a,mqttUrl:`ws${r?"s":""}://mqtt.${e}`});(0,B.useEffect)(()=>{x&&f.subscribe(c,j=>j&&console.warn(j))},[f,x]);let w=(0,y.mergeVersions)(u[a]?.[i]["@transitive-robotics"]["_robot-agent"],"status").status,I=w?.runningPackages,[T,V]=l.split("/"),L=I?.[T]?.[V],X=L&&Object.values(L).filter(Boolean)[0],_=`/${a}/${i}/${l}/${X}`;(0,B.useEffect)(()=>{F.debug("topics",s),X&&s.forEach(j=>{F.debug(`subscribing to ${_}${j}`),f.subscribe(`${_}${j}`,E=>E&&F.warn(E))})},[n,X,f]);let K=Xe.default.get(u,(0,y.topicToPath)(_));return{data:u?.[a]?.[i],mqttSync:f,agentStatus:w,topicData:K}},Ve={},St={},Lt=({capability:t,name:e,userId:r,deviceId:s,host:n="transitiverobotics.com",ssl:o=!0})=>{let[i,a]=(0,B.useState)({loaded:!1}),l=(f,u)=>{F.debug(`custom component ${e}: ${f}`),St[e]=u,a(h=>({...h,loadedModule:u,loaded:!!u}))},c=(...f)=>Ve[e].forEach(u=>u(...f));return(0,B.useEffect)(()=>{if(F.debug(`loading custom component ${e}`),St[e])return l("already loaded",St[e]);if(Ve[e])return F.debug("already loading"),Ve[e].push(l);Ve[e]=[l];let f=`http${o?"s":""}://portal.${n}`,u=new URLSearchParams({userId:r,deviceId:s}),h=`${f}/running/${t}/dist/${e}`;import(`${h}.esm.js?${u.toString()}`).then(x=>c("loaded esm",x),x=>{F.warn(`No ESM module found for ${e}, loading iife`),import(`${h}.js?${u.toString()}`).then(m=>c("loaded iife",m),m=>F.error(`Failed to load ${e} iife`,m))})},[t,e,r,s]),i};var de={badge:{width:"4em"},code:{color:"#700",borderLeft:"3px solid #aaa",padding:"0.5em 0px 0.5em 2em",backgroundColor:"#f0f0f0",borderRadius:"4px",marginTop:"0.5em"},inlineCode:{color:"#700",margin:"0px 0.5em 0px 0.5em"}},Ri=[$.default.createElement(se,{bg:"success",style:de.badge},"OK"),$.default.createElement(se,{bg:"warning",style:de.badge},"Warn"),$.default.createElement(se,{bg:"danger",style:de.badge},"Error"),$.default.createElement(se,{bg:"secondary",style:de.badge},"Stale")],Ni=({level:t})=>Ri[t]||$.default.createElement("span",null,t),Ai=({children:t})=>$.default.createElement("pre",{style:de.code},t),Si=({children:t})=>$.default.createElement("tt",{style:de.inlineCode},t),Ie={},en=$.default.createContext({}),Ci=({duration:t,onTimeout:e,onStart:r,setOnDisconnect:s,children:n})=>{t=t||60;let[o,i]=(0,$.useState)(t),[a,l]=(0,$.useState)(!1),c=(0,$.useMemo)(()=>Math.random().toString(36).slice(2),[]),f=()=>{console.log("stopping timer for",c),e&&setTimeout(e,1),clearInterval(Ie[c]),Ie[c]=null,l(!1)},u=()=>{let x=Ie[c];return console.log(x,Ie,o),!x&&o>0&&(l(!0),Ie[c]=setInterval(()=>i(m=>{if(--m>0)return m;f()}),1e3),r&&setTimeout(r,1)),f};(0,$.useEffect)(()=>{o>0&&!a&&u()},[o]),(0,$.useEffect)(()=>f,[]),s&&s(()=>{f()});let h=()=>i(t);return $.default.createElement(en.Provider,{value:{reset:h,duration:t,timer:o}},o>0?$.default.createElement("div",null,n,o<60&&$.default.createElement("div",null,"Timeout in: ",o," seconds")):$.default.createElement("div",null,"Timed out. ",$.default.createElement(Ye,{onClick:h},"Resume")))},Li=({jwt:t,host:e="transitiverobotics.com",ssl:r=!0,...s})=>{let{id:n,device:o,capability:i}=(0,y.decodeJWT)(t),a=o=="_fleet"?"fleet":"device",c=`${i.split("/")[1]}-${a}`,{loaded:f}=Lt({capability:i,name:c,userId:n||s.userId,deviceId:o,host:e,ssl:r}),u=(0,$.useRef)();(0,$.useEffect)(()=>{u.current?.instance?.setState(x=>({...x,id:n,jwt:t,host:e,ssl:r,...s}))},[u.current,n,t,e,r,...Object.values(s)]);let h=(0,$.useMemo)(()=>({id:n,jwt:t,host:e,ssl:r,...s}),[]);return f?$.default.createElement(c,{...h,ref:u}):$.default.createElement("div",null,"Loading ",c)},Pt=class extends $.default.Component{constructor(e){super(e),this.state={hasError:!1}}static getDerivedStateFromError(e){return{hasError:!0}}componentDidCatch(e,r){console.warn("ErrorBoundary caught:",e,r)}render(){return this.state.hasError?$.default.createElement("div",null,this.props.message||"Something went wrong here."):this.props.children}},Pi=t=>t.$$typeof==Symbol.for("react.forward_ref")||t.prototype?.render,qi=(t,e,r="0.0.0",s={})=>{let n=Pi(t)?$.default.createRef():null;class o extends $.default.Component{onDisconnect=null;state={};setOnDisconnect(a){this.onDisconnect=a}webComponentConstructed(a){let l=new MutationObserver(c=>{let f={};c.forEach(({attributeName:u})=>{f[u]=a.getAttribute(u)}),this.setState(u=>({...u,...f}))}).observe(a,{attributes:!0})}webComponentDisconnected(){this.setState({_disconnected:!0});try{this.onDisconnect&&this.onDisconnect()}catch(a){console.log("Error during onDisconnect of web-component",a)}}setConfig(a){this.setState({config:a})}render(){let a=s.stylesheets||["https://cdn.jsdelivr.net/gh/transitiverobotics/transitive-utils@0.8.3/web/css/bootstrap_transitive-bs-root.min.css"];return $.default.createElement("div",{id:`cap-${e}-${r}`,className:s.className||"transitive-bs-root"},$.default.createElement("style",null,a.map(l=>`@import url(${l});`)),!this.state._disconnected&&$.default.createElement(t,{ref:n,...this.props,...this.state,setOnDisconnect:this.setOnDisconnect.bind(this),setConfig:this.setConfig.bind(this)}))}}return Zs.default.create(o,e,s.shadowDOM||!1,n)};A(pe,y,module.exports);
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
8
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
9
|
+
};
|
|
10
|
+
var __export = (target, all) => {
|
|
11
|
+
for (var name in all)
|
|
12
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
13
|
+
};
|
|
14
|
+
var __copyProps = (to, from, except, desc) => {
|
|
15
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
16
|
+
for (let key of __getOwnPropNames(from))
|
|
17
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
18
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
+
mod
|
|
30
|
+
));
|
|
31
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
|
+
|
|
33
|
+
// client/react-web-component/getStyleElementsFromReactWebComponentStyleLoader.js
|
|
34
|
+
var require_getStyleElementsFromReactWebComponentStyleLoader = __commonJS({
|
|
35
|
+
"client/react-web-component/getStyleElementsFromReactWebComponentStyleLoader.js"(exports, module2) {
|
|
36
|
+
module2.exports = () => {
|
|
37
|
+
try {
|
|
38
|
+
return require("react-web-component-style-loader/exports").styleElements;
|
|
39
|
+
} catch (e) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// client/react-web-component/extractAttributes.js
|
|
47
|
+
var require_extractAttributes = __commonJS({
|
|
48
|
+
"client/react-web-component/extractAttributes.js"(exports, module2) {
|
|
49
|
+
module2.exports = function extractAttributes(nodeMap) {
|
|
50
|
+
if (!nodeMap.attributes) {
|
|
51
|
+
return {};
|
|
52
|
+
}
|
|
53
|
+
let obj = {};
|
|
54
|
+
let attribute;
|
|
55
|
+
const attributesAsNodeMap = [...nodeMap.attributes];
|
|
56
|
+
const attributes = attributesAsNodeMap.map((attribute2) => ({ [attribute2.name]: attribute2.value }));
|
|
57
|
+
for (attribute of attributes) {
|
|
58
|
+
const key = Object.keys(attribute)[0];
|
|
59
|
+
const camelCasedKey = key.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
|
60
|
+
obj[camelCasedKey] = attribute[key];
|
|
61
|
+
}
|
|
62
|
+
return obj;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// client/react-web-component/index.js
|
|
68
|
+
var require_react_web_component = __commonJS({
|
|
69
|
+
"client/react-web-component/index.js"(exports, module2) {
|
|
70
|
+
var React3 = require("react");
|
|
71
|
+
var ReactDOM = require("react-dom");
|
|
72
|
+
var retargetEvents = require("react-shadow-dom-retarget-events");
|
|
73
|
+
var getStyleElementsFromReactWebComponentStyleLoader = require_getStyleElementsFromReactWebComponentStyleLoader();
|
|
74
|
+
var extractAttributes = require_extractAttributes();
|
|
75
|
+
var lifeCycleHooks = {
|
|
76
|
+
attachedCallback: "webComponentAttached",
|
|
77
|
+
connectedCallback: "webComponentConnected",
|
|
78
|
+
disconnectedCallback: "webComponentDisconnected",
|
|
79
|
+
adoptedCallback: "webComponentAdopted"
|
|
80
|
+
};
|
|
81
|
+
module2.exports = {
|
|
82
|
+
/*
|
|
83
|
+
* @param {JSX.Element} wrapper: the wrapper component class to be instantiated and wrapped
|
|
84
|
+
* @param {string} tagName - The name of the web component. Has to be minus "-" delimited.
|
|
85
|
+
* @param {boolean} useShadowDom - If the value is set to "true" the web component will use the `shadowDom`. The default value is true.
|
|
86
|
+
*/
|
|
87
|
+
create: (wrapper, tagName, useShadowDom = true, compRef = void 0) => {
|
|
88
|
+
const proto = class extends HTMLElement {
|
|
89
|
+
instance = null;
|
|
90
|
+
// the instance we create of the wrapper
|
|
91
|
+
callConstructorHook() {
|
|
92
|
+
if (this.instance["webComponentConstructed"]) {
|
|
93
|
+
this.instance["webComponentConstructed"].apply(this.instance, [this]);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
callLifeCycleHook(hook, params = []) {
|
|
97
|
+
const method = lifeCycleHooks[hook];
|
|
98
|
+
if (method && this.instance && this.instance[method]) {
|
|
99
|
+
this.instance[method].apply(this.instance, params);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
connectedCallback() {
|
|
103
|
+
const self = this;
|
|
104
|
+
let mountPoint = self;
|
|
105
|
+
if (useShadowDom) {
|
|
106
|
+
const shadowRoot = self.attachShadow({ mode: "open" });
|
|
107
|
+
mountPoint = document.createElement("div");
|
|
108
|
+
const styles2 = getStyleElementsFromReactWebComponentStyleLoader();
|
|
109
|
+
styles2.forEach((style) => {
|
|
110
|
+
shadowRoot.appendChild(style.cloneNode(shadowRoot));
|
|
111
|
+
});
|
|
112
|
+
shadowRoot.appendChild(mountPoint);
|
|
113
|
+
retargetEvents(shadowRoot);
|
|
114
|
+
}
|
|
115
|
+
ReactDOM.render(
|
|
116
|
+
// This is where we instantiate the actual component (in its wrapper)
|
|
117
|
+
React3.createElement(wrapper, extractAttributes(self)),
|
|
118
|
+
mountPoint,
|
|
119
|
+
function() {
|
|
120
|
+
self.instance = this;
|
|
121
|
+
self.callConstructorHook();
|
|
122
|
+
self.callLifeCycleHook("connectedCallback");
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
disconnectedCallback() {
|
|
127
|
+
this.callLifeCycleHook("disconnectedCallback");
|
|
128
|
+
}
|
|
129
|
+
adoptedCallback(oldDocument, newDocument) {
|
|
130
|
+
this.callLifeCycleHook("adoptedCallback", [oldDocument, newDocument]);
|
|
131
|
+
}
|
|
132
|
+
/* call a function defined in the component, either as a class method, or
|
|
133
|
+
* via useImperativeHandle */
|
|
134
|
+
call(functionName, args) {
|
|
135
|
+
return compRef?.current?.[functionName]?.call(compRef?.current, args);
|
|
136
|
+
}
|
|
137
|
+
/* predefined function to retrieve the pre-defined config object of the
|
|
138
|
+
* state, populated via the pre-defined `setConfig` method given as prop
|
|
139
|
+
* to the wrapped component. */
|
|
140
|
+
getConfig() {
|
|
141
|
+
return this.instance.state.config;
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
customElements.define(tagName, proto);
|
|
145
|
+
return proto;
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// ../common/constants.js
|
|
152
|
+
var require_constants = __commonJS({
|
|
153
|
+
"../common/constants.js"(exports, module2) {
|
|
154
|
+
module2.exports = {
|
|
155
|
+
rosReleases: {
|
|
156
|
+
kinetic: { rosVersion: 1, ubuntuCodename: "xenial" },
|
|
157
|
+
melodic: { rosVersion: 1, ubuntuCodename: "bionic" },
|
|
158
|
+
noetic: { rosVersion: 1, ubuntuCodename: "focal" },
|
|
159
|
+
dashing: { rosVersion: 2 },
|
|
160
|
+
eloquent: { rosVersion: 2 },
|
|
161
|
+
foxy: { rosVersion: 2 },
|
|
162
|
+
galactic: { rosVersion: 2 },
|
|
163
|
+
humble: { rosVersion: 2 },
|
|
164
|
+
iron: { rosVersion: 2 },
|
|
165
|
+
rolling: { rosVersion: 2 }
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// ../common/common.js
|
|
172
|
+
var require_common = __commonJS({
|
|
173
|
+
"../common/common.js"(exports, module2) {
|
|
174
|
+
var semverCompare = require("semver/functions/compare");
|
|
175
|
+
var semverMinVersion = require("semver/ranges/min-version");
|
|
176
|
+
var _2 = {
|
|
177
|
+
get: require("lodash/get"),
|
|
178
|
+
set: require("lodash/set"),
|
|
179
|
+
unset: require("lodash/unset"),
|
|
180
|
+
forEach: require("lodash/forEach"),
|
|
181
|
+
map: require("lodash/map"),
|
|
182
|
+
isEmpty: require("lodash/isEmpty"),
|
|
183
|
+
eq: require("lodash/isEqual"),
|
|
184
|
+
isPlainObject: require("lodash/isPlainObject"),
|
|
185
|
+
merge: require("lodash/merge")
|
|
186
|
+
};
|
|
187
|
+
var loglevel = require("loglevel");
|
|
188
|
+
var chalk = require("chalk");
|
|
189
|
+
var constants = require_constants();
|
|
190
|
+
loglevel.setAll = (level) => Object.values(loglevel.getLoggers()).forEach((l) => l.setLevel(level));
|
|
191
|
+
var methodColors = {
|
|
192
|
+
warn: chalk.yellow,
|
|
193
|
+
error: chalk.red,
|
|
194
|
+
info: chalk.green,
|
|
195
|
+
debug: chalk.gray
|
|
196
|
+
};
|
|
197
|
+
var coloredMethod = (method) => methodColors[method] ? methodColors[method](method) : method;
|
|
198
|
+
var originalFactory = loglevel.methodFactory;
|
|
199
|
+
loglevel.methodFactory = (methodName, level, loggerName) => {
|
|
200
|
+
const rawMethod = originalFactory(methodName, level, loggerName);
|
|
201
|
+
if (typeof window != "undefined") {
|
|
202
|
+
const context2 = `${loggerName} ${methodName}`;
|
|
203
|
+
return (...args) => rawMethod(`[${context2}]`, ...args);
|
|
204
|
+
}
|
|
205
|
+
const context = `${loggerName} ${coloredMethod(methodName)}`;
|
|
206
|
+
return (...args) => rawMethod(
|
|
207
|
+
`[${chalk.blue((/* @__PURE__ */ new Date()).toISOString())} ${context}]`,
|
|
208
|
+
...args
|
|
209
|
+
);
|
|
210
|
+
};
|
|
211
|
+
var getLogger2 = loglevel.getLogger;
|
|
212
|
+
var clone2 = (obj) => JSON.parse(JSON.stringify(obj));
|
|
213
|
+
var decodeJWT3 = (jwt) => JSON.parse(atob(jwt.split(".")[1]));
|
|
214
|
+
var tryJSONParse = (string) => {
|
|
215
|
+
try {
|
|
216
|
+
return JSON.parse(string);
|
|
217
|
+
} catch (e) {
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
var visit = (object, childField, visitor) => {
|
|
222
|
+
if (!object)
|
|
223
|
+
return;
|
|
224
|
+
visitor(object);
|
|
225
|
+
object[childField]?.forEach((child) => visit(child, childField, visitor));
|
|
226
|
+
};
|
|
227
|
+
var visitAncestor = (object, path, visitor, prefix = []) => {
|
|
228
|
+
visitor(object, prefix);
|
|
229
|
+
const next = path[0];
|
|
230
|
+
if (next) {
|
|
231
|
+
const sub = object[next];
|
|
232
|
+
if (sub) {
|
|
233
|
+
visitAncestor(sub, path.slice(1), visitor, prefix.concat(next));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
var wait = (delay) => new Promise((resolve) => {
|
|
238
|
+
setTimeout(resolve, delay);
|
|
239
|
+
});
|
|
240
|
+
var toFlatObject = (obj, prefix = [], rtv = {}) => {
|
|
241
|
+
_2.forEach(obj, (value, key) => {
|
|
242
|
+
const newPrefix = prefix.concat(String(key));
|
|
243
|
+
if ((_2.isPlainObject(value) || value instanceof Array) && value !== null) {
|
|
244
|
+
toFlatObject(value, newPrefix, rtv);
|
|
245
|
+
} else {
|
|
246
|
+
rtv[pathToTopic2(newPrefix)] = value;
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
return rtv;
|
|
250
|
+
};
|
|
251
|
+
var forMatchIterator = (obj, path, callback, pathSoFar = [], matchSoFar = {}) => {
|
|
252
|
+
if (path.length == 0 || path[0] == "#") {
|
|
253
|
+
callback(obj, pathSoFar, matchSoFar);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const next = path[0];
|
|
257
|
+
if (next) {
|
|
258
|
+
for (let key in obj) {
|
|
259
|
+
if (key == next || next == "*" || next.startsWith("+")) {
|
|
260
|
+
const match = next.startsWith("+") && next.length > 1 ? Object.assign({}, matchSoFar, { [next.slice(1)]: key }) : matchSoFar;
|
|
261
|
+
forMatchIterator(
|
|
262
|
+
obj[key],
|
|
263
|
+
path.slice(1),
|
|
264
|
+
callback,
|
|
265
|
+
pathSoFar.concat([key]),
|
|
266
|
+
match
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
var setFromPath = (obj, path, value) => {
|
|
273
|
+
if (path.length == 0)
|
|
274
|
+
return obj;
|
|
275
|
+
const next = path.shift();
|
|
276
|
+
if (path.length == 0) {
|
|
277
|
+
obj[next] = value;
|
|
278
|
+
} else {
|
|
279
|
+
if (!obj[next])
|
|
280
|
+
obj[next] = {};
|
|
281
|
+
setFromPath(obj[next], path, value);
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
var encodeTopicElement = (x) => x.replace(/%/g, "%25").replace(/\//g, "%2F");
|
|
285
|
+
var decodeTopicElement = (x) => x.replace(/%25/g, "%").replace(/%2F/g, "/");
|
|
286
|
+
var pathToTopic2 = (pathArray) => {
|
|
287
|
+
const dropWildcardIds = (x) => x.startsWith("+") ? "+" : x;
|
|
288
|
+
return `/${pathArray.map(dropWildcardIds).map(encodeTopicElement).join("/")}`;
|
|
289
|
+
};
|
|
290
|
+
var topicToPath2 = (topic) => {
|
|
291
|
+
const path = topic.split("/").map(decodeTopicElement);
|
|
292
|
+
path.length > 0 && path[0].length == 0 && path.shift();
|
|
293
|
+
path.length > 0 && path.at(-1).length == 0 && path.pop();
|
|
294
|
+
return path;
|
|
295
|
+
};
|
|
296
|
+
var topicMatch = (selector, topic) => {
|
|
297
|
+
const byArray = (s, p) => {
|
|
298
|
+
if (s.length == 0)
|
|
299
|
+
return true;
|
|
300
|
+
if (s[0][0] == "#")
|
|
301
|
+
return true;
|
|
302
|
+
if (p.length == 0)
|
|
303
|
+
return true;
|
|
304
|
+
if (s[0] == p[0])
|
|
305
|
+
return byArray(s.slice(1), p.slice(1));
|
|
306
|
+
if (s[0][0] == "+") {
|
|
307
|
+
const sub = byArray(s.slice(1), p.slice(1));
|
|
308
|
+
return sub && Object.assign({ [s[0].slice(1)]: p[0] }, sub);
|
|
309
|
+
}
|
|
310
|
+
return false;
|
|
311
|
+
};
|
|
312
|
+
const selectorArray = topicToPath2(selector);
|
|
313
|
+
const pathArray = topicToPath2(topic);
|
|
314
|
+
return byArray(selectorArray, pathArray);
|
|
315
|
+
};
|
|
316
|
+
var isSubTopicOf = (sub, parent) => {
|
|
317
|
+
const pPath = topicToPath2(parent);
|
|
318
|
+
const sPath = topicToPath2(sub);
|
|
319
|
+
return isPrefixOf(pPath, sPath) && pPath.length < sPath.length;
|
|
320
|
+
};
|
|
321
|
+
var isPrefixOf = (prefixArray, array) => {
|
|
322
|
+
if (prefixArray.length == 0)
|
|
323
|
+
return true;
|
|
324
|
+
return prefixArray[0] == array[0] && isPrefixOf(prefixArray.slice(1), array.slice(1));
|
|
325
|
+
};
|
|
326
|
+
var parseMQTTUsername = (username) => {
|
|
327
|
+
const parts = username.split(":");
|
|
328
|
+
return {
|
|
329
|
+
organization: parts[0],
|
|
330
|
+
client: parts[1],
|
|
331
|
+
sub: parts.slice(2)
|
|
332
|
+
};
|
|
333
|
+
};
|
|
334
|
+
var parseMQTTTopic = (topic) => {
|
|
335
|
+
const parts = topicToPath2(topic);
|
|
336
|
+
return {
|
|
337
|
+
organization: parts[0],
|
|
338
|
+
device: parts[1],
|
|
339
|
+
capabilityScope: parts[2],
|
|
340
|
+
capabilityName: parts[3],
|
|
341
|
+
capability: `${parts[2]}/${parts[3]}`,
|
|
342
|
+
version: parts[4],
|
|
343
|
+
sub: parts.slice(5)
|
|
344
|
+
};
|
|
345
|
+
};
|
|
346
|
+
var mqttParsePayload = (payload) => payload.length == 0 ? null : JSON.parse(payload.toString("utf-8"));
|
|
347
|
+
var mqttClearRetained = (mqttClient, prefixes, callback, delay = 1e3) => {
|
|
348
|
+
const toDelete = [];
|
|
349
|
+
const collectToDelete = (topic) => {
|
|
350
|
+
prefixes.forEach(
|
|
351
|
+
(prefix) => (
|
|
352
|
+
// mqttTopicMatch(topic, `${prefix}/#`) && toDelete.push(topic)
|
|
353
|
+
topicMatch(`${prefix}/#`, topic) && toDelete.push(topic)
|
|
354
|
+
)
|
|
355
|
+
);
|
|
356
|
+
};
|
|
357
|
+
mqttClient.on("message", collectToDelete);
|
|
358
|
+
prefixes.forEach((prefix) => {
|
|
359
|
+
if (typeof prefix == "string") {
|
|
360
|
+
mqttClient.subscribe(`${prefix}/#`);
|
|
361
|
+
} else {
|
|
362
|
+
console.warn("Ignoring", prefix, "since it is not a string.");
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
const nullValue = typeof Buffer != "undefined" ? Buffer.alloc(0) : null;
|
|
366
|
+
setTimeout(() => {
|
|
367
|
+
mqttClient.removeListener("message", collectToDelete);
|
|
368
|
+
prefixes.forEach((prefix) => mqttClient.unsubscribe(`${prefix}/#`));
|
|
369
|
+
const count = toDelete.length;
|
|
370
|
+
console.log(`clearing ${count} retained messages from ${prefixes}`);
|
|
371
|
+
toDelete.forEach((topic) => {
|
|
372
|
+
mqttClient.publish(topic, nullValue, { retain: true });
|
|
373
|
+
});
|
|
374
|
+
callback && callback(count);
|
|
375
|
+
}, delay);
|
|
376
|
+
};
|
|
377
|
+
var getRandomId = () => Math.random().toString(36).slice(2);
|
|
378
|
+
var versionCompare = (a, b) => semverCompare(semverMinVersion(a), semverMinVersion(b));
|
|
379
|
+
var mergeVersions2 = (versionsObject, subTopic = void 0, options = {}) => {
|
|
380
|
+
if (!versionsObject) {
|
|
381
|
+
return subTopic ? _2.set({}, subTopic, versionsObject) : versionsObject;
|
|
382
|
+
}
|
|
383
|
+
const versions = Object.keys(versionsObject).filter((ver) => (!options.maxVersion || versionCompare(ver, options.maxVersion) <= 0) && (!options.minVersion || versionCompare(options.minVersion, ver) <= 0)).sort(versionCompare);
|
|
384
|
+
const merged = {};
|
|
385
|
+
const subPath = subTopic && topicToPath2(subTopic);
|
|
386
|
+
versions.forEach((nextVersion) => {
|
|
387
|
+
const newValue = subPath ? _2.get(versionsObject[nextVersion], subPath) : versionsObject[nextVersion];
|
|
388
|
+
_2.merge(merged, newValue);
|
|
389
|
+
});
|
|
390
|
+
return subPath ? _2.set({}, subPath, merged) : merged;
|
|
391
|
+
};
|
|
392
|
+
var units = ["B", "KB", "MB", "GB", "TB"];
|
|
393
|
+
var formatBytes = (bytes) => {
|
|
394
|
+
if (!bytes)
|
|
395
|
+
return "--";
|
|
396
|
+
let i = 0;
|
|
397
|
+
while (bytes > 1024) {
|
|
398
|
+
bytes /= 1024;
|
|
399
|
+
i++;
|
|
400
|
+
}
|
|
401
|
+
return `${bytes.toFixed(2)} ${units[i]}`;
|
|
402
|
+
};
|
|
403
|
+
var formatDuration = (seconds) => {
|
|
404
|
+
if (!seconds)
|
|
405
|
+
return "--";
|
|
406
|
+
const parts = {};
|
|
407
|
+
if (seconds > 3600) {
|
|
408
|
+
parts.h = Math.floor(seconds / 3600);
|
|
409
|
+
seconds = seconds % 3600;
|
|
410
|
+
}
|
|
411
|
+
if (seconds > 60) {
|
|
412
|
+
parts.m = Math.floor(seconds / 60);
|
|
413
|
+
seconds = seconds % 60;
|
|
414
|
+
}
|
|
415
|
+
parts.s = Math.floor(seconds);
|
|
416
|
+
let rtv = "";
|
|
417
|
+
parts.h > 0 && (rtv += `${parts.h}h `);
|
|
418
|
+
parts.m > 0 && (rtv += `${parts.m}m `);
|
|
419
|
+
!parts.h && (rtv += `${parts.s}s`);
|
|
420
|
+
return rtv.trim();
|
|
421
|
+
};
|
|
422
|
+
module2.exports = {
|
|
423
|
+
parseMQTTUsername,
|
|
424
|
+
parseMQTTTopic,
|
|
425
|
+
pathToTopic: pathToTopic2,
|
|
426
|
+
topicToPath: topicToPath2,
|
|
427
|
+
toFlatObject,
|
|
428
|
+
topicMatch,
|
|
429
|
+
mqttParsePayload,
|
|
430
|
+
getRandomId,
|
|
431
|
+
versionCompare,
|
|
432
|
+
loglevel,
|
|
433
|
+
getLogger: getLogger2,
|
|
434
|
+
mergeVersions: mergeVersions2,
|
|
435
|
+
mqttClearRetained,
|
|
436
|
+
isSubTopicOf,
|
|
437
|
+
clone: clone2,
|
|
438
|
+
setFromPath,
|
|
439
|
+
forMatchIterator,
|
|
440
|
+
encodeTopicElement,
|
|
441
|
+
decodeTopicElement,
|
|
442
|
+
constants,
|
|
443
|
+
visit,
|
|
444
|
+
wait,
|
|
445
|
+
formatBytes,
|
|
446
|
+
formatDuration,
|
|
447
|
+
tryJSONParse,
|
|
448
|
+
decodeJWT: decodeJWT3,
|
|
449
|
+
visitAncestor
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
// ../common/DataCache.js
|
|
455
|
+
var require_DataCache = __commonJS({
|
|
456
|
+
"../common/DataCache.js"(exports, module2) {
|
|
457
|
+
var _2 = {
|
|
458
|
+
get: require("lodash/get"),
|
|
459
|
+
set: require("lodash/set"),
|
|
460
|
+
unset: require("lodash/unset"),
|
|
461
|
+
forEach: require("lodash/forEach"),
|
|
462
|
+
map: require("lodash/map"),
|
|
463
|
+
isEmpty: require("lodash/isEmpty"),
|
|
464
|
+
eq: require("lodash/isEqual"),
|
|
465
|
+
isPlainObject: require("lodash/isPlainObject"),
|
|
466
|
+
merge: require("lodash/merge")
|
|
467
|
+
};
|
|
468
|
+
var { topicToPath: topicToPath2, pathToTopic: pathToTopic2, toFlatObject, topicMatch, forMatchIterator } = require_common();
|
|
469
|
+
var unset = (obj, path) => {
|
|
470
|
+
if (!path || path.length == 0)
|
|
471
|
+
return;
|
|
472
|
+
_2.unset(obj, path);
|
|
473
|
+
const parentPath = path.slice(0, -1);
|
|
474
|
+
const parent = parentPath.length == 0 ? obj : _2.get(obj, parentPath);
|
|
475
|
+
if (_2.isEmpty(parent)) {
|
|
476
|
+
return unset(obj, parentPath);
|
|
477
|
+
} else {
|
|
478
|
+
return path;
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
var updateObject = (obj, modifier) => {
|
|
482
|
+
_2.forEach(modifier, (value, topic) => {
|
|
483
|
+
const path = topicToPath2(topic);
|
|
484
|
+
if (value == null) {
|
|
485
|
+
unset(obj, path);
|
|
486
|
+
} else {
|
|
487
|
+
_2.set(obj, path, value);
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
return obj;
|
|
491
|
+
};
|
|
492
|
+
var selectFromObject = (obj, path) => {
|
|
493
|
+
if (path.length == 0)
|
|
494
|
+
return;
|
|
495
|
+
const next = path[0];
|
|
496
|
+
if (next) {
|
|
497
|
+
for (let key in obj) {
|
|
498
|
+
if (key != next && next != "*" && !next.startsWith("+")) {
|
|
499
|
+
delete obj[key];
|
|
500
|
+
} else {
|
|
501
|
+
selectFromObject(obj[key], path.slice(1));
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
};
|
|
506
|
+
var DataCache = class {
|
|
507
|
+
#data = {};
|
|
508
|
+
#listeners = [];
|
|
509
|
+
#flatListeners = [];
|
|
510
|
+
constructor(data = {}) {
|
|
511
|
+
this.#data = data;
|
|
512
|
+
}
|
|
513
|
+
/** Update the object with the given value at the given path, remove empty;
|
|
514
|
+
return the flat changes (see toFlatObject). Add `tags` to updates to mark
|
|
515
|
+
them somehow based on the context, e.g., so that some subscriptions can choose
|
|
516
|
+
to ignore updates with a certain tag.
|
|
517
|
+
*/
|
|
518
|
+
updateFromArray(path, value, tags = {}) {
|
|
519
|
+
const current = _2.get(this.#data, path);
|
|
520
|
+
if (value == null) {
|
|
521
|
+
if (current === void 0 || current === null) {
|
|
522
|
+
return {};
|
|
523
|
+
} else {
|
|
524
|
+
unset(this.#data, path);
|
|
525
|
+
}
|
|
526
|
+
} else {
|
|
527
|
+
if (_2.eq(current, value)) {
|
|
528
|
+
return {};
|
|
529
|
+
}
|
|
530
|
+
_2.set(this.#data, path, value);
|
|
531
|
+
}
|
|
532
|
+
const topic = pathToTopic2(path);
|
|
533
|
+
const obj = { [topic]: value };
|
|
534
|
+
let flatChanges;
|
|
535
|
+
if (value instanceof Object) {
|
|
536
|
+
const flatValue = toFlatObject(value);
|
|
537
|
+
flatChanges = {};
|
|
538
|
+
_2.forEach(flatValue, (atomic, flatKey) => {
|
|
539
|
+
flatChanges[`${topic}${flatKey}`] = atomic;
|
|
540
|
+
});
|
|
541
|
+
} else {
|
|
542
|
+
flatChanges = obj;
|
|
543
|
+
}
|
|
544
|
+
this.#listeners.forEach((fn) => fn(obj, tags));
|
|
545
|
+
this.#flatListeners.forEach((fn) => fn(flatChanges, tags));
|
|
546
|
+
return flatChanges;
|
|
547
|
+
}
|
|
548
|
+
/** Update the value at the given path (array or dot separated string) */
|
|
549
|
+
update(path, value, tags) {
|
|
550
|
+
if (typeof path == "string") {
|
|
551
|
+
return this.updateFromTopic(path, value, tags);
|
|
552
|
+
} else if (path instanceof Array) {
|
|
553
|
+
return this.updateFromArray(path, value, tags);
|
|
554
|
+
} else {
|
|
555
|
+
throw new Error("unrecognized path expression");
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
/** Set value from the given topic (with or without leading or trailing slash) */
|
|
559
|
+
updateFromTopic(topic, value, tags) {
|
|
560
|
+
return this.updateFromArray(topicToPath2(topic), value, tags);
|
|
561
|
+
}
|
|
562
|
+
/** Update data from a modifier object where keys are topic names to be
|
|
563
|
+
interpreted as paths, and values are the values to set */
|
|
564
|
+
updateFromModifier(modifier, tags) {
|
|
565
|
+
return _2.map(modifier, (value, topic) => this.updateFromTopic(topic, value, tags));
|
|
566
|
+
}
|
|
567
|
+
/** Add a callback for all change events. */
|
|
568
|
+
subscribe(callback) {
|
|
569
|
+
if (callback instanceof Function) {
|
|
570
|
+
this.#listeners.push(callback);
|
|
571
|
+
} else {
|
|
572
|
+
console.warn("DataCache.subscribe expects a function as argument. Did you mean to use subscribePath?");
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
/** Subscribe to a specific topic only. Callback receives
|
|
576
|
+
`value, key, matched, tags`. */
|
|
577
|
+
subscribePath(topic, callback) {
|
|
578
|
+
this.#listeners.push((changes, tags) => {
|
|
579
|
+
_2.forEach(changes, (value, key) => {
|
|
580
|
+
const matched = topicMatch(topic, key);
|
|
581
|
+
matched && callback(value, key, matched, tags);
|
|
582
|
+
});
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
/** Same as subscribePath but always get all changes in flat form */
|
|
586
|
+
subscribePathFlat(topic, callback) {
|
|
587
|
+
this.#flatListeners.push((changes, tags) => {
|
|
588
|
+
_2.forEach(changes, (value, key) => {
|
|
589
|
+
const matched = topicMatch(topic, key);
|
|
590
|
+
matched && callback(value, key, matched, tags);
|
|
591
|
+
});
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
/** Remove a callback previously registered using `subscribe`. */
|
|
595
|
+
unsubscribe(callback) {
|
|
596
|
+
this.#listeners = this.#listeners.filter((f) => f != callback);
|
|
597
|
+
}
|
|
598
|
+
/** Get sub-value at path, or entire object if none given */
|
|
599
|
+
get(path = []) {
|
|
600
|
+
return path.length == 0 ? this.#data : _2.get(this.#data, path);
|
|
601
|
+
}
|
|
602
|
+
/** Get sub-value specified by topic */
|
|
603
|
+
getByTopic(topic) {
|
|
604
|
+
return this.get(topicToPath2(topic));
|
|
605
|
+
}
|
|
606
|
+
/** Filter the object using path with wildcards */
|
|
607
|
+
filter(path) {
|
|
608
|
+
const rtv = JSON.parse(JSON.stringify(this.get()));
|
|
609
|
+
selectFromObject(rtv, path);
|
|
610
|
+
return rtv;
|
|
611
|
+
}
|
|
612
|
+
/** Filter the object using topic with wildcards */
|
|
613
|
+
filterByTopic(topic) {
|
|
614
|
+
return this.filter(topicToPath2(topic));
|
|
615
|
+
}
|
|
616
|
+
/** For each topic match, invoke the callback with the value, topic, and match
|
|
617
|
+
just like subscribePath, but on the current data rather than future changes. */
|
|
618
|
+
forMatch(topic, callback) {
|
|
619
|
+
const path = topicToPath2(topic);
|
|
620
|
+
this.forPathMatch(path, callback);
|
|
621
|
+
}
|
|
622
|
+
/** For each path match, invoke the callback with the value, topic, and match
|
|
623
|
+
just like subscribePath */
|
|
624
|
+
forPathMatch(path, callback) {
|
|
625
|
+
forMatchIterator(this.get(), path, callback);
|
|
626
|
+
}
|
|
627
|
+
};
|
|
628
|
+
module2.exports = {
|
|
629
|
+
DataCache,
|
|
630
|
+
updateObject
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
});
|
|
634
|
+
|
|
635
|
+
// ../common/MqttSync.js
|
|
636
|
+
var require_MqttSync = __commonJS({
|
|
637
|
+
"../common/MqttSync.js"(exports, module2) {
|
|
638
|
+
"use strict";
|
|
639
|
+
var {
|
|
640
|
+
mqttParsePayload,
|
|
641
|
+
topicMatch,
|
|
642
|
+
topicToPath: topicToPath2,
|
|
643
|
+
pathToTopic: pathToTopic2,
|
|
644
|
+
toFlatObject,
|
|
645
|
+
getLogger: getLogger2,
|
|
646
|
+
mergeVersions: mergeVersions2,
|
|
647
|
+
parseMQTTTopic,
|
|
648
|
+
isSubTopicOf,
|
|
649
|
+
versionCompare,
|
|
650
|
+
encodeTopicElement,
|
|
651
|
+
visitAncestor
|
|
652
|
+
} = require_common();
|
|
653
|
+
var { DataCache } = require_DataCache();
|
|
654
|
+
var _2 = require("lodash");
|
|
655
|
+
var log2 = getLogger2("MqttSync");
|
|
656
|
+
var HEARTBEAT_TOPIC = "$SYS/broker/uptime";
|
|
657
|
+
var specialKey = "$_";
|
|
658
|
+
var noop = () => {
|
|
659
|
+
};
|
|
660
|
+
var clone2 = (payload) => {
|
|
661
|
+
if (typeof payload == "object") {
|
|
662
|
+
return JSON.parse(JSON.stringify(payload));
|
|
663
|
+
} else {
|
|
664
|
+
return payload;
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
var ensureHashSuffix = (topic) => topic.endsWith("/#") ? topic : topic.endsWith("/") ? topic.concat("#") : topic.concat("/#");
|
|
668
|
+
var resolveDoubleSlashes = (path) => path.replace(/\/\//g, "/");
|
|
669
|
+
var MqttSync3 = class {
|
|
670
|
+
data = new DataCache();
|
|
671
|
+
/* Directory of paths we've subscribed to in this class; this matters
|
|
672
|
+
because the same mqtt client may have subscriptions to paths that we don't
|
|
673
|
+
care to store (sync). */
|
|
674
|
+
subscribedPaths = {};
|
|
675
|
+
publishedPaths = {};
|
|
676
|
+
// not used in atomic mode
|
|
677
|
+
/* Store messages retained on mqtt so we can publish what is necessary to
|
|
678
|
+
achieve the "should-be" state. Note that we cannot use a structured document
|
|
679
|
+
for storing these publishedMessages since we need to be able to store separate
|
|
680
|
+
values at non-leaf nodes in the object (just like mqtt, where you can have
|
|
681
|
+
/a/b = 1 and /a/b/c = 1 at the same time). Note: not used in atomic mode.
|
|
682
|
+
Note: we use specialKey in this DataCache to allow overlapping
|
|
683
|
+
topics (e.g., `/a/b/$_ = 1` and `/a/$_ = {b: 2}`)
|
|
684
|
+
*/
|
|
685
|
+
publishedMessages = new DataCache();
|
|
686
|
+
/* The order in which we send retained messages matters, which is why we use
|
|
687
|
+
a queue for sending things. Note that we here use the property of Map that it
|
|
688
|
+
remembers insertion order of keys. */
|
|
689
|
+
publishQueue = /* @__PURE__ */ new Map();
|
|
690
|
+
/* List of callbacks waiting for next heartbeat, gets purged with each
|
|
691
|
+
heartbeat */
|
|
692
|
+
heartbeatWaitersOnce = [];
|
|
693
|
+
heartbeats = 0;
|
|
694
|
+
beforeDisconnectHooks = [];
|
|
695
|
+
constructor({
|
|
696
|
+
mqttClient,
|
|
697
|
+
onChange,
|
|
698
|
+
ignoreRetain,
|
|
699
|
+
migrate,
|
|
700
|
+
onReady,
|
|
701
|
+
sliceTopic,
|
|
702
|
+
onHeartbeatGranted
|
|
703
|
+
}) {
|
|
704
|
+
this.mqtt = mqttClient;
|
|
705
|
+
this.mqtt.on("message", (topic, payload, packet) => {
|
|
706
|
+
const payloadString = payload && payload.toString();
|
|
707
|
+
log2.debug(
|
|
708
|
+
"got message",
|
|
709
|
+
topic,
|
|
710
|
+
payloadString.slice(0, 180),
|
|
711
|
+
payloadString.length > 180 ? `... (${payloadString.length} bytes)` : "",
|
|
712
|
+
packet.retain
|
|
713
|
+
);
|
|
714
|
+
if (topic == HEARTBEAT_TOPIC) {
|
|
715
|
+
if (this.heartbeats > 0) {
|
|
716
|
+
this.heartbeatWaitersOnce.forEach((cb) => cb());
|
|
717
|
+
this.heartbeatWaitersOnce = [];
|
|
718
|
+
}
|
|
719
|
+
if (this.heartbeats == 1 && !migrate && onReady)
|
|
720
|
+
onReady();
|
|
721
|
+
this.heartbeats++;
|
|
722
|
+
} else if (packet.retain || ignoreRetain) {
|
|
723
|
+
let path = topicToPath2(topic);
|
|
724
|
+
log2.debug("processing message", topic, path);
|
|
725
|
+
if (sliceTopic) {
|
|
726
|
+
path = path.slice(sliceTopic);
|
|
727
|
+
topic = pathToTopic2(path);
|
|
728
|
+
}
|
|
729
|
+
const json = mqttParsePayload(payload);
|
|
730
|
+
if (this.isPublished(topic)) {
|
|
731
|
+
this.publishedMessages.updateFromArray([...path, specialKey], json);
|
|
732
|
+
this.data.update(topic, json, { external: true });
|
|
733
|
+
} else if (this.isSubscribed(topic)) {
|
|
734
|
+
log2.debug("applying received update", topic);
|
|
735
|
+
const changes = this.data.update(topic, json);
|
|
736
|
+
onChange && Object.keys(changes).length > 0 && onChange(changes);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
});
|
|
740
|
+
this.mqtt.subscribe(HEARTBEAT_TOPIC, { rap: true }, (err, granted) => {
|
|
741
|
+
log2.debug(HEARTBEAT_TOPIC, { granted });
|
|
742
|
+
granted && granted.length > 0 && onHeartbeatGranted?.();
|
|
743
|
+
});
|
|
744
|
+
migrate?.length > 0 && this.migrate(migrate, () => {
|
|
745
|
+
log2.debug("done migrating", onReady);
|
|
746
|
+
onReady && this.waitForHeartbeatOnce(onReady);
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* Publish all values at the given level of the given object under the given
|
|
751
|
+
* topic (plus sub-key, of course).
|
|
752
|
+
* TODO: Is this OK, or do we need to go through this.publish?
|
|
753
|
+
*/
|
|
754
|
+
publishAtLevel(topic, value, level) {
|
|
755
|
+
log2.debug(`publishingAtLevel ${level}`, topic, value);
|
|
756
|
+
if (level > 0) {
|
|
757
|
+
_2.forEach(value, (subValue, subKey) => {
|
|
758
|
+
const subTopic = `${topic}/${encodeTopicElement(subKey)}`;
|
|
759
|
+
log2.debug(`publishing ${subTopic}`);
|
|
760
|
+
this.publishAtLevel(subTopic, subValue, level - 1);
|
|
761
|
+
});
|
|
762
|
+
} else {
|
|
763
|
+
this.mqtt.publish(topic, JSON.stringify(value), { retain: true }, (err) => {
|
|
764
|
+
err && log2.warn("Error when publishing migration result", err);
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
/** Migrate a list of `{topic, newVersion, transform}`. The version number in
|
|
769
|
+
topic will be ignored, and all versions' values will be merged, applied in
|
|
770
|
+
order, such that the latest version is applied last. */
|
|
771
|
+
migrate(list, onReady = void 0) {
|
|
772
|
+
let toGo = list.length;
|
|
773
|
+
if (toGo == 0) {
|
|
774
|
+
onReady && onReady();
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
const oneDown = () => --toGo == 0 && onReady && onReady();
|
|
778
|
+
list.forEach(({
|
|
779
|
+
topic,
|
|
780
|
+
newVersion,
|
|
781
|
+
transform = void 0,
|
|
782
|
+
flat = false,
|
|
783
|
+
level = 0
|
|
784
|
+
}) => {
|
|
785
|
+
log2.debug("migrating", topic, newVersion);
|
|
786
|
+
const { organization, device, capability, sub } = parseMQTTTopic(topic);
|
|
787
|
+
const prefix = `/${organization}/${device}/${capability}`;
|
|
788
|
+
const suffix = sub.length == 0 ? "/#" : pathToTopic2(sub);
|
|
789
|
+
const subTopic = `${prefix}/+${suffix}`;
|
|
790
|
+
this.subscribe(subTopic, (err) => {
|
|
791
|
+
if (err) {
|
|
792
|
+
log2.warn("Error during migration", err);
|
|
793
|
+
oneDown();
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
this.waitForHeartbeatOnce(() => {
|
|
797
|
+
log2.debug("got heartbeat", topic, subTopic);
|
|
798
|
+
const all = this.data.getByTopic(prefix);
|
|
799
|
+
if (!all) {
|
|
800
|
+
this.unsubscribe(subTopic);
|
|
801
|
+
oneDown();
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
804
|
+
const merged = mergeVersions2(all, suffix, { maxVersion: newVersion });
|
|
805
|
+
const suffixMergedValue = _2.get(merged, topicToPath2(suffix));
|
|
806
|
+
const transformed = transform ? transform(suffixMergedValue) : suffixMergedValue;
|
|
807
|
+
const newTopic = resolveDoubleSlashes(`${prefix}/${newVersion}/${suffix}`);
|
|
808
|
+
log2.debug("publishing merged", newTopic);
|
|
809
|
+
if (flat) {
|
|
810
|
+
const flatObj = toFlatObject(transformed);
|
|
811
|
+
const newPath = topicToPath2(newTopic);
|
|
812
|
+
_2.forEach(flatObj, (value, key) => {
|
|
813
|
+
const keyTopic = pathToTopic2(newPath.concat(topicToPath2(key)));
|
|
814
|
+
this.mqtt.publish(
|
|
815
|
+
keyTopic,
|
|
816
|
+
JSON.stringify(value),
|
|
817
|
+
{ retain: true },
|
|
818
|
+
(err2) => {
|
|
819
|
+
err2 && log2.warn(
|
|
820
|
+
`Error when publishing migration result for ${key}`,
|
|
821
|
+
err2
|
|
822
|
+
);
|
|
823
|
+
}
|
|
824
|
+
);
|
|
825
|
+
});
|
|
826
|
+
} else {
|
|
827
|
+
this.publishAtLevel(newTopic, transformed, level);
|
|
828
|
+
}
|
|
829
|
+
this.unsubscribe(subTopic);
|
|
830
|
+
this.waitForHeartbeatOnce(() => {
|
|
831
|
+
const oldVersions = Object.keys(all).filter((v) => versionCompare(v, newVersion) < 0);
|
|
832
|
+
const prefixesToClear = oldVersions.map((oldV) => resolveDoubleSlashes(`${prefix}/${oldV}/${suffix}`));
|
|
833
|
+
log2.debug({ prefixesToClear });
|
|
834
|
+
this.clear(prefixesToClear);
|
|
835
|
+
oneDown();
|
|
836
|
+
});
|
|
837
|
+
});
|
|
838
|
+
});
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
/** Delete all retained messages in a certain topic prefix, waiting for
|
|
842
|
+
a mqtt broker heartbeat to collect existing retained. Use with care, never
|
|
843
|
+
delete topics not owned by us. Harmless within capabilities, which are
|
|
844
|
+
namespaced already.
|
|
845
|
+
|
|
846
|
+
`options.filter(topic)`: a function that can be provided to further,
|
|
847
|
+
programmatically filter the set of topics to clear, e.g., to onlt clear
|
|
848
|
+
topics of old versions.
|
|
849
|
+
|
|
850
|
+
Note: This may not yet work in robot-capabilities, since the subscription
|
|
851
|
+
prefix and received topic prefix don't match (the device prefix is added to
|
|
852
|
+
subscription by localMQTT.
|
|
853
|
+
*/
|
|
854
|
+
clear(prefixes, callback = void 0, options = {}) {
|
|
855
|
+
const toDelete = [];
|
|
856
|
+
const collectToDelete = (topic) => {
|
|
857
|
+
prefixes.forEach(
|
|
858
|
+
(prefix) => topicMatch(`${prefix}/#`, topic) && (!options.filter || options.filter(topic)) && toDelete.push(topic)
|
|
859
|
+
);
|
|
860
|
+
};
|
|
861
|
+
this.mqtt.on("message", collectToDelete);
|
|
862
|
+
prefixes.forEach((prefix) => {
|
|
863
|
+
if (typeof prefix == "string") {
|
|
864
|
+
this.mqtt.subscribe(`${prefix}/#`);
|
|
865
|
+
} else {
|
|
866
|
+
log2.warn("Ignoring", prefix, "since it is not a string.");
|
|
867
|
+
}
|
|
868
|
+
});
|
|
869
|
+
const nullValue = typeof Buffer != "undefined" ? Buffer.alloc(0) : null;
|
|
870
|
+
this.waitForHeartbeatOnce(() => {
|
|
871
|
+
this.mqtt.removeListener("message", collectToDelete);
|
|
872
|
+
prefixes.forEach((prefix) => this.mqtt.unsubscribe(prefix));
|
|
873
|
+
const count = toDelete.length;
|
|
874
|
+
log2.debug(`clearing ${count} retained messages from ${prefixes}`);
|
|
875
|
+
toDelete.forEach((topic) => {
|
|
876
|
+
this.mqtt.publish(topic, nullValue, { retain: true });
|
|
877
|
+
});
|
|
878
|
+
callback && callback(count);
|
|
879
|
+
});
|
|
880
|
+
}
|
|
881
|
+
/** register a callback for the next heartbeat from the broker */
|
|
882
|
+
waitForHeartbeatOnce(callback) {
|
|
883
|
+
setTimeout(() => this.heartbeatWaitersOnce.push(callback), 1);
|
|
884
|
+
}
|
|
885
|
+
/** check whether we are subscribed to the given topic */
|
|
886
|
+
isSubscribed(topic) {
|
|
887
|
+
return Object.keys(this.subscribedPaths).some((subscribedTopic) => topicMatch(subscribedTopic, topic));
|
|
888
|
+
}
|
|
889
|
+
/** Check whether we are publishing the given topic in a non-atomic way.
|
|
890
|
+
This is used to determine whether to store the published value or not. */
|
|
891
|
+
isPublished(topic) {
|
|
892
|
+
return Object.keys(this.publishedPaths).some(
|
|
893
|
+
(subscribedTopic) => topicMatch(subscribedTopic, topic) && !this.publishedPaths[subscribedTopic].atomic
|
|
894
|
+
);
|
|
895
|
+
}
|
|
896
|
+
/** Subscribe to the given topic (and all sub-topics). The callback will
|
|
897
|
+
indicate success/failure, *not* a message on the topic. */
|
|
898
|
+
subscribe(topic, callback = noop) {
|
|
899
|
+
topic = ensureHashSuffix(topic);
|
|
900
|
+
log2.debug("subscribing to", topic);
|
|
901
|
+
if (this.subscribedPaths[topic]) {
|
|
902
|
+
log2.debug("already subscribed to", topic);
|
|
903
|
+
callback();
|
|
904
|
+
return;
|
|
905
|
+
}
|
|
906
|
+
this.mqtt.subscribe(topic, { rap: true }, (err, granted) => {
|
|
907
|
+
log2.debug("subscribe", topic, "granted:", granted);
|
|
908
|
+
if (granted && granted.some((grant) => grant.topic == topic && grant.qos < 128)) {
|
|
909
|
+
this.subscribedPaths[topic] = 1;
|
|
910
|
+
callback(null);
|
|
911
|
+
} else {
|
|
912
|
+
callback(`not permitted to subscribe to topic ${topic}, ${JSON.stringify(granted)}`);
|
|
913
|
+
}
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
unsubscribe(topic) {
|
|
917
|
+
topic = ensureHashSuffix(topic);
|
|
918
|
+
if (this.subscribedPaths[topic]) {
|
|
919
|
+
this.mqtt.unsubscribe(topic);
|
|
920
|
+
delete this.subscribedPaths[topic];
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
/** Publish retained to MQTT, store as published, and return a promise */
|
|
924
|
+
_actuallyPublish(topic, value) {
|
|
925
|
+
if (!this.mqtt.connected) {
|
|
926
|
+
log2.warn("not connected, not publishing", topic);
|
|
927
|
+
return false;
|
|
928
|
+
}
|
|
929
|
+
log2.debug("actually publishing", topic);
|
|
930
|
+
this.mqtt.publish(
|
|
931
|
+
topic,
|
|
932
|
+
value == null ? null : JSON.stringify(value),
|
|
933
|
+
// aka "unparse payload"
|
|
934
|
+
{ retain: true }
|
|
935
|
+
);
|
|
936
|
+
return true;
|
|
937
|
+
}
|
|
938
|
+
/** Send all items in the queue in sequence, if any and if not already
|
|
939
|
+
running. */
|
|
940
|
+
// async _processQueue() {
|
|
941
|
+
// if (this._processing) return; // already running (and probably waiting)
|
|
942
|
+
//
|
|
943
|
+
// this._processing = true;
|
|
944
|
+
// while (this.publishQueue.length > 0) {
|
|
945
|
+
// const {topic, value} = this.publishQueue.shift();
|
|
946
|
+
// await this._actuallyPublish(topic, value);
|
|
947
|
+
// }
|
|
948
|
+
// this._processing = false;
|
|
949
|
+
// }
|
|
950
|
+
// when using Map
|
|
951
|
+
_processQueue_rec(cb) {
|
|
952
|
+
if (this.publishQueue.size > 0) {
|
|
953
|
+
const [topic, value] = this.publishQueue.entries().next().value;
|
|
954
|
+
if (this._actuallyPublish(topic, value)) {
|
|
955
|
+
this.publishQueue.delete(topic);
|
|
956
|
+
this._processQueue_rec(cb);
|
|
957
|
+
} else {
|
|
958
|
+
setTimeout(() => this._processQueue_rec(cb), 5e3);
|
|
959
|
+
}
|
|
960
|
+
} else {
|
|
961
|
+
cb();
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
_processQueue() {
|
|
965
|
+
if (this._processing)
|
|
966
|
+
return;
|
|
967
|
+
this._processing = true;
|
|
968
|
+
this._processQueue_rec(() => this._processing = false);
|
|
969
|
+
}
|
|
970
|
+
/** Set delay between processing of publishing queue in milliseconds. This
|
|
971
|
+
allows you to effectively throttle the rate at which this instance will
|
|
972
|
+
publish changes. Note that updates to a topic already in the queue will not
|
|
973
|
+
cause multiple publications. Only the latest value will be published.
|
|
974
|
+
@param {number} [delay] - Number of milliseconds to wait between processing
|
|
975
|
+
of publish queue.
|
|
976
|
+
*/
|
|
977
|
+
setThrottle(delay) {
|
|
978
|
+
this._processQueueThrottled = _2.throttle(this._processQueue.bind(this), delay);
|
|
979
|
+
}
|
|
980
|
+
/** Clear the set throttling delay. */
|
|
981
|
+
clearThrottle() {
|
|
982
|
+
delete this._processQueueThrottled;
|
|
983
|
+
}
|
|
984
|
+
addToQueue(topic, value) {
|
|
985
|
+
this.publishQueue.set(topic, value);
|
|
986
|
+
}
|
|
987
|
+
/** Add to publication queue */
|
|
988
|
+
_enqueue(topic, value) {
|
|
989
|
+
log2.debug("enqueuing", topic);
|
|
990
|
+
this.addToQueue(topic, value);
|
|
991
|
+
if (this._processQueueThrottled) {
|
|
992
|
+
this._processQueueThrottled();
|
|
993
|
+
} else {
|
|
994
|
+
this._processQueue();
|
|
995
|
+
}
|
|
996
|
+
const path = topicToPath2(topic);
|
|
997
|
+
this.publishedMessages.updateFromArray(
|
|
998
|
+
[...path, specialKey],
|
|
999
|
+
value == null ? null : clone2(value)
|
|
1000
|
+
);
|
|
1001
|
+
}
|
|
1002
|
+
/** Register a listener for path in data. Make sure to populate the data
|
|
1003
|
+
before calling this or set the data all at once afterwards.
|
|
1004
|
+
|
|
1005
|
+
With option "atomic" this will always send the whole sub-document,
|
|
1006
|
+
not flat changes. Useful, e.g., for desiredPackages, see
|
|
1007
|
+
https://github.com/chfritz/transitive/issues/85.
|
|
1008
|
+
|
|
1009
|
+
@return true if publication added (false, e.g., when already present)
|
|
1010
|
+
*/
|
|
1011
|
+
publish(topic, options = { atomic: false }) {
|
|
1012
|
+
topic = ensureHashSuffix(topic);
|
|
1013
|
+
if (_2.isEqual(this.publishedPaths[topic], options)) {
|
|
1014
|
+
return false;
|
|
1015
|
+
}
|
|
1016
|
+
this.publishedPaths[topic] = options;
|
|
1017
|
+
if (options.atomic) {
|
|
1018
|
+
this.data.subscribePath(topic, (value, key, matched, tags) => {
|
|
1019
|
+
if (tags?.external)
|
|
1020
|
+
return;
|
|
1021
|
+
log2.debug("processing change (atomic)", key, topic);
|
|
1022
|
+
const topicWithoutHash = topic.slice(0, topic.length - 2);
|
|
1023
|
+
const groundedTopic = pathToTopic2(
|
|
1024
|
+
// get length of topic (how many levels of selectors), get that many
|
|
1025
|
+
// levels from key prefix
|
|
1026
|
+
topicToPath2(key).slice(0, topicToPath2(topicWithoutHash).length)
|
|
1027
|
+
);
|
|
1028
|
+
this._enqueue(groundedTopic, this.data.getByTopic(groundedTopic));
|
|
1029
|
+
});
|
|
1030
|
+
return true;
|
|
1031
|
+
}
|
|
1032
|
+
this.mqtt.subscribe(topic);
|
|
1033
|
+
this.data.subscribePath(topic, (value, key, matched, tags) => {
|
|
1034
|
+
if (tags?.external)
|
|
1035
|
+
return;
|
|
1036
|
+
log2.debug("processing change", key);
|
|
1037
|
+
const path = topicToPath2(key);
|
|
1038
|
+
const publishedSub = this.publishedMessages.get(path);
|
|
1039
|
+
_2.each(publishedSub, (oldSubVal, oldSubKey) => {
|
|
1040
|
+
if (oldSubKey == specialKey)
|
|
1041
|
+
return true;
|
|
1042
|
+
const toClear = Object.keys(toFlatObject(oldSubVal)).filter((subkey) => subkey.endsWith(specialKey));
|
|
1043
|
+
log2.debug("flat->atomic: ", { toClear }, oldSubKey);
|
|
1044
|
+
toClear.forEach((oldSubSubKey) => {
|
|
1045
|
+
const oldKey = oldSubSubKey.slice(0, -(specialKey.length + 1));
|
|
1046
|
+
const clearKey = `${key}/${oldSubKey}/${oldKey}`;
|
|
1047
|
+
this._enqueue(clearKey, null);
|
|
1048
|
+
});
|
|
1049
|
+
});
|
|
1050
|
+
const published = this.publishedMessages.get();
|
|
1051
|
+
visitAncestor(published, path.slice(0, -1), (subObj, prefix) => {
|
|
1052
|
+
const oldVal = subObj[specialKey];
|
|
1053
|
+
if (oldVal && _2.isObject(oldVal)) {
|
|
1054
|
+
log2.debug("atomic->flat", { oldVal });
|
|
1055
|
+
const prefixTopic = pathToTopic2(prefix);
|
|
1056
|
+
this._enqueue(prefixTopic, null);
|
|
1057
|
+
const flat = toFlatObject(oldVal);
|
|
1058
|
+
_2.each(flat, (flatValue, flatKey) => {
|
|
1059
|
+
const oldFlatKey = `${prefixTopic}${flatKey}`;
|
|
1060
|
+
this._enqueue(oldFlatKey, flatValue);
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
});
|
|
1064
|
+
this._enqueue(key, value);
|
|
1065
|
+
return true;
|
|
1066
|
+
});
|
|
1067
|
+
}
|
|
1068
|
+
/** Run all registered hooks before disconnecting */
|
|
1069
|
+
beforeDisconnect() {
|
|
1070
|
+
this.beforeDisconnectHooks.forEach((fn) => fn(this));
|
|
1071
|
+
}
|
|
1072
|
+
/** register a new hook to be called before disconnecting */
|
|
1073
|
+
onBeforeDisconnect(fn) {
|
|
1074
|
+
this.beforeDisconnectHooks.push(fn);
|
|
1075
|
+
}
|
|
1076
|
+
};
|
|
1077
|
+
module2.exports = MqttSync3;
|
|
1078
|
+
}
|
|
1079
|
+
});
|
|
1080
|
+
|
|
1081
|
+
// index.js
|
|
1082
|
+
var web_exports = {};
|
|
1083
|
+
__export(web_exports, {
|
|
1084
|
+
CapabilityContext: () => CapabilityContext,
|
|
1085
|
+
CapabilityContextProvider: () => CapabilityContextProvider,
|
|
1086
|
+
Code: () => Code,
|
|
1087
|
+
ErrorBoundary: () => ErrorBoundary,
|
|
1088
|
+
InlineCode: () => InlineCode,
|
|
1089
|
+
LevelBadge: () => LevelBadge,
|
|
1090
|
+
MqttSync: () => MqttSync,
|
|
1091
|
+
Timer: () => Timer,
|
|
1092
|
+
TimerContext: () => TimerContext,
|
|
1093
|
+
TransitiveCapability: () => TransitiveCapability,
|
|
1094
|
+
createWebComponent: () => createWebComponent,
|
|
1095
|
+
fetchJson: () => fetchJson,
|
|
1096
|
+
parseCookie: () => parseCookie,
|
|
1097
|
+
useCapability: () => useCapability,
|
|
1098
|
+
useMqttSync: () => useMqttSync,
|
|
1099
|
+
useTopics: () => useTopics,
|
|
1100
|
+
useTransitive: () => useTransitive
|
|
1101
|
+
});
|
|
1102
|
+
module.exports = __toCommonJS(web_exports);
|
|
1103
|
+
|
|
1104
|
+
// client/shared.jsx
|
|
1105
|
+
var import_react2 = __toESM(require("react"));
|
|
1106
|
+
var import_react_bootstrap = require("react-bootstrap");
|
|
1107
|
+
var import_react_web_component = __toESM(require_react_web_component());
|
|
1108
|
+
|
|
1109
|
+
// client/client.js
|
|
1110
|
+
var client_exports = {};
|
|
1111
|
+
__export(client_exports, {
|
|
1112
|
+
MqttSync: () => MqttSync,
|
|
1113
|
+
fetchJson: () => fetchJson,
|
|
1114
|
+
parseCookie: () => parseCookie
|
|
1115
|
+
});
|
|
1116
|
+
__reExport(client_exports, __toESM(require_common()));
|
|
1117
|
+
__reExport(client_exports, __toESM(require_DataCache()));
|
|
1118
|
+
var import_MqttSync = __toESM(require_MqttSync());
|
|
1119
|
+
var MqttSync = import_MqttSync.default;
|
|
1120
|
+
var parseCookie = (str) => str.split(";").map((v) => v.split("=")).reduce((acc, v) => {
|
|
1121
|
+
acc[decodeURIComponent(v[0].trim())] = v[1] && decodeURIComponent(v[1].trim());
|
|
1122
|
+
return acc;
|
|
1123
|
+
}, {});
|
|
1124
|
+
var fetchJson = (url, callback, options = {}) => {
|
|
1125
|
+
fetch(url, {
|
|
1126
|
+
method: options.method || (options.body ? "post" : "get"),
|
|
1127
|
+
mode: "cors",
|
|
1128
|
+
cache: "no-cache",
|
|
1129
|
+
// Maybe we'll need this (when embedding)?
|
|
1130
|
+
// credentials: 'same-origin', // include, *same-origin, omit
|
|
1131
|
+
headers: {
|
|
1132
|
+
"Content-Type": "application/json",
|
|
1133
|
+
...options.headers
|
|
1134
|
+
},
|
|
1135
|
+
redirect: "follow",
|
|
1136
|
+
referrerPolicy: "no-referrer",
|
|
1137
|
+
body: options.body ? JSON.stringify(options.body) : void 0
|
|
1138
|
+
}).then((res) => {
|
|
1139
|
+
const error = !res.ok && `fetching ${url} failed: ${res.status} ${res.statusText}`;
|
|
1140
|
+
res.json().then((data) => callback(error, data)).catch((err) => {
|
|
1141
|
+
throw new Error(err);
|
|
1142
|
+
});
|
|
1143
|
+
}).catch((error) => callback(`error: ${error}`));
|
|
1144
|
+
};
|
|
1145
|
+
|
|
1146
|
+
// client/hooks.jsx
|
|
1147
|
+
var import_react = __toESM(require("react"));
|
|
1148
|
+
var import_lodash = __toESM(require("lodash"));
|
|
1149
|
+
var import_mqtt_browser = __toESM(require("mqtt-browser"));
|
|
1150
|
+
var MqttSync2 = require_MqttSync();
|
|
1151
|
+
var log = (0, client_exports.getLogger)("utils-web/hooks");
|
|
1152
|
+
log.setLevel("info");
|
|
1153
|
+
log.setLevel("debug");
|
|
1154
|
+
var useMqttSync = ({ jwt, id, mqttUrl, appReact }) => {
|
|
1155
|
+
const { useState: useState3, useRef: useRef2, useEffect: useEffect3 } = appReact || import_react.default;
|
|
1156
|
+
const [status, setStatus] = useState3("connecting");
|
|
1157
|
+
const [mqttSync, setMqttSync] = useState3();
|
|
1158
|
+
const [data, setData] = useState3({});
|
|
1159
|
+
const [heartbeatGranted, setHeartbeatGranted] = useState3(false);
|
|
1160
|
+
useEffect3(() => {
|
|
1161
|
+
const payload = (0, client_exports.decodeJWT)(jwt);
|
|
1162
|
+
const client = import_mqtt_browser.default.connect(mqttUrl, {
|
|
1163
|
+
username: JSON.stringify({ id, payload }),
|
|
1164
|
+
password: jwt
|
|
1165
|
+
});
|
|
1166
|
+
client.on("connect", () => {
|
|
1167
|
+
log.debug("connected");
|
|
1168
|
+
const mqttSyncClient = new MqttSync2({
|
|
1169
|
+
mqttClient: client,
|
|
1170
|
+
ignoreRetain: true,
|
|
1171
|
+
onHeartbeatGranted: () => setHeartbeatGranted(true)
|
|
1172
|
+
});
|
|
1173
|
+
setMqttSync(mqttSyncClient);
|
|
1174
|
+
setStatus("connected");
|
|
1175
|
+
mqttSyncClient.data.subscribe(import_lodash.default.throttle(() => setData((0, client_exports.clone)(mqttSyncClient.data.get())), 50));
|
|
1176
|
+
});
|
|
1177
|
+
client.on("error", (error) => {
|
|
1178
|
+
log.error(error);
|
|
1179
|
+
setStatus(`error: ${error}`);
|
|
1180
|
+
});
|
|
1181
|
+
return () => {
|
|
1182
|
+
log.info("cleaning up useMQTTSync");
|
|
1183
|
+
if (mqttSync && mqttSync.beforeDisconnect) {
|
|
1184
|
+
mqttSync.beforeDisconnect();
|
|
1185
|
+
mqttSync.waitForHeartbeatOnce(() => client.end());
|
|
1186
|
+
} else {
|
|
1187
|
+
client.end();
|
|
1188
|
+
}
|
|
1189
|
+
};
|
|
1190
|
+
}, [jwt, id]);
|
|
1191
|
+
return {
|
|
1192
|
+
status,
|
|
1193
|
+
// ready: status == 'connected',
|
|
1194
|
+
ready: heartbeatGranted,
|
|
1195
|
+
StatusComponent: () => /* @__PURE__ */ import_react.default.createElement("div", null, status),
|
|
1196
|
+
mqttSync,
|
|
1197
|
+
// Note: mqttSync.data is not reactive.
|
|
1198
|
+
data
|
|
1199
|
+
// This is a reactive data-source (to use meteor terminology).
|
|
1200
|
+
};
|
|
1201
|
+
};
|
|
1202
|
+
var useTransitive = ({ jwt, id, host, ssl, capability, versionNS, appReact }) => {
|
|
1203
|
+
const [scope, capabilityName] = capability.split("/");
|
|
1204
|
+
const { device } = (0, client_exports.decodeJWT)(jwt);
|
|
1205
|
+
const prefixPath = [id, device, scope, capabilityName];
|
|
1206
|
+
const prefix = (0, client_exports.pathToTopic)(prefixPath);
|
|
1207
|
+
const prefixPathVersion = [...prefixPath, versionNS];
|
|
1208
|
+
const prefixVersion = (0, client_exports.pathToTopic)(prefixPathVersion);
|
|
1209
|
+
const mqttUrl = `${ssl && JSON.parse(ssl) ? "wss" : "ws"}://mqtt.${host}`;
|
|
1210
|
+
const fromMqttSync = useMqttSync({ jwt, id, mqttUrl, appReact });
|
|
1211
|
+
return {
|
|
1212
|
+
...fromMqttSync,
|
|
1213
|
+
device,
|
|
1214
|
+
prefixPath,
|
|
1215
|
+
prefix,
|
|
1216
|
+
prefixPathVersion,
|
|
1217
|
+
prefixVersion
|
|
1218
|
+
};
|
|
1219
|
+
};
|
|
1220
|
+
var useTopics = ({
|
|
1221
|
+
jwt,
|
|
1222
|
+
host = "transitiverobotics.com",
|
|
1223
|
+
ssl = true,
|
|
1224
|
+
topics = [],
|
|
1225
|
+
appReact
|
|
1226
|
+
}) => {
|
|
1227
|
+
log.debug({ appReact });
|
|
1228
|
+
const { useState: useState3, useEffect: useEffect3 } = appReact || import_react.default;
|
|
1229
|
+
const [topicList, setTopicList] = useState3();
|
|
1230
|
+
!import_lodash.default.isEqual(topicList, topics) && setTopicList(topics);
|
|
1231
|
+
const { device, id, capability } = (0, client_exports.decodeJWT)(jwt);
|
|
1232
|
+
if (device == "_fleet") {
|
|
1233
|
+
log.warn("useTopics only works for device JWTs, not _fleet ones");
|
|
1234
|
+
return;
|
|
1235
|
+
}
|
|
1236
|
+
const agentPrefix = `/${id}/${device}/@transitive-robotics/_robot-agent/+/status`;
|
|
1237
|
+
const { mqttSync, data, status, ready, StatusComponent } = useMqttSync({ jwt, id, mqttUrl: `ws${ssl ? "s" : ""}://mqtt.${host}`, appReact });
|
|
1238
|
+
useEffect3(() => {
|
|
1239
|
+
if (ready) {
|
|
1240
|
+
mqttSync.subscribe(agentPrefix, (err) => err && console.warn(err));
|
|
1241
|
+
}
|
|
1242
|
+
}, [mqttSync, ready]);
|
|
1243
|
+
const agentStatus = (0, client_exports.mergeVersions)(
|
|
1244
|
+
data[id]?.[device]["@transitive-robotics"]["_robot-agent"],
|
|
1245
|
+
"status"
|
|
1246
|
+
).status;
|
|
1247
|
+
const runningPackages = agentStatus?.runningPackages;
|
|
1248
|
+
const [scope, capName] = capability.split("/");
|
|
1249
|
+
const versions = runningPackages?.[scope]?.[capName];
|
|
1250
|
+
const runningVersion = versions && Object.values(versions).filter(Boolean)[0];
|
|
1251
|
+
const prefix = `/${id}/${device}/${capability}/${runningVersion}`;
|
|
1252
|
+
useEffect3(() => {
|
|
1253
|
+
log.debug("topics", topics);
|
|
1254
|
+
if (runningVersion) {
|
|
1255
|
+
topics.forEach((topic) => {
|
|
1256
|
+
log.debug(`subscribing to ${prefix}${topic}`);
|
|
1257
|
+
mqttSync.subscribe(
|
|
1258
|
+
`${prefix}${topic}`,
|
|
1259
|
+
(err) => err && log.warn(err)
|
|
1260
|
+
);
|
|
1261
|
+
});
|
|
1262
|
+
}
|
|
1263
|
+
}, [topicList, runningVersion, mqttSync]);
|
|
1264
|
+
const topicData = import_lodash.default.get(data, (0, client_exports.topicToPath)(prefix));
|
|
1265
|
+
return { data: data?.[id]?.[device], mqttSync, agentStatus, topicData };
|
|
1266
|
+
};
|
|
1267
|
+
var listeners = {};
|
|
1268
|
+
var loadedModules = {};
|
|
1269
|
+
var useCapability = ({
|
|
1270
|
+
capability,
|
|
1271
|
+
name,
|
|
1272
|
+
userId,
|
|
1273
|
+
deviceId,
|
|
1274
|
+
host = "transitiverobotics.com",
|
|
1275
|
+
ssl = true,
|
|
1276
|
+
appReact
|
|
1277
|
+
}) => {
|
|
1278
|
+
const { useState: useState3, useEffect: useEffect3 } = appReact || import_react.default;
|
|
1279
|
+
const [returns, setReturns] = useState3({ loaded: false });
|
|
1280
|
+
const done = (message, theModule) => {
|
|
1281
|
+
log.debug(`custom component ${name}: ${message}`);
|
|
1282
|
+
loadedModules[name] = theModule;
|
|
1283
|
+
setReturns((x) => ({ ...x, loadedModule: theModule, loaded: !!theModule }));
|
|
1284
|
+
};
|
|
1285
|
+
const notifyListeners = (...args) => listeners[name].forEach((l) => l(...args));
|
|
1286
|
+
useEffect3(() => {
|
|
1287
|
+
log.debug(`loading custom component ${name}`);
|
|
1288
|
+
if (loadedModules[name]) {
|
|
1289
|
+
return done("already loaded", loadedModules[name]);
|
|
1290
|
+
}
|
|
1291
|
+
if (listeners[name]) {
|
|
1292
|
+
log.debug("already loading");
|
|
1293
|
+
listeners[name].push(done);
|
|
1294
|
+
return;
|
|
1295
|
+
}
|
|
1296
|
+
listeners[name] = [done];
|
|
1297
|
+
const baseUrl = `http${ssl ? "s" : ""}://portal.${host}`;
|
|
1298
|
+
const params = new URLSearchParams({ userId, deviceId });
|
|
1299
|
+
const fileBasename = `${baseUrl}/running/${capability}/dist/${name}`;
|
|
1300
|
+
import(
|
|
1301
|
+
/* webpackIgnore: true */
|
|
1302
|
+
`${fileBasename}.esm.js?${params.toString()}`
|
|
1303
|
+
).then(
|
|
1304
|
+
(esm) => notifyListeners("loaded esm", esm),
|
|
1305
|
+
(error) => {
|
|
1306
|
+
log.warn(`No ESM module found for ${name}, loading iife`, error);
|
|
1307
|
+
import(
|
|
1308
|
+
/* webpackIgnore: true */
|
|
1309
|
+
`${fileBasename}.js?${params.toString()}`
|
|
1310
|
+
).then(
|
|
1311
|
+
(iife) => notifyListeners("loaded iife", iife),
|
|
1312
|
+
(error2) => log.error(`Failed to load ${name} iife`, error2)
|
|
1313
|
+
);
|
|
1314
|
+
}
|
|
1315
|
+
);
|
|
1316
|
+
}, [capability, name, userId, deviceId]);
|
|
1317
|
+
return returns;
|
|
1318
|
+
};
|
|
1319
|
+
|
|
1320
|
+
// client/shared.jsx
|
|
1321
|
+
var styles = {
|
|
1322
|
+
badge: {
|
|
1323
|
+
width: "4em"
|
|
1324
|
+
},
|
|
1325
|
+
code: {
|
|
1326
|
+
color: "#700",
|
|
1327
|
+
borderLeft: "3px solid #aaa",
|
|
1328
|
+
padding: "0.5em 0px 0.5em 2em",
|
|
1329
|
+
backgroundColor: "#f0f0f0",
|
|
1330
|
+
borderRadius: "4px",
|
|
1331
|
+
marginTop: "0.5em"
|
|
1332
|
+
},
|
|
1333
|
+
inlineCode: {
|
|
1334
|
+
color: "#700",
|
|
1335
|
+
margin: "0px 0.5em 0px 0.5em"
|
|
1336
|
+
}
|
|
1337
|
+
};
|
|
1338
|
+
var levelBadges = [
|
|
1339
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_bootstrap.Badge, { bg: "success", style: styles.badge }, "OK"),
|
|
1340
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_bootstrap.Badge, { bg: "warning", style: styles.badge }, "Warn"),
|
|
1341
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_bootstrap.Badge, { bg: "danger", style: styles.badge }, "Error"),
|
|
1342
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_bootstrap.Badge, { bg: "secondary", style: styles.badge }, "Stale")
|
|
1343
|
+
];
|
|
1344
|
+
var LevelBadge = ({ level }) => levelBadges[level] || /* @__PURE__ */ import_react2.default.createElement("span", null, level);
|
|
1345
|
+
var Code = ({ children }) => /* @__PURE__ */ import_react2.default.createElement("pre", { style: styles.code }, children);
|
|
1346
|
+
var InlineCode = ({ children }) => /* @__PURE__ */ import_react2.default.createElement("tt", { style: styles.inlineCode }, children);
|
|
1347
|
+
var intervals = {};
|
|
1348
|
+
var TimerContext = import_react2.default.createContext({});
|
|
1349
|
+
var Timer = ({ duration, onTimeout, onStart, setOnDisconnect, children }) => {
|
|
1350
|
+
duration = duration || 60;
|
|
1351
|
+
const [timer, setTimer] = (0, import_react2.useState)(duration);
|
|
1352
|
+
const [running, setRunning] = (0, import_react2.useState)(false);
|
|
1353
|
+
const id = (0, import_react2.useMemo)(() => Math.random().toString(36).slice(2), []);
|
|
1354
|
+
const stop = () => {
|
|
1355
|
+
console.log("stopping timer for", id);
|
|
1356
|
+
onTimeout && setTimeout(onTimeout, 1);
|
|
1357
|
+
clearInterval(intervals[id]);
|
|
1358
|
+
intervals[id] = null;
|
|
1359
|
+
setRunning(false);
|
|
1360
|
+
};
|
|
1361
|
+
const startTimer = () => {
|
|
1362
|
+
const interval = intervals[id];
|
|
1363
|
+
console.log(interval, intervals, timer);
|
|
1364
|
+
if (!interval && timer > 0) {
|
|
1365
|
+
setRunning(true);
|
|
1366
|
+
intervals[id] = setInterval(() => setTimer((t) => {
|
|
1367
|
+
if (--t > 0) {
|
|
1368
|
+
return t;
|
|
1369
|
+
} else {
|
|
1370
|
+
stop();
|
|
1371
|
+
}
|
|
1372
|
+
}), 1e3);
|
|
1373
|
+
onStart && setTimeout(onStart, 1);
|
|
1374
|
+
}
|
|
1375
|
+
return stop;
|
|
1376
|
+
};
|
|
1377
|
+
(0, import_react2.useEffect)(() => {
|
|
1378
|
+
timer > 0 && !running && startTimer();
|
|
1379
|
+
}, [timer]);
|
|
1380
|
+
(0, import_react2.useEffect)(() => stop, []);
|
|
1381
|
+
setOnDisconnect && setOnDisconnect(() => {
|
|
1382
|
+
stop();
|
|
1383
|
+
});
|
|
1384
|
+
const reset = () => setTimer(duration);
|
|
1385
|
+
return /* @__PURE__ */ import_react2.default.createElement(TimerContext.Provider, { value: { reset, duration, timer } }, timer > 0 ? /* @__PURE__ */ import_react2.default.createElement("div", null, children, timer < 60 && /* @__PURE__ */ import_react2.default.createElement("div", null, "Timeout in: ", timer, " seconds")) : /* @__PURE__ */ import_react2.default.createElement("div", null, "Timed out. ", /* @__PURE__ */ import_react2.default.createElement(import_react_bootstrap.Button, { onClick: reset }, "Resume")));
|
|
1386
|
+
};
|
|
1387
|
+
var TransitiveCapability = ({
|
|
1388
|
+
jwt,
|
|
1389
|
+
host = "transitiverobotics.com",
|
|
1390
|
+
ssl = true,
|
|
1391
|
+
...config
|
|
1392
|
+
}) => {
|
|
1393
|
+
const { id, device, capability } = (0, client_exports.decodeJWT)(jwt);
|
|
1394
|
+
const type = device == "_fleet" ? "fleet" : "device";
|
|
1395
|
+
const capName = capability.split("/")[1];
|
|
1396
|
+
const name = `${capName}-${type}`;
|
|
1397
|
+
const { loaded } = useCapability({
|
|
1398
|
+
capability,
|
|
1399
|
+
name,
|
|
1400
|
+
userId: id || config.userId,
|
|
1401
|
+
// accept both id and userId, see #492
|
|
1402
|
+
deviceId: device,
|
|
1403
|
+
host,
|
|
1404
|
+
ssl
|
|
1405
|
+
});
|
|
1406
|
+
const ref = (0, import_react2.useRef)();
|
|
1407
|
+
(0, import_react2.useEffect)(() => {
|
|
1408
|
+
ref.current?.instance?.setState((s) => ({ ...s, id, jwt, host, ssl, ...config }));
|
|
1409
|
+
}, [ref.current, id, jwt, host, ssl, ...Object.values(config)]);
|
|
1410
|
+
const propClone = (0, import_react2.useMemo)(() => ({ id, jwt, host, ssl, ...config }), []);
|
|
1411
|
+
if (!loaded)
|
|
1412
|
+
return /* @__PURE__ */ import_react2.default.createElement("div", null, "Loading ", name);
|
|
1413
|
+
return import_react2.default.createElement(name, { ...propClone, ref });
|
|
1414
|
+
};
|
|
1415
|
+
var ErrorBoundary = class extends import_react2.default.Component {
|
|
1416
|
+
constructor(props) {
|
|
1417
|
+
super(props);
|
|
1418
|
+
this.state = { hasError: false };
|
|
1419
|
+
}
|
|
1420
|
+
static getDerivedStateFromError(error) {
|
|
1421
|
+
return { hasError: true };
|
|
1422
|
+
}
|
|
1423
|
+
componentDidCatch(error, errorInfo) {
|
|
1424
|
+
console.warn("ErrorBoundary caught:", error, errorInfo);
|
|
1425
|
+
}
|
|
1426
|
+
render() {
|
|
1427
|
+
return this.state.hasError ? /* @__PURE__ */ import_react2.default.createElement("div", null, this.props.message || "Something went wrong here.") : this.props.children;
|
|
1428
|
+
}
|
|
1429
|
+
};
|
|
1430
|
+
var CapabilityContext = import_react2.default.createContext({});
|
|
1431
|
+
var LoadedCapabilityContextProvider = (props) => {
|
|
1432
|
+
const { children, jwt, id, host, ssl, loadedModule } = props;
|
|
1433
|
+
const context = loadedModule.provideContext?.({
|
|
1434
|
+
jwt,
|
|
1435
|
+
id,
|
|
1436
|
+
host,
|
|
1437
|
+
ssl,
|
|
1438
|
+
appReact: import_react2.default
|
|
1439
|
+
});
|
|
1440
|
+
return /* @__PURE__ */ import_react2.default.createElement(CapabilityContext.Provider, { value: { ...context } }, children);
|
|
1441
|
+
};
|
|
1442
|
+
var CapabilityContextProvider = ({ children, jwt, host = void 0, ssl = void 0 }) => {
|
|
1443
|
+
const { id, device, capability } = (0, client_exports.decodeJWT)(jwt);
|
|
1444
|
+
const type = device == "_fleet" ? "fleet" : "device";
|
|
1445
|
+
const capName = capability.split("/")[1];
|
|
1446
|
+
const name = `${capName}-${type}`;
|
|
1447
|
+
const { loaded, loadedModule } = useCapability({
|
|
1448
|
+
capability,
|
|
1449
|
+
name,
|
|
1450
|
+
userId: id,
|
|
1451
|
+
deviceId: device,
|
|
1452
|
+
appReact: import_react2.default,
|
|
1453
|
+
host,
|
|
1454
|
+
ssl
|
|
1455
|
+
});
|
|
1456
|
+
if (!loadedModule)
|
|
1457
|
+
return /* @__PURE__ */ import_react2.default.createElement("div", null, "Loading ", capability);
|
|
1458
|
+
return /* @__PURE__ */ import_react2.default.createElement(LoadedCapabilityContextProvider, { ...{ jwt, id, host, ssl, loadedModule } }, children);
|
|
1459
|
+
};
|
|
1460
|
+
var componentPermitsRefs = (Component) => Component.$$typeof == Symbol.for("react.forward_ref") || Component.prototype?.render;
|
|
1461
|
+
var createWebComponent = (Component, name, version = "0.0.0", options = {}) => {
|
|
1462
|
+
const compRef = componentPermitsRefs(Component) ? import_react2.default.createRef() : null;
|
|
1463
|
+
class Wrapper extends import_react2.default.Component {
|
|
1464
|
+
onDisconnect = null;
|
|
1465
|
+
state = {};
|
|
1466
|
+
/* function used by `Component` to register a onDisconnect handler */
|
|
1467
|
+
setOnDisconnect(fn) {
|
|
1468
|
+
this.onDisconnect = fn;
|
|
1469
|
+
}
|
|
1470
|
+
webComponentConstructed(instance) {
|
|
1471
|
+
const observer = new MutationObserver((mutationRecords) => {
|
|
1472
|
+
const update = {};
|
|
1473
|
+
mutationRecords.forEach(({ attributeName }) => {
|
|
1474
|
+
update[attributeName] = instance.getAttribute(attributeName);
|
|
1475
|
+
});
|
|
1476
|
+
this.setState((old) => ({ ...old, ...update }));
|
|
1477
|
+
}).observe(instance, { attributes: true });
|
|
1478
|
+
}
|
|
1479
|
+
webComponentDisconnected() {
|
|
1480
|
+
this.setState({ _disconnected: true });
|
|
1481
|
+
try {
|
|
1482
|
+
this.onDisconnect && this.onDisconnect();
|
|
1483
|
+
} catch (e) {
|
|
1484
|
+
console.log("Error during onDisconnect of web-component", e);
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
/* method exposed to the wrapped component via prop that allows setting
|
|
1488
|
+
* the "config" state variable inside the wrapper (not the component
|
|
1489
|
+
* itself). This config is retrieved by the portal for inclusion in the
|
|
1490
|
+
* embedding instructions. */
|
|
1491
|
+
setConfig(config) {
|
|
1492
|
+
this.setState({ config });
|
|
1493
|
+
}
|
|
1494
|
+
render() {
|
|
1495
|
+
const stylesheets = options.stylesheets || [
|
|
1496
|
+
// 'https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css'
|
|
1497
|
+
// Bootstrap 5.3.2 css scoped to `.transitive-bs-root`:
|
|
1498
|
+
"https://cdn.jsdelivr.net/gh/transitiverobotics/transitive-utils@0.8.3/web/css/bootstrap_transitive-bs-root.min.css"
|
|
1499
|
+
];
|
|
1500
|
+
return /* @__PURE__ */ import_react2.default.createElement(
|
|
1501
|
+
"div",
|
|
1502
|
+
{
|
|
1503
|
+
id: `cap-${name}-${version}`,
|
|
1504
|
+
className: options.className || "transitive-bs-root"
|
|
1505
|
+
},
|
|
1506
|
+
/* @__PURE__ */ import_react2.default.createElement("style", null, stylesheets.map((url) => `@import url(${url});`)),
|
|
1507
|
+
!this.state._disconnected && /* @__PURE__ */ import_react2.default.createElement(
|
|
1508
|
+
Component,
|
|
1509
|
+
{
|
|
1510
|
+
ref: compRef,
|
|
1511
|
+
...this.props,
|
|
1512
|
+
...this.state,
|
|
1513
|
+
setOnDisconnect: this.setOnDisconnect.bind(this),
|
|
1514
|
+
setConfig: this.setConfig.bind(this)
|
|
1515
|
+
}
|
|
1516
|
+
)
|
|
1517
|
+
);
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
;
|
|
1521
|
+
return import_react_web_component.default.create(
|
|
1522
|
+
Wrapper,
|
|
1523
|
+
name,
|
|
1524
|
+
options.shadowDOM || false,
|
|
1525
|
+
compRef
|
|
1526
|
+
);
|
|
1527
|
+
};
|
|
1528
|
+
|
|
1529
|
+
// index.js
|
|
1530
|
+
__reExport(web_exports, client_exports, module.exports);
|