@continuonai/rcan-ts 0.8.0 → 1.1.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.
@@ -2944,7 +2944,7 @@ var RobotURI = class _RobotURI {
2944
2944
  };
2945
2945
 
2946
2946
  // src/version.ts
2947
- var SPEC_VERSION = "1.9.0";
2947
+ var SPEC_VERSION = "2.1.0";
2948
2948
 
2949
2949
  // src/message.ts
2950
2950
  var RCANMessageError = class extends Error {
@@ -2980,6 +2980,10 @@ var RCANMessage = class _RCANMessage {
2980
2980
  transportEncoding;
2981
2981
  /** v1.6: GAP-18 multi-modal media chunks */
2982
2982
  mediaChunks;
2983
+ /** v2.1: SHA-256 of sender's firmware manifest */
2984
+ firmwareHash;
2985
+ /** v2.1: URI to sender's SBOM attestation endpoint */
2986
+ attestationRef;
2983
2987
  constructor(data) {
2984
2988
  if (!data.cmd || data.cmd.trim() === "") {
2985
2989
  throw new RCANMessageError("'cmd' is required");
@@ -3008,6 +3012,13 @@ var RCANMessage = class _RCANMessage {
3008
3012
  this.loa = data.loa;
3009
3013
  this.transportEncoding = data.transportEncoding;
3010
3014
  this.mediaChunks = data.mediaChunks;
3015
+ this.firmwareHash = data.firmwareHash;
3016
+ this.attestationRef = data.attestationRef;
3017
+ if (this.signature !== void 0 && this.signature["sig"] === "pending") {
3018
+ throw new RCANMessageError(
3019
+ "signature.sig:'pending' is not valid in RCAN v2.1. Sign the message before sending."
3020
+ );
3021
+ }
3011
3022
  if (this.confidence !== void 0) {
3012
3023
  if (this.confidence < 0 || this.confidence > 1) {
3013
3024
  throw new RCANMessageError(
@@ -3049,6 +3060,8 @@ var RCANMessage = class _RCANMessage {
3049
3060
  if (this.loa !== void 0) obj.loa = this.loa;
3050
3061
  if (this.transportEncoding !== void 0) obj.transportEncoding = this.transportEncoding;
3051
3062
  if (this.mediaChunks !== void 0) obj.mediaChunks = this.mediaChunks;
3063
+ if (this.firmwareHash !== void 0) obj.firmwareHash = this.firmwareHash;
3064
+ if (this.attestationRef !== void 0) obj.attestationRef = this.attestationRef;
3052
3065
  return obj;
3053
3066
  }
3054
3067
  /** Serialize to JSON string */
@@ -3091,7 +3104,9 @@ var RCANMessage = class _RCANMessage {
3091
3104
  readOnly: obj.readOnly,
3092
3105
  loa: obj.loa,
3093
3106
  transportEncoding: obj.transportEncoding,
3094
- mediaChunks: obj.mediaChunks
3107
+ mediaChunks: obj.mediaChunks,
3108
+ firmwareHash: obj.firmwareHash,
3109
+ attestationRef: obj.attestationRef
3095
3110
  });
3096
3111
  }
3097
3112
  };
package/dist/rcan.iife.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var RCAN=(()=>{var rn=Object.create;var z=Object.defineProperty;var sn=Object.getOwnPropertyDescriptor;var on=Object.getOwnPropertyNames;var an=Object.getPrototypeOf,cn=Object.prototype.hasOwnProperty;var Q=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,n)=>(typeof require<"u"?require:e)[n]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var dn=(t,e)=>{for(var n in e)z(t,n,{get:e[n],enumerable:!0})},Ze=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of on(e))!cn.call(t,s)&&s!==n&&z(t,s,{get:()=>e[s],enumerable:!(r=sn(e,s))||r.enumerable});return t};var et=(t,e,n)=>(n=t!=null?rn(an(t)):{},Ze(e||!t||!t.__esModule?z(n,"default",{value:t,enumerable:!0}):n,t)),un=t=>Ze(z({},"__esModule",{value:!0}),t);var Pn={};dn(Pn,{AuditChain:()=>ne,AuditError:()=>te,CONTRIBUTE_SCOPE_LEVEL:()=>Qe,ClockDriftError:()=>H,CommitmentRecord:()=>$,ConfidenceGate:()=>Z,DEFAULT_LOA_POLICY:()=>je,DataCategory:()=>Le,FaultCode:()=>$e,FederationSyncType:()=>Be,GateError:()=>O,HiTLGate:()=>ee,KeyStore:()=>Re,LevelOfAssurance:()=>Ae,MediaEncoding:()=>Je,MessageType:()=>x,NodeClient:()=>le,OfflineModeManager:()=>Ce,PRODUCTION_LOA_POLICY:()=>Ut,QoSAckTimeoutError:()=>ge,QoSLevel:()=>Me,QoSManager:()=>pe,RCANAddressError:()=>re,RCANConfigAuthorizationError:()=>ue,RCANDelegationChainError:()=>de,RCANError:()=>_,RCANGateError:()=>oe,RCANMessage:()=>l,RCANMessageError:()=>A,RCANNodeError:()=>L,RCANNodeNotFoundError:()=>k,RCANNodeSyncError:()=>R,RCANNodeTrustError:()=>j,RCANRegistryError:()=>D,RCANReplayAttackError:()=>ce,RCANSignatureError:()=>ie,RCANValidationError:()=>se,RCANVersionIncompatibleError:()=>ae,RCAN_VERSION:()=>Mn,RegistryClient:()=>fe,RegistryTier:()=>qe,ReplayCache:()=>ye,RevocationCache:()=>K,RobotURI:()=>M,RobotURIError:()=>U,SAFETY_MESSAGE_TYPE:()=>Pe,SDK_VERSION:()=>tt,SPEC_VERSION:()=>h,TransportEncoding:()=>Ke,TransportError:()=>E,TrustAnchorCache:()=>xe,VERSION:()=>Un,addDelegationHop:()=>st,addMediaInline:()=>ze,addMediaRef:()=>Vt,assertClockSynced:()=>bt,checkClockSync:()=>De,checkRevocation:()=>wt,decodeBleFrames:()=>Ft,decodeCompact:()=>Ye,decodeMinimal:()=>qt,encodeBleFrames:()=>Bt,encodeCompact:()=>Ve,encodeMinimal:()=>jt,extractLoaFromJwt:()=>Ee,fetchCanonicalSchema:()=>me,isPreemptedBy:()=>Zt,isSafetyMessage:()=>yt,makeCloudRelayMessage:()=>rt,makeConfigUpdate:()=>Ct,makeConsentDeny:()=>be,makeConsentGrant:()=>Se,makeConsentRequest:()=>_e,makeContributeCancel:()=>Qt,makeContributeRequest:()=>Wt,makeContributeResult:()=>zt,makeEstopMessage:()=>gt,makeEstopWithQoS:()=>mt,makeFaultReport:()=>It,makeFederationSync:()=>Pt,makeKeyRotationMessage:()=>Et,makeResumeMessage:()=>ht,makeRevocationBroadcast:()=>vt,makeStopMessage:()=>pt,makeStreamChunk:()=>Gt,makeTrainingConsentDeny:()=>kt,makeTrainingConsentGrant:()=>Ot,makeTrainingConsentRequest:()=>Nt,makeTrainingDataMessage:()=>Jt,makeTransparencyMessage:()=>_t,selectTransport:()=>Ht,validateConfig:()=>ut,validateConfigAgainstSchema:()=>ft,validateConfigUpdate:()=>At,validateConsentMessage:()=>xt,validateContributeScope:()=>Xt,validateCrossRegistryCommand:()=>Dt,validateDelegationChain:()=>ot,validateLoaForScope:()=>Mt,validateMediaChunks:()=>Yt,validateMessage:()=>dt,validateNodeAgainstSchema:()=>lt,validateReplay:()=>St,validateSafetyMessage:()=>Rt,validateTrainingDataMessage:()=>Tt,validateURI:()=>ct,validateVersionCompat:()=>nt});var U=class extends Error{constructor(e){super(e),this.name="RobotURIError"}},M=class t{registry;manufacturer;model;version;deviceId;constructor(e){this.registry=e.registry,this.manufacturer=e.manufacturer,this.model=e.model,this.version=e.version,this.deviceId=e.deviceId}static parse(e){if(!e.startsWith("rcan://"))throw new U(`URI must start with 'rcan://' \u2014 got: ${e}`);let r=e.slice(7).split("/");if(r.length!==5)throw new U(`URI must have exactly 5 path segments (registry/manufacturer/model/version/device-id) \u2014 got ${r.length} in: ${e}`);let[s,o,i,a,d]=r;for(let[u,f]of[["registry",s],["manufacturer",o],["model",i],["version",a],["device-id",d]])if(!f||f.trim()==="")throw new U(`URI segment '${u}' must not be empty`);return new t({registry:s,manufacturer:o,model:i,version:a,deviceId:d})}static build(e){let n=e.registry??"registry.rcan.dev",{manufacturer:r,model:s,version:o,deviceId:i}=e;for(let[a,d]of[["manufacturer",r],["model",s],["version",o],["deviceId",i]])if(!d||d.trim()==="")throw new U(`'${a}' must not be empty`);return new t({registry:n,manufacturer:r,model:s,version:o,deviceId:i})}toString(){return`rcan://${this.registry}/${this.manufacturer}/${this.model}/${this.version}/${this.deviceId}`}get namespace(){return`${this.manufacturer}/${this.model}`}get registryUrl(){return`https://${this.registry}/registry/${this.manufacturer}/${this.model}/${this.version}/${this.deviceId}`}equals(e){return this.toString()===e.toString()}toJSON(){return{uri:this.toString(),registry:this.registry,manufacturer:this.manufacturer,model:this.model,version:this.version,deviceId:this.deviceId}}};var h="1.9.0",tt="0.8.0";function nt(t,e=h){let n=o=>{let i=o.split("."),a=parseInt(i[0]??"0",10),d=parseInt(i[1]??"0",10);return[isNaN(a)?0:a,isNaN(d)?0:d]},[r]=n(t),[s]=n(e);return r===s}var x=(c=>(c[c.COMMAND=1]="COMMAND",c[c.RESPONSE=2]="RESPONSE",c[c.STATUS=3]="STATUS",c[c.HEARTBEAT=4]="HEARTBEAT",c[c.CONFIG=5]="CONFIG",c[c.SAFETY=6]="SAFETY",c[c.AUTH=7]="AUTH",c[c.ERROR=8]="ERROR",c[c.DISCOVER=9]="DISCOVER",c[c.PENDING_AUTH=10]="PENDING_AUTH",c[c.INVOKE=11]="INVOKE",c[c.INVOKE_RESULT=12]="INVOKE_RESULT",c[c.INVOKE_CANCEL=13]="INVOKE_CANCEL",c[c.REGISTRY_REGISTER=14]="REGISTRY_REGISTER",c[c.REGISTRY_RESOLVE=15]="REGISTRY_RESOLVE",c[c.TRANSPARENCY=16]="TRANSPARENCY",c[c.COMMAND_ACK=17]="COMMAND_ACK",c[c.COMMAND_NACK=18]="COMMAND_NACK",c[c.ROBOT_REVOCATION=19]="ROBOT_REVOCATION",c[c.CONSENT_REQUEST=20]="CONSENT_REQUEST",c[c.CONSENT_GRANT=21]="CONSENT_GRANT",c[c.CONSENT_DENY=22]="CONSENT_DENY",c[c.FLEET_COMMAND=23]="FLEET_COMMAND",c[c.SUBSCRIBE=24]="SUBSCRIBE",c[c.UNSUBSCRIBE=25]="UNSUBSCRIBE",c[c.FAULT_REPORT=26]="FAULT_REPORT",c[c.KEY_ROTATION=27]="KEY_ROTATION",c[c.COMMAND_COMMIT=28]="COMMAND_COMMIT",c[c.SENSOR_DATA=29]="SENSOR_DATA",c[c.TRAINING_CONSENT_REQUEST=30]="TRAINING_CONSENT_REQUEST",c[c.TRAINING_CONSENT_GRANT=31]="TRAINING_CONSENT_GRANT",c[c.TRAINING_CONSENT_DENY=32]="TRAINING_CONSENT_DENY",c[c.CONTRIBUTE_REQUEST=33]="CONTRIBUTE_REQUEST",c[c.CONTRIBUTE_RESULT=34]="CONTRIBUTE_RESULT",c[c.CONTRIBUTE_CANCEL=35]="CONTRIBUTE_CANCEL",c[c.TRAINING_DATA=36]="TRAINING_DATA",c[c.FEDERATION_SYNC=23]="FEDERATION_SYNC",c[c.ALERT=26]="ALERT",c[c.AUDIT=16]="AUDIT",c))(x||{}),A=class extends Error{constructor(e){super(e),this.name="RCANMessageError"}},l=class t{rcan;rcanVersion;cmd;target;params;confidence;modelIdentity;signature;timestamp;senderType;cloudProvider;keyId;delegationChain;groupId;qos;presenceVerified;proximityMeters;readOnly;loa;transportEncoding;mediaChunks;constructor(e){if(!e.cmd||e.cmd.trim()==="")throw new A("'cmd' is required");if(!e.target)throw new A("'target' is required");if(this.rcan=e.rcan??h,this.rcanVersion=e.rcanVersion??h,this.cmd=e.cmd,this.target=e.target instanceof M?e.target.toString():String(e.target),this.params=e.params??{},this.confidence=e.confidence,this.modelIdentity=e.modelIdentity??e.model_identity,this.signature=e.signature,this.timestamp=e.timestamp??new Date().toISOString(),this.senderType=e.senderType,this.cloudProvider=e.cloudProvider,this.keyId=e.keyId,this.delegationChain=e.delegationChain,this.groupId=e.groupId,this.qos=e.qos,this.presenceVerified=e.presenceVerified,this.proximityMeters=e.proximityMeters,this.readOnly=e.readOnly,this.loa=e.loa,this.transportEncoding=e.transportEncoding,this.mediaChunks=e.mediaChunks,this.confidence!==void 0&&(this.confidence<0||this.confidence>1))throw new A(`confidence must be in [0.0, 1.0] \u2014 got ${this.confidence}`)}get isSigned(){return this.signature!==void 0&&this.signature.sig!==""}get isAiDriven(){return this.confidence!==void 0}toJSON(){let e={rcan:this.rcan,rcanVersion:this.rcanVersion,cmd:this.cmd,target:this.target,timestamp:this.timestamp};return Object.keys(this.params).length>0&&(e.params=this.params),this.confidence!==void 0&&(e.confidence=this.confidence),this.modelIdentity&&(e.model_identity=this.modelIdentity),this.signature&&(e.signature=this.signature),this.senderType!==void 0&&(e.senderType=this.senderType),this.cloudProvider!==void 0&&(e.cloudProvider=this.cloudProvider),this.keyId!==void 0&&(e.keyId=this.keyId),this.delegationChain!==void 0&&(e.delegationChain=this.delegationChain),this.groupId!==void 0&&(e.groupId=this.groupId),this.qos!==void 0&&(e.qos=this.qos),this.presenceVerified!==void 0&&(e.presenceVerified=this.presenceVerified),this.proximityMeters!==void 0&&(e.proximityMeters=this.proximityMeters),this.readOnly!==void 0&&(e.readOnly=this.readOnly),this.loa!==void 0&&(e.loa=this.loa),this.transportEncoding!==void 0&&(e.transportEncoding=this.transportEncoding),this.mediaChunks!==void 0&&(e.mediaChunks=this.mediaChunks),e}toJSONString(e){return JSON.stringify(this.toJSON(),null,e)}static fromJSON(e){let n;if(typeof e=="string")try{n=JSON.parse(e)}catch{throw new A("Invalid JSON string")}else n=e;if(!n.cmd)throw new A("Missing required field: 'cmd'");if(!n.target)throw new A("Missing required field: 'target'");if(!n.rcan)throw new A("Missing required field: 'rcan'");return new t({rcan:n.rcan,rcanVersion:n.rcanVersion,cmd:n.cmd,target:n.target,params:n.params??{},confidence:n.confidence,modelIdentity:n.model_identity??n.modelIdentity,signature:n.signature,timestamp:n.timestamp,senderType:n.senderType,cloudProvider:n.cloudProvider,keyId:n.keyId,delegationChain:n.delegationChain,groupId:n.groupId,qos:n.qos,presenceVerified:n.presenceVerified,proximityMeters:n.proximityMeters,readOnly:n.readOnly,loa:n.loa,transportEncoding:n.transportEncoding,mediaChunks:n.mediaChunks})}};function rt(t,e){let n=t.toJSON();return n.senderType="cloud_function",n.cloudProvider=e,new l(n)}function st(t,e){let n=t.delegationChain?[...t.delegationChain,e]:[e],r=t.toJSON();return r.delegationChain=n,new l(r)}function ot(t){if(t.length>4)return{valid:!1,reason:"DELEGATION_CHAIN_EXCEEDED: max depth is 4 hops"};for(let e=0;e<t.length;e++){let n=t[e];if(!n)return{valid:!1,reason:`hop ${e} is undefined`};if(!n.issuerRuri)return{valid:!1,reason:`hop ${e}: missing issuerRuri`};if(!n.humanSubject)return{valid:!1,reason:`hop ${e}: missing humanSubject`};if(!n.timestamp)return{valid:!1,reason:`hop ${e}: missing timestamp`};if(!n.scope)return{valid:!1,reason:`hop ${e}: missing scope`};if(!n.signature)return{valid:!1,reason:`hop ${e}: missing signature`}}return{valid:!0,reason:"ok"}}function X(){if(typeof globalThis.crypto<"u"&&typeof globalThis.crypto.randomUUID=="function")return globalThis.crypto.randomUUID();try{let{randomUUID:t}=Q("crypto");return t()}catch{return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,t=>{let e=Math.random()*16|0;return(t==="x"?e:e&3|8).toString(16)})}}function Te(t,e){return typeof process<"u",ln(t,e)}function ke(t){let e=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],n=1779033703,r=3144134277,s=1013904242,o=2773480762,i=1359893119,a=2600822924,d=528734635,u=1541459225,q=t.length*8,C=[...t];for(C.push(128);C.length%64!==56;)C.push(0);for(let y=7;y>=0;y--)C.push(q/Math.pow(2,y*8)&255);for(let y=0;y<C.length;y+=64){let S=[];for(let g=0;g<16;g++)S[g]=C[y+g*4]<<24|C[y+g*4+1]<<16|C[y+g*4+2]<<8|C[y+g*4+3];for(let g=16;g<64;g++){let Ne=w(S[g-15],7)^w(S[g-15],18)^S[g-15]>>>3,Oe=w(S[g-2],17)^w(S[g-2],19)^S[g-2]>>>10;S[g]=S[g-16]+Ne+S[g-7]+Oe>>>0}let[T,B,F,we,I,G,W,ve]=[n,r,s,o,i,a,d,u];for(let g=0;g<64;g++){let Ne=w(I,6)^w(I,11)^w(I,25),Oe=I&G^~I&W,Xe=ve+Ne+Oe+e[g]+S[g]>>>0,en=w(T,2)^w(T,13)^w(T,22),tn=T&B^T&F^B&F,nn=en+tn>>>0;[ve,W,G,I,we,F,B,T]=[W,G,I,we+Xe>>>0,F,B,T,Xe+nn>>>0]}n=n+T>>>0,r=r+B>>>0,s=s+F>>>0,o=o+we>>>0,i=i+I>>>0,a=a+G>>>0,d=d+W>>>0,u=u+ve>>>0}let p=new Uint8Array(32),N=new DataView(p.buffer);return[n,r,s,o,i,a,d,u].forEach((y,S)=>N.setUint32(S*4,y)),p}function w(t,e){return t>>>e|t<<32-e}function it(t){if(typeof TextEncoder<"u")return new TextEncoder().encode(t);let e=new Uint8Array(t.length);for(let n=0;n<t.length;n++)e[n]=t.charCodeAt(n)&255;return e}function fn(t){return Array.from(t).map(e=>e.toString(16).padStart(2,"0")).join("")}function ln(t,e){let r=it(t);r.length>64&&(r=ke(r));let s=new Uint8Array(64),o=new Uint8Array(64);for(let f=0;f<64;f++)s[f]=(r[f]??0)^54,o[f]=(r[f]??0)^92;let i=it(e),a=new Uint8Array(64+i.length);a.set(s),a.set(i,64);let d=ke(a),u=new Uint8Array(96);return u.set(o),u.set(d,64),fn(ke(u))}var O=class extends Error{constructor(e){super(e),this.name="GateError"}},Z=class{threshold;constructor(e=.8){if(e<0||e>1)throw new O(`threshold must be in [0.0, 1.0] \u2014 got ${e}`);this.threshold=e}allows(e){return e>=this.threshold}margin(e){return e-this.threshold}assert(e,n){if(!this.allows(e)){let r=n?` for action '${n}'`:"";throw new O(`Confidence ${e}${r} is below threshold ${this.threshold}`)}}},ee=class{_pending=new Map;request(e,n={}){let r=X();return this._pending.set(r,{token:r,action:e,context:n,createdAt:new Date().toISOString(),status:"pending"}),r}approve(e){let n=this._pending.get(e);if(!n)throw new O(`Unknown token: ${e}`);n.status="approved"}deny(e,n){let r=this._pending.get(e);if(!r)throw new O(`Unknown token: ${e}`);r.status="denied",n&&(r.reason=n)}check(e){let n=this._pending.get(e);if(!n)throw new O(`Unknown token: ${e}`);return n.status}get pendingApprovals(){return Array.from(this._pending.values()).filter(e=>e.status==="pending")}getApproval(e){return this._pending.get(e)}clearResolved(){for(let[e,n]of this._pending.entries())n.status!=="pending"&&this._pending.delete(e)}};var te=class extends Error{constructor(e){super(e),this.name="AuditError"}};function mn(t,e,n,r,s){let o=JSON.stringify({recordId:t,action:e,robotUri:n,timestamp:r,params:s},Object.keys({recordId:t,action:e,robotUri:n,timestamp:r,params:s}).sort());return Te("rcan-content-hash",o)}function at(t,e){let{hmac:n,...r}=e,s=JSON.stringify(r,Object.keys(r).sort());return Te(t,s)}var $=class t{recordId;action;robotUri;confidence;modelIdentity;params;safetyApproved;timestamp;contentHash;previousHash;hmac;constructor(e){this.recordId=e.recordId,this.action=e.action,this.robotUri=e.robotUri,this.confidence=e.confidence,this.modelIdentity=e.modelIdentity,this.params=e.params,this.safetyApproved=e.safetyApproved,this.timestamp=e.timestamp,this.contentHash=e.contentHash,this.previousHash=e.previousHash,this.hmac=e.hmac}static create(e,n,r=null){let s=X(),o=new Date().toISOString(),i=e.params??{},a=e.robotUri??"",d=mn(s,e.action,a,o,i),u={recordId:s,action:e.action,robotUri:a,confidence:e.confidence,modelIdentity:e.modelIdentity,params:i,safetyApproved:e.safetyApproved??!0,timestamp:o,contentHash:d,previousHash:r,hmac:""};return u.hmac=at(n,u),new t(u)}verify(e){return at(e,this.toJSON())===this.hmac}toJSON(){return{recordId:this.recordId,action:this.action,robotUri:this.robotUri,confidence:this.confidence,modelIdentity:this.modelIdentity,params:this.params,safetyApproved:this.safetyApproved,timestamp:this.timestamp,contentHash:this.contentHash,previousHash:this.previousHash,hmac:this.hmac}}static fromJSON(e){return new t(e)}},ne=class t{_records=[];_secret;constructor(e){this._secret=e}get records(){return this._records}append(e){let r=this._records[this._records.length-1]?.contentHash??null,s=$.create(e,this._secret,r);return this._records.push(s),s}verifyAll(){let e=[],n=null;for(let r of this._records)r.verify(this._secret)||e.push(`HMAC invalid for record ${r.recordId.slice(0,8)}`),n!==null&&r.previousHash!==n&&e.push(`Chain broken at ${r.recordId.slice(0,8)}: expected prev=${n.slice(0,12)}`),n=r.contentHash;return{valid:e.length===0,count:this._records.length,errors:e}}toJSONL(){return this._records.map(e=>JSON.stringify(e.toJSON())).join(`
1
+ "use strict";var RCAN=(()=>{var qr=Object.create;var te=Object.defineProperty;var Fr=Object.getOwnPropertyDescriptor;var Hr=Object.getOwnPropertyNames;var Br=Object.getPrototypeOf,Vr=Object.prototype.hasOwnProperty;var re=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var Kr=(t,e)=>{for(var r in e)te(t,r,{get:e[r],enumerable:!0})},gt=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Hr(e))!Vr.call(t,s)&&s!==r&&te(t,s,{get:()=>e[s],enumerable:!(n=Fr(e,s))||n.enumerable});return t};var ht=(t,e,r)=>(r=t!=null?qr(Br(t)):{},gt(e||!t||!t.__esModule?te(r,"default",{value:t,enumerable:!0}):r,t)),Jr=t=>gt(te({},"__esModule",{value:!0}),t);var Sn={};Kr(Sn,{AUTHORITY_ERROR_CODES:()=>Mr,AuditChain:()=>ae,AuditError:()=>ie,COMPETITION_SCOPE_LEVEL:()=>it,CONTRIBUTE_SCOPE_LEVEL:()=>ot,ClockDriftError:()=>G,CommitmentRecord:()=>F,ConfidenceGate:()=>se,DEFAULT_LOA_POLICY:()=>zt,DataCategory:()=>Be,FIRMWARE_MANIFEST_PATH:()=>wr,FaultCode:()=>Ve,FederationSyncType:()=>Ye,FirmwareIntegrityError:()=>Ne,GateError:()=>N,HiTLGate:()=>oe,KeyStore:()=>Ae,LevelOfAssurance:()=>Yt,M2MAuthError:()=>S,M2M_TRUSTED_ISSUER:()=>ke,MediaEncoding:()=>tt,MessageType:()=>x,NodeClient:()=>ye,OfflineModeManager:()=>Te,PRODUCTION_LOA_POLICY:()=>Qt,QoSAckTimeoutError:()=>_e,QoSLevel:()=>qe,QoSManager:()=>Se,RCANAddressError:()=>ce,RCANConfigAuthorizationError:()=>ge,RCANDelegationChainError:()=>pe,RCANError:()=>_,RCANGateError:()=>ue,RCANMessage:()=>m,RCANMessageError:()=>C,RCANNodeError:()=>q,RCANNodeNotFoundError:()=>k,RCANNodeSyncError:()=>R,RCANNodeTrustError:()=>H,RCANRegistryError:()=>j,RCANReplayAttackError:()=>me,RCANSignatureError:()=>fe,RCANValidationError:()=>de,RCANVersionIncompatibleError:()=>le,RCAN_VERSION:()=>_n,ROLE_JWT_LEVEL:()=>B,RRF_REVOCATION_CACHE_TTL_MS:()=>dt,RRF_REVOCATION_URL:()=>ct,RegistryClient:()=>he,RegistryTier:()=>We,ReplayCache:()=>be,RevocationCache:()=>W,RobotURI:()=>P,RobotURIError:()=>U,Role:()=>D,SAFETY_MESSAGE_TYPE:()=>Fe,SCOPE_MIN_ROLE:()=>Ke,SDK_VERSION:()=>yt,SPEC_VERSION:()=>h,TransportEncoding:()=>Xe,TransportError:()=>w,TrustAnchorCache:()=>Oe,VERSION:()=>Rn,addDelegationHop:()=>St,addMediaInline:()=>st,addMediaRef:()=>fr,assertClockSynced:()=>$t,authorityAccessFromWire:()=>kr,authorityAccessToWire:()=>Nr,canonicalManifestJson:()=>vr,checkClockSync:()=>He,checkRevocation:()=>Ht,decodeBleFrames:()=>cr,decodeCompact:()=>et,decodeMinimal:()=>ir,encodeBleFrames:()=>ar,encodeCompact:()=>Ze,encodeMinimal:()=>or,extractIdentityFromJwt:()=>Zt,extractLoaFromJwt:()=>ve,extractRoleFromJwt:()=>Je,fetchCanonicalSchema:()=>Re,fetchRRFRevocations:()=>lt,isAuthorityRequestValid:()=>Ir,isM2mTrustedRevoked:()=>mt,isPreemptedBy:()=>_r,isSafetyMessage:()=>Mt,makeCloudRelayMessage:()=>_t,makeCompetitionEnter:()=>Sr,makeCompetitionScore:()=>Er,makeConfigUpdate:()=>Lt,makeConsentDeny:()=>xe,makeConsentGrant:()=>we,makeConsentRequest:()=>Ce,makeContributeCancel:()=>yr,makeContributeRequest:()=>gr,makeContributeResult:()=>hr,makeEstopMessage:()=>Nt,makeEstopWithQoS:()=>Ot,makeFaultReport:()=>Wt,makeFederationSync:()=>tr,makeKeyRotationMessage:()=>qt,makePersonalResearchResult:()=>Ar,makeResumeMessage:()=>It,makeRevocationBroadcast:()=>Bt,makeSeasonStanding:()=>br,makeStopMessage:()=>kt,makeStreamChunk:()=>pr,makeTrainingConsentDeny:()=>Jt,makeTrainingConsentGrant:()=>Kt,makeTrainingConsentRequest:()=>Vt,makeTrainingDataMessage:()=>mr,makeTransparencyMessage:()=>Pt,manifestFromWire:()=>Tr,manifestToWire:()=>xr,parseM2mPeerToken:()=>Pr,parseM2mTrustedToken:()=>ut,roleFromJwtLevel:()=>Y,selectTransport:()=>dr,validateAuthorityAccess:()=>at,validateCompetitionScope:()=>Cr,validateConfig:()=>xt,validateConfigAgainstSchema:()=>Tt,validateConfigUpdate:()=>jt,validateConsentMessage:()=>Ft,validateContributeScope:()=>Rr,validateCrossRegistryCommand:()=>rr,validateDelegationChain:()=>Et,validateLoaForScope:()=>er,validateManifest:()=>Or,validateMediaChunks:()=>lr,validateMessage:()=>wt,validateNodeAgainstSchema:()=>vt,validateReplay:()=>Dt,validateRoleForScope:()=>Ge,validateSafetyMessage:()=>Ut,validateTrainingDataMessage:()=>Gt,validateURI:()=>Ct,validateVersionCompat:()=>Rt,verifyM2mTrustedToken:()=>Dr,verifyM2mTrustedTokenClaims:()=>ft});var U=class extends Error{constructor(e){super(e),this.name="RobotURIError"}},P=class t{registry;manufacturer;model;version;deviceId;constructor(e){this.registry=e.registry,this.manufacturer=e.manufacturer,this.model=e.model,this.version=e.version,this.deviceId=e.deviceId}static parse(e){if(!e.startsWith("rcan://"))throw new U(`URI must start with 'rcan://' \u2014 got: ${e}`);let n=e.slice(7).split("/");if(n.length!==5)throw new U(`URI must have exactly 5 path segments (registry/manufacturer/model/version/device-id) \u2014 got ${n.length} in: ${e}`);let[s,o,i,a,d]=n;for(let[u,l]of[["registry",s],["manufacturer",o],["model",i],["version",a],["device-id",d]])if(!l||l.trim()==="")throw new U(`URI segment '${u}' must not be empty`);return new t({registry:s,manufacturer:o,model:i,version:a,deviceId:d})}static build(e){let r=e.registry??"registry.rcan.dev",{manufacturer:n,model:s,version:o,deviceId:i}=e;for(let[a,d]of[["manufacturer",n],["model",s],["version",o],["deviceId",i]])if(!d||d.trim()==="")throw new U(`'${a}' must not be empty`);return new t({registry:r,manufacturer:n,model:s,version:o,deviceId:i})}toString(){return`rcan://${this.registry}/${this.manufacturer}/${this.model}/${this.version}/${this.deviceId}`}get namespace(){return`${this.manufacturer}/${this.model}`}get registryUrl(){return`https://${this.registry}/registry/${this.manufacturer}/${this.model}/${this.version}/${this.deviceId}`}equals(e){return this.toString()===e.toString()}toJSON(){return{uri:this.toString(),registry:this.registry,manufacturer:this.manufacturer,model:this.model,version:this.version,deviceId:this.deviceId}}};var h="2.1.0",yt="1.1.0";function Rt(t,e=h){let r=o=>{let i=o.split("."),a=parseInt(i[0]??"0",10),d=parseInt(i[1]??"0",10);return[isNaN(a)?0:a,isNaN(d)?0:d]},[n]=r(t),[s]=r(e);return n===s}var x=(c=>(c[c.COMMAND=1]="COMMAND",c[c.RESPONSE=2]="RESPONSE",c[c.STATUS=3]="STATUS",c[c.HEARTBEAT=4]="HEARTBEAT",c[c.CONFIG=5]="CONFIG",c[c.SAFETY=6]="SAFETY",c[c.AUTH=7]="AUTH",c[c.ERROR=8]="ERROR",c[c.DISCOVER=9]="DISCOVER",c[c.PENDING_AUTH=10]="PENDING_AUTH",c[c.INVOKE=11]="INVOKE",c[c.INVOKE_RESULT=12]="INVOKE_RESULT",c[c.INVOKE_CANCEL=13]="INVOKE_CANCEL",c[c.REGISTRY_REGISTER=14]="REGISTRY_REGISTER",c[c.REGISTRY_RESOLVE=15]="REGISTRY_RESOLVE",c[c.TRANSPARENCY=16]="TRANSPARENCY",c[c.COMMAND_ACK=17]="COMMAND_ACK",c[c.COMMAND_NACK=18]="COMMAND_NACK",c[c.ROBOT_REVOCATION=19]="ROBOT_REVOCATION",c[c.CONSENT_REQUEST=20]="CONSENT_REQUEST",c[c.CONSENT_GRANT=21]="CONSENT_GRANT",c[c.CONSENT_DENY=22]="CONSENT_DENY",c[c.FLEET_COMMAND=23]="FLEET_COMMAND",c[c.SUBSCRIBE=24]="SUBSCRIBE",c[c.UNSUBSCRIBE=25]="UNSUBSCRIBE",c[c.FAULT_REPORT=26]="FAULT_REPORT",c[c.KEY_ROTATION=27]="KEY_ROTATION",c[c.COMMAND_COMMIT=28]="COMMAND_COMMIT",c[c.SENSOR_DATA=29]="SENSOR_DATA",c[c.TRAINING_CONSENT_REQUEST=30]="TRAINING_CONSENT_REQUEST",c[c.TRAINING_CONSENT_GRANT=31]="TRAINING_CONSENT_GRANT",c[c.TRAINING_CONSENT_DENY=32]="TRAINING_CONSENT_DENY",c[c.CONTRIBUTE_REQUEST=33]="CONTRIBUTE_REQUEST",c[c.CONTRIBUTE_RESULT=34]="CONTRIBUTE_RESULT",c[c.CONTRIBUTE_CANCEL=35]="CONTRIBUTE_CANCEL",c[c.TRAINING_DATA=36]="TRAINING_DATA",c[c.COMPETITION_ENTER=37]="COMPETITION_ENTER",c[c.COMPETITION_SCORE=38]="COMPETITION_SCORE",c[c.SEASON_STANDING=39]="SEASON_STANDING",c[c.PERSONAL_RESEARCH_RESULT=40]="PERSONAL_RESEARCH_RESULT",c[c.AUTHORITY_ACCESS=41]="AUTHORITY_ACCESS",c[c.AUTHORITY_RESPONSE=42]="AUTHORITY_RESPONSE",c[c.FIRMWARE_ATTESTATION=43]="FIRMWARE_ATTESTATION",c[c.SBOM_UPDATE=44]="SBOM_UPDATE",c))(x||{}),C=class extends Error{constructor(e){super(e),this.name="RCANMessageError"}},m=class t{rcan;rcanVersion;cmd;target;params;confidence;modelIdentity;signature;timestamp;senderType;cloudProvider;keyId;delegationChain;groupId;qos;presenceVerified;proximityMeters;readOnly;loa;transportEncoding;mediaChunks;firmwareHash;attestationRef;constructor(e){if(!e.cmd||e.cmd.trim()==="")throw new C("'cmd' is required");if(!e.target)throw new C("'target' is required");if(this.rcan=e.rcan??h,this.rcanVersion=e.rcanVersion??h,this.cmd=e.cmd,this.target=e.target instanceof P?e.target.toString():String(e.target),this.params=e.params??{},this.confidence=e.confidence,this.modelIdentity=e.modelIdentity??e.model_identity,this.signature=e.signature,this.timestamp=e.timestamp??new Date().toISOString(),this.senderType=e.senderType,this.cloudProvider=e.cloudProvider,this.keyId=e.keyId,this.delegationChain=e.delegationChain,this.groupId=e.groupId,this.qos=e.qos,this.presenceVerified=e.presenceVerified,this.proximityMeters=e.proximityMeters,this.readOnly=e.readOnly,this.loa=e.loa,this.transportEncoding=e.transportEncoding,this.mediaChunks=e.mediaChunks,this.firmwareHash=e.firmwareHash,this.attestationRef=e.attestationRef,this.signature!==void 0&&this.signature.sig==="pending")throw new C("signature.sig:'pending' is not valid in RCAN v2.1. Sign the message before sending.");if(this.confidence!==void 0&&(this.confidence<0||this.confidence>1))throw new C(`confidence must be in [0.0, 1.0] \u2014 got ${this.confidence}`)}get isSigned(){return this.signature!==void 0&&this.signature.sig!==""}get isAiDriven(){return this.confidence!==void 0}toJSON(){let e={rcan:this.rcan,rcanVersion:this.rcanVersion,cmd:this.cmd,target:this.target,timestamp:this.timestamp};return Object.keys(this.params).length>0&&(e.params=this.params),this.confidence!==void 0&&(e.confidence=this.confidence),this.modelIdentity&&(e.model_identity=this.modelIdentity),this.signature&&(e.signature=this.signature),this.senderType!==void 0&&(e.senderType=this.senderType),this.cloudProvider!==void 0&&(e.cloudProvider=this.cloudProvider),this.keyId!==void 0&&(e.keyId=this.keyId),this.delegationChain!==void 0&&(e.delegationChain=this.delegationChain),this.groupId!==void 0&&(e.groupId=this.groupId),this.qos!==void 0&&(e.qos=this.qos),this.presenceVerified!==void 0&&(e.presenceVerified=this.presenceVerified),this.proximityMeters!==void 0&&(e.proximityMeters=this.proximityMeters),this.readOnly!==void 0&&(e.readOnly=this.readOnly),this.loa!==void 0&&(e.loa=this.loa),this.transportEncoding!==void 0&&(e.transportEncoding=this.transportEncoding),this.mediaChunks!==void 0&&(e.mediaChunks=this.mediaChunks),this.firmwareHash!==void 0&&(e.firmwareHash=this.firmwareHash),this.attestationRef!==void 0&&(e.attestationRef=this.attestationRef),e}toJSONString(e){return JSON.stringify(this.toJSON(),null,e)}static fromJSON(e){let r;if(typeof e=="string")try{r=JSON.parse(e)}catch{throw new C("Invalid JSON string")}else r=e;if(!r.cmd)throw new C("Missing required field: 'cmd'");if(!r.target)throw new C("Missing required field: 'target'");if(!r.rcan)throw new C("Missing required field: 'rcan'");return new t({rcan:r.rcan,rcanVersion:r.rcanVersion,cmd:r.cmd,target:r.target,params:r.params??{},confidence:r.confidence,modelIdentity:r.model_identity??r.modelIdentity,signature:r.signature,timestamp:r.timestamp,senderType:r.senderType,cloudProvider:r.cloudProvider,keyId:r.keyId,delegationChain:r.delegationChain,groupId:r.groupId,qos:r.qos,presenceVerified:r.presenceVerified,proximityMeters:r.proximityMeters,readOnly:r.readOnly,loa:r.loa,transportEncoding:r.transportEncoding,mediaChunks:r.mediaChunks,firmwareHash:r.firmwareHash,attestationRef:r.attestationRef})}};function _t(t,e){let r=t.toJSON();return r.senderType="cloud_function",r.cloudProvider=e,new m(r)}function St(t,e){let r=t.delegationChain?[...t.delegationChain,e]:[e],n=t.toJSON();return n.delegationChain=r,new m(n)}function Et(t){if(t.length>4)return{valid:!1,reason:"DELEGATION_CHAIN_EXCEEDED: max depth is 4 hops"};for(let e=0;e<t.length;e++){let r=t[e];if(!r)return{valid:!1,reason:`hop ${e} is undefined`};if(!r.issuerRuri)return{valid:!1,reason:`hop ${e}: missing issuerRuri`};if(!r.humanSubject)return{valid:!1,reason:`hop ${e}: missing humanSubject`};if(!r.timestamp)return{valid:!1,reason:`hop ${e}: missing timestamp`};if(!r.scope)return{valid:!1,reason:`hop ${e}: missing scope`};if(!r.signature)return{valid:!1,reason:`hop ${e}: missing signature`}}return{valid:!0,reason:"ok"}}function ne(){if(typeof globalThis.crypto<"u"&&typeof globalThis.crypto.randomUUID=="function")return globalThis.crypto.randomUUID();try{let{randomUUID:t}=re("crypto");return t()}catch{return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,t=>{let e=Math.random()*16|0;return(t==="x"?e:e&3|8).toString(16)})}}function $e(t,e){return typeof process<"u",Wr(t,e)}function De(t){let e=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],r=1779033703,n=3144134277,s=1013904242,o=2773480762,i=1359893119,a=2600822924,d=528734635,u=1541459225,V=t.length*8,A=[...t];for(A.push(128);A.length%64!==56;)A.push(0);for(let y=7;y>=0;y--)A.push(V/Math.pow(2,y*8)&255);for(let y=0;y<A.length;y+=64){let E=[];for(let p=0;p<16;p++)E[p]=A[y+p*4]<<24|A[y+p*4+1]<<16|A[y+p*4+2]<<8|A[y+p*4+3];for(let p=16;p<64;p++){let Ue=T(E[p-15],7)^T(E[p-15],18)^E[p-15]>>>3,Pe=T(E[p-2],17)^T(E[p-2],19)^E[p-2]>>>10;E[p]=E[p-16]+Ue+E[p-7]+Pe>>>0}let[I,K,J,Ie,M,Z,ee,Me]=[r,n,s,o,i,a,d,u];for(let p=0;p<64;p++){let Ue=T(M,6)^T(M,11)^T(M,25),Pe=M&Z^~M&ee,pt=Me+Ue+Pe+e[p]+E[p]>>>0,$r=T(I,2)^T(I,13)^T(I,22),Lr=I&K^I&J^K&J,jr=$r+Lr>>>0;[Me,ee,Z,M,Ie,J,K,I]=[ee,Z,M,Ie+pt>>>0,J,K,I,pt+jr>>>0]}r=r+I>>>0,n=n+K>>>0,s=s+J>>>0,o=o+Ie>>>0,i=i+M>>>0,a=a+Z>>>0,d=d+ee>>>0,u=u+Me>>>0}let g=new Uint8Array(32),O=new DataView(g.buffer);return[r,n,s,o,i,a,d,u].forEach((y,E)=>O.setUint32(E*4,y)),g}function T(t,e){return t>>>e|t<<32-e}function bt(t){if(typeof TextEncoder<"u")return new TextEncoder().encode(t);let e=new Uint8Array(t.length);for(let r=0;r<t.length;r++)e[r]=t.charCodeAt(r)&255;return e}function Gr(t){return Array.from(t).map(e=>e.toString(16).padStart(2,"0")).join("")}function Wr(t,e){let n=bt(t);n.length>64&&(n=De(n));let s=new Uint8Array(64),o=new Uint8Array(64);for(let l=0;l<64;l++)s[l]=(n[l]??0)^54,o[l]=(n[l]??0)^92;let i=bt(e),a=new Uint8Array(64+i.length);a.set(s),a.set(i,64);let d=De(a),u=new Uint8Array(96);return u.set(o),u.set(d,64),Gr(De(u))}var N=class extends Error{constructor(e){super(e),this.name="GateError"}},se=class{threshold;constructor(e=.8){if(e<0||e>1)throw new N(`threshold must be in [0.0, 1.0] \u2014 got ${e}`);this.threshold=e}allows(e){return e>=this.threshold}margin(e){return e-this.threshold}assert(e,r){if(!this.allows(e)){let n=r?` for action '${r}'`:"";throw new N(`Confidence ${e}${n} is below threshold ${this.threshold}`)}}},oe=class{_pending=new Map;request(e,r={}){let n=ne();return this._pending.set(n,{token:n,action:e,context:r,createdAt:new Date().toISOString(),status:"pending"}),n}approve(e){let r=this._pending.get(e);if(!r)throw new N(`Unknown token: ${e}`);r.status="approved"}deny(e,r){let n=this._pending.get(e);if(!n)throw new N(`Unknown token: ${e}`);n.status="denied",r&&(n.reason=r)}check(e){let r=this._pending.get(e);if(!r)throw new N(`Unknown token: ${e}`);return r.status}get pendingApprovals(){return Array.from(this._pending.values()).filter(e=>e.status==="pending")}getApproval(e){return this._pending.get(e)}clearResolved(){for(let[e,r]of this._pending.entries())r.status!=="pending"&&this._pending.delete(e)}};var ie=class extends Error{constructor(e){super(e),this.name="AuditError"}};function Yr(t,e,r,n,s){let o=JSON.stringify({recordId:t,action:e,robotUri:r,timestamp:n,params:s},Object.keys({recordId:t,action:e,robotUri:r,timestamp:n,params:s}).sort());return $e("rcan-content-hash",o)}function At(t,e){let{hmac:r,...n}=e,s=JSON.stringify(n,Object.keys(n).sort());return $e(t,s)}var F=class t{recordId;action;robotUri;confidence;modelIdentity;params;safetyApproved;timestamp;contentHash;previousHash;hmac;constructor(e){this.recordId=e.recordId,this.action=e.action,this.robotUri=e.robotUri,this.confidence=e.confidence,this.modelIdentity=e.modelIdentity,this.params=e.params,this.safetyApproved=e.safetyApproved,this.timestamp=e.timestamp,this.contentHash=e.contentHash,this.previousHash=e.previousHash,this.hmac=e.hmac}static create(e,r,n=null){let s=ne(),o=new Date().toISOString(),i=e.params??{},a=e.robotUri??"",d=Yr(s,e.action,a,o,i),u={recordId:s,action:e.action,robotUri:a,confidence:e.confidence,modelIdentity:e.modelIdentity,params:i,safetyApproved:e.safetyApproved??!0,timestamp:o,contentHash:d,previousHash:n,hmac:""};return u.hmac=At(r,u),new t(u)}verify(e){return At(e,this.toJSON())===this.hmac}toJSON(){return{recordId:this.recordId,action:this.action,robotUri:this.robotUri,confidence:this.confidence,modelIdentity:this.modelIdentity,params:this.params,safetyApproved:this.safetyApproved,timestamp:this.timestamp,contentHash:this.contentHash,previousHash:this.previousHash,hmac:this.hmac}}static fromJSON(e){return new t(e)}},ae=class t{_records=[];_secret;constructor(e){this._secret=e}get records(){return this._records}append(e){let n=this._records[this._records.length-1]?.contentHash??null,s=F.create(e,this._secret,n);return this._records.push(s),s}verifyAll(){let e=[],r=null;for(let n of this._records)n.verify(this._secret)||e.push(`HMAC invalid for record ${n.recordId.slice(0,8)}`),r!==null&&n.previousHash!==r&&e.push(`Chain broken at ${n.recordId.slice(0,8)}: expected prev=${r.slice(0,12)}`),r=n.contentHash;return{valid:e.length===0,count:this._records.length,errors:e}}toJSONL(){return this._records.map(e=>JSON.stringify(e.toJSON())).join(`
2
2
  `)+`
3
- `}static fromJSONL(e,n){let r=new t(n),s=e.trim().split(`
4
- `).filter(o=>o.trim()!=="");for(let o of s){let i=JSON.parse(o);r._records.push($.fromJSON(i))}return r}};function Ie(){return{ok:!0,issues:[],warnings:[],info:[]}}function v(t,e){t.ok=!1,t.issues.push(e)}function P(t,e){t.warnings.push(e)}function b(t,e){t.info.push(e)}function ct(t){let e=Ie();try{let n=M.parse(t);b(e,"\u2705 Valid RCAN URI"),b(e,` Registry: ${n.registry}`),b(e,` Manufacturer: ${n.manufacturer}`),b(e,` Model: ${n.model}`),b(e,` Version: ${n.version}`),b(e,` Device ID: ${n.deviceId}`)}catch(n){v(e,`Invalid RCAN URI: ${n instanceof Error?n.message:n}`)}return e}function dt(t){let e=Ie(),n;if(typeof t=="string")try{n=JSON.parse(t)}catch{return v(e,"Invalid JSON string"),e}else if(typeof t=="object"&&t!==null)n=t;else return v(e,"Expected object or JSON string"),e;for(let r of["rcan","cmd","target"])(!(r in n)||!n[r])&&v(e,`Missing required field: '${r}'`);if(!e.ok)return e;try{let r=l.fromJSON(n);b(e,`\u2705 RCAN message valid (v${r.rcan})`),b(e,` cmd: ${r.cmd}`),b(e,` target: ${r.target}`),r.confidence!==void 0?b(e,` confidence: ${r.confidence}`):P(e,"No confidence score \u2014 add for RCAN \xA716 AI accountability"),r.isSigned?b(e,` signature: alg=${r.signature?.alg}, kid=${r.signature?.kid}`):P(e,"Message is unsigned (recommended for production)")}catch(r){v(e,`Message validation failed: ${r instanceof Error?r.message:r}`)}return e}function ut(t){let e=Ie(),n=t.metadata??{},r=t.agent??{},s=t.rcan_protocol??{};for(let i of["rcan_version","metadata","agent"])(!(i in t)||t[i]===void 0||t[i]===null)&&v(e,`Missing required key: '${i}'`);let o=t.rcan_version;if(o&&(/^\d+\.\d+$/.test(o)||v(e,`rcan_version '${o}' must match pattern N.N (e.g. '1.2')`)),n.manufacturer||v(e,"L1: metadata.manufacturer is required (\xA72)"),n.model||v(e,"L1: metadata.model is required (\xA72)"),!n.device_id&&!n.robot_name&&v(e,"L1: metadata.device_id (or robot_name) is required (\xA72)"),s.jwt_auth?.enabled||P(e,"L2: jwt_auth not enabled (required for L2 conformance, \xA78)"),(!r.confidence_gates||r.confidence_gates.length===0)&&P(e,"L2: confidence_gates not configured (\xA716)"),(!r.hitl_gates||r.hitl_gates.length===0)&&P(e,"L3: hitl_gates not configured (\xA716)"),r.commitment_chain?.enabled||P(e,"L3: commitment_chain not enabled (\xA716)"),n.rrn?b(e,`\u2705 RRN registered: ${n.rrn}`):P(e,"Robot not registered \u2014 visit rcan.dev/registry/register"),e.ok&&e.issues.length===0){let i=!e.warnings.some(f=>f.startsWith("L1")),a=i&&!e.warnings.some(f=>f.startsWith("L2")),u=a&&!e.warnings.some(f=>f.startsWith("L3"))?"L3":a?"L2":i?"L1":"FAIL";b(e,`\u2705 Config valid \u2014 conformance level: ${u}`)}return e}var _=class extends Error{constructor(e){super(e),this.name="RCANError",Object.setPrototypeOf(this,new.target.prototype)}},re=class extends _{constructor(e){super(e),this.name="RCANAddressError",Object.setPrototypeOf(this,new.target.prototype)}},se=class extends _{constructor(e){super(e),this.name="RCANValidationError",Object.setPrototypeOf(this,new.target.prototype)}},oe=class extends _{constructor(n,r,s,o){super(n);this.gateType=r;this.value=s;this.threshold=o;this.name="RCANGateError",Object.setPrototypeOf(this,new.target.prototype)}},ie=class extends _{constructor(e){super(e),this.name="RCANSignatureError",Object.setPrototypeOf(this,new.target.prototype)}},D=class extends _{constructor(e){super(e),this.name="RCANRegistryError",Object.setPrototypeOf(this,new.target.prototype)}},L=class t extends _{constructor(n,r){super(n);this.nodeUrl=r;this.name="RCANNodeError",Object.setPrototypeOf(this,t.prototype)}},k=class t extends L{constructor(n,r){super(`RRN not found in federation: ${n}`,r);this.rrn=n;this.name="RCANNodeNotFoundError",Object.setPrototypeOf(this,t.prototype)}},R=class t extends L{constructor(n,r,s){super(n,r);this.cause=s;this.name="RCANNodeSyncError",Object.setPrototypeOf(this,t.prototype)}},j=class t extends L{reason;constructor(e,n){super(`Node trust verification failed: ${e}`,n),this.name="RCANNodeTrustError",this.reason=e,Object.setPrototypeOf(this,t.prototype)}},ae=class t extends _{constructor(e,n){super(`VERSION_INCOMPATIBLE: incoming=${e}, local=${n}`),this.name="RCANVersionIncompatibleError",Object.setPrototypeOf(this,t.prototype)}},ce=class t extends _{constructor(e){super(`REPLAY_DETECTED: ${e}`),this.name="RCANReplayAttackError",Object.setPrototypeOf(this,t.prototype)}},de=class t extends _{constructor(e){super(`DELEGATION_CHAIN_ERROR: ${e}`),this.name="RCANDelegationChainError",Object.setPrototypeOf(this,t.prototype)}},ue=class t extends _{constructor(e){super(`CONFIG_AUTH_ERROR: ${e}`),this.name="RCANConfigAuthorizationError",Object.setPrototypeOf(this,t.prototype)}};var gn="https://rcan-spec.pages.dev",fe=class{baseUrl;apiKey;timeout;constructor(e){this.baseUrl=(e?.baseUrl??gn).replace(/\/$/,""),this.apiKey=e?.apiKey,this.timeout=e?.timeout??1e4}async _fetch(e,n={}){let r=`${this.baseUrl}${e}`,s=new AbortController,o=setTimeout(()=>s.abort(),this.timeout);try{return await fetch(r,{...n,signal:s.signal,headers:{"Content-Type":"application/json",...n.headers??{}}})}finally{clearTimeout(o)}}_authHeaders(){if(!this.apiKey)throw new D("API key required for write operations. Pass apiKey to RegistryClient.");return{Authorization:`Bearer ${this.apiKey}`}}async _checkResponse(e){if(!e.ok){let n=`Registry API error: ${e.status}`;try{let r=await e.json();r?.error&&(n=r.error)}catch{}throw new D(n)}return await e.json()}async register(e){let n=await this._fetch("/api/v1/robots",{method:"POST",body:JSON.stringify(e)});return this._checkResponse(n)}async get(e){let n=await this._fetch(`/api/v1/robots/${encodeURIComponent(e)}`);return this._checkResponse(n)}async list(e){let n=new URLSearchParams;e?.limit!==void 0&&n.set("limit",String(e.limit)),e?.offset!==void 0&&n.set("offset",String(e.offset)),e?.tier&&n.set("tier",e.tier);let r=n.toString()?`?${n}`:"",s=await this._fetch(`/api/v1/robots${r}`);return this._checkResponse(s)}async patch(e,n){let r=await this._fetch(`/api/v1/robots/${encodeURIComponent(e)}`,{method:"PATCH",headers:this._authHeaders(),body:JSON.stringify(n)});return this._checkResponse(r)}async delete(e){let n=await this._fetch(`/api/v1/robots/${encodeURIComponent(e)}`,{method:"DELETE",headers:this._authHeaders()});n.ok||await this._checkResponse(n)}async search(e){let n=new URLSearchParams;e.q&&n.set("q",e.q),e.manufacturer&&n.set("manufacturer",e.manufacturer),e.model&&n.set("model",e.model),e.tier&&n.set("tier",e.tier);let r=n.toString()?`?${n}`:"",s=await this._fetch(`/api/v1/robots/search${r}`);if(!s.ok){let i=await this._fetch(`/api/v1/robots${r}`),a=await this._checkResponse(i);return"robots"in a?a.robots:"results"in a&&a.results?a.results:[]}let o=await s.json();return Array.isArray(o)?o:"results"in o&&o.results?o.results:"robots"in o?o.robots:[]}};var pn="https://rcan.dev",hn="/.well-known/rcan-node.json",yn=new Set(["root","authoritative","resolver","cache"]);function Rn(t){let e=t.match(/^RRN-([A-Z0-9]{2,8})-(\d{8,16})$/);if(e)return{type:"delegated",prefix:e[1],serial:e[2]};let n=t.match(/^RRN-(\d{8,16})$/);return n?{type:"root",serial:n[1]}:null}var le=class{rootUrl;timeoutMs;constructor(e=pn,n=1e4){this.rootUrl=e.replace(/\/$/,""),this.timeoutMs=n}async _fetch(e){let n=new AbortController,r=setTimeout(()=>n.abort(),this.timeoutMs);try{return await globalThis.fetch(e,{signal:n.signal})}catch(s){throw s instanceof Error&&s.name==="AbortError"?new R(`Request timed out: ${e}`,e,s):new R(`Network error fetching ${e}: ${s.message}`,e,s instanceof Error?s:void 0)}finally{clearTimeout(r)}}async getNodeManifest(e){let n=`${e.replace(/\/$/,"")}${hn}`,r=await this._fetch(n);if(!r.ok)throw r.status===404?new k(n,e):new R(`Failed to fetch node manifest from ${e}: HTTP ${r.status}`,e);let s;try{s=await r.json()}catch(o){throw new R(`Invalid JSON in node manifest from ${e}`,e,o instanceof Error?o:void 0)}if(!this.verifyNode(s))throw new j("missing_pubkey",e);return s}async listNodes(e){let n=e?`?prefix=${encodeURIComponent(e)}`:"",r=`${this.rootUrl}/api/v1/nodes${n}`,s=await this._fetch(r);if(!s.ok)throw new R(`Failed to list nodes from ${r}: HTTP ${s.status}`,r);let o;try{o=await s.json()}catch(i){throw new R(`Invalid JSON in nodes list from ${r}`,r,i instanceof Error?i:void 0)}return Array.isArray(o)?o:o&&typeof o=="object"&&"nodes"in o?o.nodes:[]}async discover(e){let n=Rn(e);if(!n)throw new k(e,this.rootUrl);if(n.type==="root")return this.getNodeManifest(this.rootUrl);let r=await this.listNodes(n.prefix);if(r.length===0)throw new k(e,this.rootUrl);return r[0]}async resolve(e){let n=`${this.rootUrl}/api/v1/resolve/${encodeURIComponent(e)}`,r;try{r=await this._fetch(n)}catch(a){throw a}if(r.ok)try{return await r.json()}catch(a){throw new R(`Invalid JSON in resolve response for ${e}`,this.rootUrl,a instanceof Error?a:void 0)}if(r.status!==404)throw new R(`Unexpected HTTP ${r.status} resolving ${e}`,this.rootUrl);let s=await this.discover(e),o=`${s.api_base.replace(/\/$/,"")}/robots/${encodeURIComponent(e)}`,i=await this._fetch(o);if(!i.ok)throw i.status===404?new k(e,s.api_base):new R(`HTTP ${i.status} from authoritative node for ${e}`,s.api_base);try{return await i.json()}catch(a){throw new R(`Invalid JSON in fallback resolve response for ${e}`,s.api_base,a instanceof Error?a:void 0)}}verifyNode(e){if(!e||typeof e!="object")return!1;let n=e;return!(typeof n.rcan_node_version!="string"||!n.rcan_node_version||typeof n.node_type!="string"||!yn.has(n.node_type)||typeof n.operator!="string"||!n.operator||typeof n.namespace_prefix!="string"||!n.namespace_prefix||typeof n.public_key!="string"||!n.public_key.startsWith("ed25519:")||typeof n.api_base!="string"||!n.api_base.startsWith("https://"))}};var _n="https://rcan.dev/schemas",Ue=new Map;async function me(t){if(Ue.has(t))return Ue.get(t);try{let e=new AbortController,n=setTimeout(()=>e.abort(),5e3);n.unref?.();let r=await fetch(`${_n}/${t}`,{signal:e.signal});if(clearTimeout(n),!r.ok)return null;let s=await r.json();return Ue.set(t,s),s}catch{return null}}async function ft(t){let e=await me("rcan-config.schema.json");if(!e)return{valid:!0,skipped:!0};let n=[];if(typeof t!="object"||t===null)return{valid:!1,errors:["Config must be an object"]};let r=t,s=e.required??[];for(let o of s)o in r||n.push(`Missing required field: ${o}`);return n.length===0?{valid:!0}:{valid:!1,errors:n}}async function lt(t){let e=await me("rcan-node.schema.json");if(!e)return{valid:!0,skipped:!0};let n=[];if(typeof t!="object"||t===null)return{valid:!1,errors:["Manifest must be an object"]};let r=t,s=e.required??[];for(let o of s)o in r||n.push(`Missing required field: ${o}`);return n.length===0?{valid:!0}:{valid:!1,errors:n}}var Me=(r=>(r[r.FIRE_AND_FORGET=0]="FIRE_AND_FORGET",r[r.ACKNOWLEDGED=1]="ACKNOWLEDGED",r[r.EXACTLY_ONCE=2]="EXACTLY_ONCE",r))(Me||{}),ge=class t extends Error{constructor(e){super(`ACK timeout for message ${e} \u2014 safety halt required`),this.name="QoSAckTimeoutError",Object.setPrototypeOf(this,t.prototype)}},pe=class{_send;_waitForAck;constructor(e,n){this._send=e,this._waitForAck=n}async sendWithQoS(e,n={}){let r=n.qos??0,s=n.maxRetries??3,o=n.initialBackoffMs??100,i=n.ackTimeoutMs??500;if(r===0)return await this._send(e),{delivered:!0,attempts:1,reason:"fire-and-forget"};let a=e.message_id??e.msg_id??"unknown",d=0,u=o;for(;d<=s;){if(await this._send(e),d++,await this._waitForAck(a,i))return{delivered:!0,attempts:d,reason:r===2?"exactly-once":"acknowledged"};if(d>s)break;await bn(u),u=Math.min(u*2,5e3)}return{delivered:!1,attempts:d,reason:`ACK not received after ${s} retries`}}};function mt(t,e){return{message_type:6,ruri:t,safety_event:"ESTOP",reason:e.slice(0,512),timestamp_ms:Date.now(),message_id:Sn(),qos:2}}function Sn(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();let t=Array.from({length:16},()=>Math.floor(Math.random()*256));t[6]=t[6]&15|64,t[8]=t[8]&63|128;let e=t.map(n=>n.toString(16).padStart(2,"0"));return`${e.slice(0,4).join("")}-${e.slice(4,6).join("")}-${e.slice(6,8).join("")}-${e.slice(8,10).join("")}-${e.slice(10).join("")}`}function bn(t){return new Promise(e=>setTimeout(e,t))}var Pe=6;function he(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();let t=Array.from({length:16},()=>Math.floor(Math.random()*256));t[6]=t[6]&15|64,t[8]=t[8]&63|128;let e=t.map(n=>n.toString(16).padStart(2,"0"));return`${e.slice(0,4).join("")}-${e.slice(4,6).join("")}-${e.slice(6,8).join("")}-${e.slice(8,10).join("")}-${e.slice(10).join("")}`}function gt(t,e){return{message_type:6,ruri:t,safety_event:"ESTOP",reason:e.slice(0,512),timestamp_ms:Date.now(),message_id:he(),qos:2}}function pt(t,e){return{message_type:6,ruri:t,safety_event:"STOP",reason:e.slice(0,512),timestamp_ms:Date.now(),message_id:he()}}function ht(t,e){return{message_type:6,ruri:t,safety_event:"RESUME",reason:e.slice(0,512),timestamp_ms:Date.now(),message_id:he()}}function yt(t){return typeof t=="object"&&t!==null&&t.message_type===Pe}function Rt(t){let e=[];return t.message_type!==6&&e.push("message_type must be 6"),t.ruri||e.push("ruri is required"),["ESTOP","STOP","RESUME"].includes(t.safety_event??"")||e.push("safety_event must be ESTOP, STOP, or RESUME"),(!t.reason||t.reason.length===0)&&e.push("reason is required"),t.message_id||e.push("message_id is required"),(!t.timestamp_ms||t.timestamp_ms<=0)&&e.push("timestamp_ms must be positive"),e}function _t(t,e,n){return{message_type:11,ruri:t,disclosure:e,timestamp_ms:Date.now(),message_id:he(),delegation_chain:n}}var ye=class{windowSeconds;maxSize;_seen;constructor(e=30,n=1e4){this.windowSeconds=e,this.maxSize=n,this._seen=new Map}checkAndRecord(e,n,r=!1){let s=Date.now();this._evict(s);let o=r?Math.min(this.windowSeconds,10):this.windowSeconds,i=Cn(n);if(i===null)return{allowed:!1,reason:`invalid timestamp format: ${n}`};let a=s-i,d=o*1e3;if(a>d)return{allowed:!1,reason:`message too old: age=${Math.round(a/1e3)}s > window=${o}s`};if(i>s+5e3)return{allowed:!1,reason:"message timestamp is in the future"};if(this._seen.has(e))return{allowed:!1,reason:`replay detected: msg_id ${e} already seen`};if(this._seen.size>=this.maxSize){let f=this._seen.keys().next().value;this._seen.delete(f)}let u=s+d;return this._seen.set(e,u),{allowed:!0,reason:"ok"}}_evict(e){for(let[n,r]of this._seen)r<=e&&this._seen.delete(n)}get size(){return this._seen.size}};function St(t,e){let n=t,r=n.message_id??n.msg_id;if(!r)return{valid:!1,reason:"missing message_id / msg_id"};let s;if(typeof n.timestamp_ms=="number"?s=String(n.timestamp_ms/1e3):n.timestamp!==void 0&&(s=String(n.timestamp)),!s)return{valid:!1,reason:"missing timestamp"};let o=n.message_type===6||n.message_type===6,i=e.checkAndRecord(r,s,o);return{valid:i.allowed,reason:i.reason}}function Cn(t){if(t.includes("T")||t.includes("-")){let n=new Date(t);if(!isNaN(n.getTime()))return n.getTime()}let e=parseFloat(t);return isNaN(e)?null:e>1e12?e:e*1e3}var H=class t extends Error{offsetSeconds;constructor(e,n){super(`Clock drift too large: offset=${e.toFixed(3)}s > max=${n}s`),this.name="ClockDriftError",this.offsetSeconds=e,Object.setPrototypeOf(this,t.prototype)}};async function De(t){let e=t??"https://worldtimeapi.org/api/ip";try{let n=Date.now(),r=await fetch(e,{method:"HEAD",signal:AbortSignal.timeout(3e3)}),s=Date.now(),o=r.headers.get("Date")??r.headers.get("date");if(!o)return{synchronized:!0,offsetSeconds:0,source:"assumed (no Date header)"};let i=new Date(o).getTime();if(isNaN(i))return{synchronized:!0,offsetSeconds:0,source:"assumed (unparseable Date header)"};let d=((n+s)/2-i)/1e3;return{synchronized:Math.abs(d)<=5,offsetSeconds:d,source:e}}catch{return{synchronized:!0,offsetSeconds:0,source:"assumed (network unavailable)"}}}async function bt(t=5){let e=await De();if(!e.synchronized||Math.abs(e.offsetSeconds)>t)throw new H(e.offsetSeconds,t)}async function An(t){let e=JSON.stringify(t,Object.keys(t).sort());if(typeof crypto<"u"&&crypto.subtle){let r=new TextEncoder().encode(e),s=await crypto.subtle.digest("SHA-256",r);return Array.from(new Uint8Array(s)).map(o=>o.toString(16).padStart(2,"0")).join("")}let n=2166136261;for(let r=0;r<e.length;r++)n^=e.charCodeAt(r),n=n*16777619>>>0;return n.toString(16).padStart(8,"0")}async function Ct(t,e,n,r="rcan://local/config",s=!1){let o=await An(t);return new l({rcan:h,cmd:"CONFIG_UPDATE",target:r,params:{message_type:5,diff:t,rollback:n,scope:e,config_hash:o,safety_overrides:s}})}function At(t){let e=t.params;return!e.diff||typeof e.diff!="object"?{valid:!1,reason:"missing required field: params.diff"}:!e.config_hash||typeof e.config_hash!="string"?{valid:!1,reason:"missing required field: params.config_hash"}:"rollback"in e?e.safety_overrides===!0&&e.scope!=="creator"?{valid:!1,reason:"safety_overrides=true requires scope=creator (owner is insufficient)"}:{valid:!0,reason:"ok"}:{valid:!1,reason:"missing required field: params.rollback"}}function En(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2)}`}var Re=class{_keys=[];addKey(e){this._keys.push(e)}getJWKS(){return{keys:[...this._keys]}}findKey(e){return this._keys.find(n=>n.kid===e)}isKeyValid(e,n){let r=this.findKey(e);if(!r)return!1;let s=(n??Date.now())/1e3;return!(r.revoked_at!==void 0&&r.revoked_at<=s||r.exp!==void 0&&r.exp<s)}expireKey(e,n){let r=this.findKey(e);r&&(r.exp=n??Math.floor(Date.now()/1e3))}revokeKey(e){let n=this.findKey(e);n&&(n.revoked_at=Math.floor(Date.now()/1e3))}validKeys(e){return this._keys.filter(n=>this.isKeyValid(n.kid,e))}};function Et(t,e,n=120,r="rcan://local/keys"){let s=En().slice(0,8);return new l({rcan:h,cmd:"KEY_ROTATION",target:r,params:{message_type:5,new_public_key:t,new_kid:s,old_kid:e,overlap_seconds:n,initiated_at:new Date().toISOString()},keyId:s})}function xn(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2)}`}function _e(t){let e=t.requestId??xn();return new l({rcan:h,cmd:"CONSENT_REQUEST",target:t.targetRuri,params:{message_type:20,requester_ruri:t.requesterRuri,requester_owner:t.requesterOwner,target_ruri:t.targetRuri,requested_scopes:t.requestedScopes,duration_hours:t.durationHours,justification:t.justification,request_id:e,consent_type:t.consentType??"cross_robot",data_categories:t.dataCategories??[]}})}function Se(t){let e=t.expiresAt??new Date(Date.now()+864e5).toISOString();return new l({rcan:h,cmd:"CONSENT_GRANT",target:"rcan://local/consent",params:{message_type:21,request_id:t.requestId,granted_scopes:t.grantedScopes??[],expires_at:e,reason:t.reason??"approved"}})}function be(t){return new l({rcan:h,cmd:"CONSENT_DENY",target:"rcan://local/consent",params:{message_type:22,request_id:t.requestId,reason:t.reason??"denied"}})}function xt(t){let e=t.cmd,n=t.params,r=n.message_type;return e==="CONSENT_REQUEST"?r!==20?{valid:!1,reason:"message_type must be CONSENT_REQUEST (20)"}:n.requester_ruri?n.target_ruri?!n.requested_scopes||!Array.isArray(n.requested_scopes)||n.requested_scopes.length===0?{valid:!1,reason:"requested_scopes must be a non-empty array"}:n.request_id?n.justification?{valid:!0,reason:"ok"}:{valid:!1,reason:"missing justification"}:{valid:!1,reason:"missing request_id"}:{valid:!1,reason:"missing target_ruri"}:{valid:!1,reason:"missing requester_ruri"}:e==="CONSENT_GRANT"?r!==21?{valid:!1,reason:"message_type must be CONSENT_GRANT (21)"}:n.request_id?n.expires_at?{valid:!0,reason:"ok"}:{valid:!1,reason:"missing expires_at"}:{valid:!1,reason:"missing request_id"}:e==="CONSENT_DENY"?r!==22?{valid:!1,reason:"message_type must be CONSENT_DENY (22)"}:n.request_id?{valid:!0,reason:"ok"}:{valid:!1,reason:"missing request_id"}:{valid:!1,reason:`unknown consent command: ${e}`}}var wn=3600*1e3,K=class{_cache=new Map;get(e,n){let r=this._cache.get(e);if(!r)return;let s=n??Date.now();if(r.cachedUntil!==void 0&&r.cachedUntil<s){this._cache.delete(e);return}return r}set(e,n){let r=n??Date.now();this._cache.set(e.rrn,{...e,cachedUntil:r+wn})}invalidate(e){this._cache.delete(e)}get size(){return this._cache.size}};async function wt(t,e,n){let r=n??new K,s=r.get(t);if(s)return s;let o=`${e.replace(/\/$/,"")}/api/v1/robots/${encodeURIComponent(t)}/revocation-status`;try{let i=await fetch(o,{signal:AbortSignal.timeout(5e3)});if(!i.ok){let u={rrn:t,status:"active",reason:`registry returned ${i.status}`};return r.set(u),u}let a=await i.json(),d={rrn:t,status:a.status??"active",revokedAt:a.revokedAt,reason:a.reason,authority:a.authority};return r.set(d),d}catch{return{rrn:t,status:"active",reason:"network unavailable"}}}function vt(t,e){return new l({rcan:h,cmd:"ROBOT_REVOCATION",target:"rcan://broadcast/revocation",params:{message_type:19,rrn:t,reason:e,revoked_at:new Date().toISOString()}})}var Le=(o=>(o.VIDEO="video",o.AUDIO="audio",o.LOCATION="location",o.BIOMETRIC="biometric",o.TELEMETRY="telemetry",o))(Le||{});function Nt(t){return _e({requesterRuri:t.requesterRuri,requesterOwner:t.requesterOwner,targetRuri:t.targetRuri,requestedScopes:["training_data"],durationHours:t.durationHours,justification:t.justification,requestId:t.requestId,consentType:"training_data",dataCategories:t.dataCategories})}function Ot(t){return Se(t)}function kt(t){return be(t)}function Tt(t){if(t.params.message_type!==36)return{valid:!1,reason:"not a TRAINING_DATA message"};let e=t.params.consent_token;return!e||typeof e!="string"||e.trim()===""?{valid:!1,reason:"TRAINING_DATA message missing consent_token (\xA717)"}:{valid:!0,reason:"ok"}}var Ce=class{crossOwnerGraceS;keyTtlS;_cachedKeys=[];constructor(e=3600,n=86400){this.crossOwnerGraceS=e,this.keyTtlS=n}canAcceptCommand(e,n,r,s=!0,o=!1,i,a){if(e&&e.message_type===6&&e.safety_event==="ESTOP")return{allowed:!0,reason:"ESTOP always accepted (Protocol 66)"};if(!n)return{allowed:!0,reason:"online mode"};if(!r)return{allowed:!1,reason:"offline mode: cross-network commands blocked"};if(!s)return{allowed:!1,reason:"offline mode: only owner-role commands accepted from local network"};if(o&&i!==void 0){let u=((a??Date.now())-i)/1e3;if(u>this.crossOwnerGraceS)return{allowed:!1,reason:`offline mode: cross-owner grace period expired (${Math.round(u)}s > ${this.crossOwnerGraceS}s)`}}return{allowed:!0,reason:"offline mode: owner command on local network accepted"}}cacheKey(e,n){let r=n??Date.now();this._cachedKeys=this._cachedKeys.filter(s=>s.kid!==e.kid),this._cachedKeys.push({...e,cachedAtMs:r,ttlSeconds:this.keyTtlS})}getCachedKey(e,n){let r=n??Date.now(),s=this._cachedKeys.find(i=>i.kid===e);if(!s)return;if((r-s.cachedAtMs)/1e3>s.ttlSeconds){this._cachedKeys=this._cachedKeys.filter(i=>i.kid!==e);return}return s}getManifestFields(e,n){if(e===void 0)return{offline_mode:!1,offline_since_s:0};let r=n??Date.now();return{offline_mode:!0,offline_since_s:Math.round((r-e)/1e3)}}};var $e=(p=>(p.SENSOR_PROXIMITY_FAILURE="SENSOR_PROXIMITY_FAILURE",p.SENSOR_CAMERA_FAILURE="SENSOR_CAMERA_FAILURE",p.SENSOR_IMU_FAILURE="SENSOR_IMU_FAILURE",p.MOTOR_OVERCURRENT="MOTOR_OVERCURRENT",p.MOTOR_OVERTEMP="MOTOR_OVERTEMP",p.MOTOR_STALL="MOTOR_STALL",p.BATTERY_CRITICAL="BATTERY_CRITICAL",p.BATTERY_LOW="BATTERY_LOW",p.NETWORK_TIMEOUT="NETWORK_TIMEOUT",p.NETWORK_REGISTRY_UNREACHABLE="NETWORK_REGISTRY_UNREACHABLE",p.SAFETY_ESTOP_STUCK="SAFETY_ESTOP_STUCK",p.SAFETY_WATCHDOG_TIMEOUT="SAFETY_WATCHDOG_TIMEOUT",p.UNKNOWN="UNKNOWN",p))($e||{});function It(t){return new l({rcan:h,cmd:"FAULT_REPORT",target:t.target??"rcan://local/fault",params:{message_type:26,fault_code:t.faultCode,severity:t.severity,subsystem:t.subsystem,affects_safety:t.affectsSafety,safe_to_continue:t.safeToContinue,description:t.description??"",reported_at:new Date().toISOString()}})}var Ae=(r=>(r[r.ANONYMOUS=1]="ANONYMOUS",r[r.EMAIL_VERIFIED=2]="EMAIL_VERIFIED",r[r.HARDWARE_TOKEN=3]="HARDWARE_TOKEN",r))(Ae||{}),je={minLoaDiscover:1,minLoaStatus:1,minLoaChat:1,minLoaControl:1,minLoaSafety:1},Ut={minLoaDiscover:1,minLoaStatus:1,minLoaChat:1,minLoaControl:2,minLoaSafety:3};function Ee(t){try{let e=t.split(".");if(e.length<2)return 1;let n=(e[1]??"").replace(/-/g,"+").replace(/_/g,"/"),r=n+"=".repeat((4-n.length%4)%4),s;typeof atob<"u"?s=atob(r):s=Buffer.from(r,"base64").toString("utf-8");let i=JSON.parse(s).loa;if(typeof i=="number"&&i>=1&&i<=3)return i}catch{}return 1}function vn(t,e){switch(t.toLowerCase()){case"discover":return e.minLoaDiscover;case"status":return e.minLoaStatus;case"chat":return e.minLoaChat;case"contribute":return e.minLoaChat;case"control":return e.minLoaControl;case"safety":return e.minLoaSafety;default:return null}}function Mt(t,e,n=je){let r=vn(e,n);return r===null?{valid:!0,reason:"unknown scope; allowed by default"}:t>=r?{valid:!0,reason:"ok"}:{valid:!1,reason:`LOA_INSUFFICIENT: scope=${e} requires LoA>=${r}, caller has LoA=${t}`}}var qe=(r=>(r.ROOT="root",r.AUTHORITATIVE="authoritative",r.COMMUNITY="community",r))(qe||{}),Be=(r=>(r.CONSENT="consent",r.REVOCATION="revocation",r.KEY="key",r))(Be||{}),Nn=1440*60*1e3,xe=class{store=new Map;set(e){this.store.set(e.registryUrl,{identity:e,expiresAt:Date.now()+Nn})}lookup(e){let n=this.store.get(e);if(n){if(Date.now()>n.expiresAt){this.store.delete(e);return}return n.identity}}async discoverViaDns(e){let n=`_rcan-registry.${e}`,r;try{r=await Q("dns").promises.resolveTxt(n)}catch{return}for(let s of r){let o=s.join("");try{let i=JSON.parse(o);if(i.registryUrl&&i.tier&&i.publicKeyPem&&i.domain){let a={registryUrl:i.registryUrl,tier:i.tier,publicKeyPem:i.publicKeyPem,domain:i.domain,verifiedAt:new Date().toISOString()};return this.set(a),a}}catch{}}}async verifyRegistryJwt(e,n){let r=this.lookup(n);if(!r)throw new Error(`REGISTRY_UNKNOWN: ${n} is not in the trust cache`);let s;try{let i=(e.split(".")[1]??"").replace(/-/g,"+").replace(/_/g,"/"),a=i+"=".repeat((4-i.length%4)%4),d;typeof atob<"u"?d=atob(a):d=Buffer.from(a,"base64").toString("utf-8");let u=JSON.parse(d);s=typeof u.iss=="string"?u.iss:void 0}catch{throw new Error("REGISTRY_JWT_MALFORMED: cannot decode token payload")}if(s!==n)throw new Error(`REGISTRY_JWT_ISS_MISMATCH: expected iss=${n}, got iss=${s??"(none)"}`);return r}};function On(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();let t=Array.from({length:16},()=>Math.floor(Math.random()*256));t[6]=(t[6]??0)&15|64,t[8]=(t[8]??0)&63|128;let e=t.map(n=>n.toString(16).padStart(2,"0"));return`${e.slice(0,4).join("")}-${e.slice(4,6).join("")}-${e.slice(6,8).join("")}-${e.slice(8,10).join("")}-${e.slice(10).join("")}`}function Pt(t,e,n,r){return new l({rcan:"1.6",rcanVersion:"1.6",cmd:"federation_sync",target:e,params:{msg_type:23,msg_id:On(),source_registry:t,target_registry:e,sync_type:n,payload:r},timestamp:new Date().toISOString()})}async function Dt(t,e,n){let r=t.params?.msg_type;if(r===6||r===6||t.cmd==="estop"||t.cmd==="ESTOP")return{valid:!0,reason:"ESTOP always permitted (P66 invariant)"};let o=t.params?.source_registry??t.params?.from_registry;if(!o||o===e)return{valid:!0,reason:"local registry; no federation check needed"};if(!n.lookup(o))return{valid:!1,reason:`REGISTRY_UNKNOWN: ${o} is not in the local trust cache`};let a=1,d=t.params?.registry_jwt;return d?a=Ee(d):typeof t.loa=="number"&&(a=t.loa),a<2?{valid:!1,reason:`LOA_INSUFFICIENT: cross-registry commands require LoA>=2 (EMAIL_VERIFIED), got LoA=${a}`}:{valid:!0,reason:"cross-registry command accepted"}}var E=class t extends Error{constructor(e){super(e),this.name="TransportError",Object.setPrototypeOf(this,t.prototype)}},Ke=(s=>(s.HTTP="http",s.COMPACT="compact",s.MINIMAL="minimal",s.BLE="ble",s))(Ke||{}),Fe={msg_type:"t",msg_id:"i",timestamp:"ts",from_rrn:"f",to_rrn:"to",scope:"s",payload:"p",signature:"sig"},Lt=Object.fromEntries(Object.entries(Fe).map(([t,e])=>[e,t]));function Ve(t){let e=t.toJSON(),n={};for(let[o,i]of Object.entries(e)){let a=Fe[o];n[a??o]=i}if(n.p&&typeof n.p=="object"){let o=n.p,i={};for(let[a,d]of Object.entries(o)){let u=Fe[a];i[u??a]=d}n.p=i}let r=JSON.stringify(n);return new TextEncoder().encode(r)}function Ye(t){let n=new TextDecoder().decode(t),r=JSON.parse(n),s={};for(let[o,i]of Object.entries(r)){let a=Lt[o];s[a??o]=i}if(s.payload&&typeof s.payload=="object"){let o=s.payload,i={};for(let[a,d]of Object.entries(o)){let u=Lt[a];i[u??a]=d}s.payload=i}return new l({rcan:s.rcan??"1.6",rcanVersion:s.rcanVersion,cmd:s.cmd,target:s.target,params:s.params??s.payload??{},timestamp:s.timestamp,confidence:s.confidence,signature:s.signature})}var Y=32,He=6;async function $t(t){let e=new TextEncoder().encode(t),n=new ArrayBuffer(e.byteLength);new Uint8Array(n).set(e);let s=await(globalThis.crypto?.subtle??(await import("crypto")).webcrypto.subtle).digest("SHA-256",n);return new Uint8Array(s)}async function jt(t){let e=t.params?.msg_type??0;if(e!==He)throw new E(`encodeMinimal only supports SAFETY (type 6) messages; got type=${e}`);let n=t.params?.from_rrn??t.target??"",r=t.params?.to_rrn??t.target??"",s=await $t(n),o=await $t(r),i=(t.signature?.sig??"").replace(/[^A-Za-z0-9+/=]/g,""),a;try{if(typeof atob<"u"){let N=atob(i.slice(0,16));a=new Uint8Array(N.length);for(let y=0;y<N.length;y++)a[y]=N.charCodeAt(y)}else a=Buffer.from(i.slice(0,16),"base64")}catch{a=new Uint8Array(8)}let u=(t.timestamp?Math.floor(new Date(t.timestamp).getTime()/1e3):Math.floor(Date.now()/1e3))>>>0,f=new Uint8Array(Y),q=new DataView(f.buffer);q.setUint16(0,He,!1),f.set(s.subarray(0,8),2),f.set(o.subarray(0,8),10),q.setUint32(18,u,!1);let C=new Uint8Array(8);C.set(a.subarray(0,Math.min(8,a.length))),f.set(C,22);let p=0;for(let N=0;N<30;N++)p^=f[N]??0;if(q.setUint16(30,p&65535,!1),f.length!==Y)throw new E(`encodeMinimal assertion failed: expected ${Y} bytes, got ${f.length}`);return f}function qt(t){if(t.length!==Y)throw new E(`decodeMinimal: expected ${Y} bytes, got ${t.length}`);let e=new DataView(t.buffer,t.byteOffset,t.byteLength),n=e.getUint16(0,!1),r=t.subarray(2,10),s=t.subarray(10,18),o=e.getUint32(18,!1),i=t.subarray(22,30),a=new Date(o*1e3).toISOString(),d=u=>Array.from(u).map(f=>f.toString(16).padStart(2,"0")).join("");return{params:{msg_type:n,from_hash:d(r),to_hash:d(s),timestamp_s:o,sig_truncated:d(i)},timestamp:a}}var kn=251,V=3;function Bt(t,e=kn){let n=Ve(t),r=e-V;if(r<=0)throw new E(`MTU ${e} is too small (need at least ${V+1})`);let s=Math.ceil(n.length/r),o=[];for(let i=0;i<s;i++){let a=n.subarray(i*r,(i+1)*r),d=new Uint8Array(V+a.length);d[0]=i,d[1]=s,d[2]=i===s-1?1:0,d.set(a,V),o.push(d)}return o}function Ft(t){if(t.length===0)throw new E("decodeBleFrames: no frames provided");let e=[...t].sort((a,d)=>(a[0]??0)-(d[0]??0)),n=e[0]?.[1]??e.length;if(e.length!==n)throw new E(`decodeBleFrames: expected ${n} frames, got ${e.length}`);let r=e.map(a=>a.subarray(V)),s=r.reduce((a,d)=>a+d.length,0),o=new Uint8Array(s),i=0;for(let a of r)o.set(a,i),i+=a.length;return Ye(o)}function Ht(t,e){let r=(e.params?.msg_type??0)===He,s=o=>t.includes(o);if(r){if(s("minimal"))return"minimal";if(s("ble"))return"ble";if(s("compact"))return"compact";if(s("http"))return"http"}else{if(s("http"))return"http";if(s("compact"))return"compact";if(s("ble"))return"ble"}throw new E(`No suitable transport available from: [${t.join(", ")}]`)}var Je=(n=>(n.BASE64="base64",n.REF="ref",n))(Je||{});function J(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();let t=Array.from({length:16},()=>Math.floor(Math.random()*256));t[6]=(t[6]??0)&15|64,t[8]=(t[8]??0)&63|128;let e=t.map(n=>n.toString(16).padStart(2,"0"));return`${e.slice(0,4).join("")}-${e.slice(4,6).join("")}-${e.slice(6,8).join("")}-${e.slice(8,10).join("")}-${e.slice(10).join("")}`}async function Ge(t){let e=globalThis.crypto?.subtle??(await import("crypto")).webcrypto.subtle,n=new ArrayBuffer(t.byteLength);new Uint8Array(n).set(t);let r=await e.digest("SHA-256",n),s=new Uint8Array(r);return Array.from(s).map(o=>o.toString(16).padStart(2,"0")).join("")}function Kt(t){if(typeof Buffer<"u")return Buffer.from(t).toString("base64");let e="";for(let n=0;n<t.length;n++)e+=String.fromCharCode(t[n]??0);return btoa(e)}function We(t,e){let n={...t.toJSON(),...e};return l.fromJSON(n)}async function ze(t,e,n){let r=await Ge(e),s=Kt(e),o={chunkId:J(),mimeType:n,encoding:"base64",hashSha256:r,dataB64:s,sizeBytes:e.length},i=t.mediaChunks??[];return We(t,{mediaChunks:[...i,o]})}function Vt(t,e,n,r,s){let o={chunkId:J(),mimeType:n,encoding:"ref",hashSha256:r,refUrl:e,sizeBytes:s},i=t.mediaChunks??[];return We(t,{mediaChunks:[...i,o]})}async function Yt(t){let e=t.mediaChunks??[];if(e.length===0)return{valid:!0,reason:"no media chunks"};for(let n=0;n<e.length;n++){let r=e[n];if(!r.chunkId)return{valid:!1,reason:`chunk[${n}]: missing chunkId`};if(!r.mimeType)return{valid:!1,reason:`chunk[${n}]: missing mimeType`};if(!r.hashSha256)return{valid:!1,reason:`chunk[${n}]: missing hashSha256`};if(r.sizeBytes<0)return{valid:!1,reason:`chunk[${n}]: sizeBytes must be >= 0`};if(r.encoding==="base64"){if(!r.dataB64)return{valid:!1,reason:`chunk[${n}]: BASE64 encoding requires dataB64`};let s;try{if(typeof Buffer<"u")s=Buffer.from(r.dataB64,"base64");else{let i=atob(r.dataB64);s=new Uint8Array(i.length);for(let a=0;a<i.length;a++)s[a]=i.charCodeAt(a)}}catch{return{valid:!1,reason:`chunk[${n}]: failed to decode base64 data`}}let o=await Ge(s);if(o!==r.hashSha256)return{valid:!1,reason:`chunk[${n}]: SHA-256 mismatch (expected ${r.hashSha256}, got ${o})`}}else if(r.encoding==="ref"){if(!r.refUrl)return{valid:!1,reason:`chunk[${n}]: REF encoding requires refUrl`}}else return{valid:!1,reason:`chunk[${n}]: unknown encoding '${r.encoding}'`}}return{valid:!0,reason:"ok"}}async function Jt(t){let e=new l({rcan:"1.6",rcanVersion:"1.6",cmd:"training_data",target:"rcan://training/data",params:{msg_type:36,msg_id:J()},timestamp:new Date().toISOString()});for(let n of t)e=await ze(e,n.data,n.mimeType);return e}async function Gt(t,e,n,r,s){let o=await Ge(e),i=Kt(e),a={chunkId:J(),mimeType:n,encoding:"base64",hashSha256:o,dataB64:i,sizeBytes:e.length},d={streamId:t,chunkIndex:r,isFinal:s,chunk:a},u=new l({rcan:"1.6",rcanVersion:"1.6",cmd:"stream_chunk",target:"rcan://streaming/chunk",params:{msg_type:29,msg_id:J(),stream_chunk:d},timestamp:new Date().toISOString()});return u=We(u,{mediaChunks:[a]}),u}var Qe=2.5,Tn=0;function In(){return`cr-${Date.now()}-${++Tn}`}function Wt(t={}){return{type:33,request_id:t.request_id??In(),project_id:t.project_id??"",project_name:t.project_name??"",work_unit_id:t.work_unit_id??"",resource_type:t.resource_type??"cpu",estimated_duration_s:t.estimated_duration_s??0,priority:t.priority??0,payload:t.payload??{},timestamp:t.timestamp??Date.now()/1e3}}function zt(t={}){let e={type:34,request_id:t.request_id??"",work_unit_id:t.work_unit_id??"",status:t.status??"completed",resource_type:t.resource_type??"cpu",duration_s:t.duration_s??0,compute_units:t.compute_units??0,result_payload:t.result_payload??{},timestamp:t.timestamp??Date.now()/1e3};return t.error_message!==void 0&&(e.error_message=t.error_message),e}function Qt(t={}){return{type:35,request_id:t.request_id??"",work_unit_id:t.work_unit_id??"",reason:t.reason??"",timestamp:t.timestamp??Date.now()/1e3}}function Xt(t,e="request"){return e==="request"||e==="result"?t>=Qe:e==="cancel"?t>=2:!1}function Zt(t){return t>=3}var Un="0.6.0",Mn="1.6";return un(Pn);})();
3
+ `}static fromJSONL(e,r){let n=new t(r),s=e.trim().split(`
4
+ `).filter(o=>o.trim()!=="");for(let o of s){let i=JSON.parse(o);n._records.push(F.fromJSON(i))}return n}};function Le(){return{ok:!0,issues:[],warnings:[],info:[]}}function v(t,e){t.ok=!1,t.issues.push(e)}function L(t,e){t.warnings.push(e)}function b(t,e){t.info.push(e)}function Ct(t){let e=Le();try{let r=P.parse(t);b(e,"\u2705 Valid RCAN URI"),b(e,` Registry: ${r.registry}`),b(e,` Manufacturer: ${r.manufacturer}`),b(e,` Model: ${r.model}`),b(e,` Version: ${r.version}`),b(e,` Device ID: ${r.deviceId}`)}catch(r){v(e,`Invalid RCAN URI: ${r instanceof Error?r.message:r}`)}return e}function wt(t){let e=Le(),r;if(typeof t=="string")try{r=JSON.parse(t)}catch{return v(e,"Invalid JSON string"),e}else if(typeof t=="object"&&t!==null)r=t;else return v(e,"Expected object or JSON string"),e;for(let n of["rcan","cmd","target"])(!(n in r)||!r[n])&&v(e,`Missing required field: '${n}'`);if(!e.ok)return e;try{let n=m.fromJSON(r);b(e,`\u2705 RCAN message valid (v${n.rcan})`),b(e,` cmd: ${n.cmd}`),b(e,` target: ${n.target}`),n.confidence!==void 0?b(e,` confidence: ${n.confidence}`):L(e,"No confidence score \u2014 add for RCAN \xA716 AI accountability"),n.isSigned?b(e,` signature: alg=${n.signature?.alg}, kid=${n.signature?.kid}`):L(e,"Message is unsigned (recommended for production)")}catch(n){v(e,`Message validation failed: ${n instanceof Error?n.message:n}`)}return e}function xt(t){let e=Le(),r=t.metadata??{},n=t.agent??{},s=t.rcan_protocol??{};for(let i of["rcan_version","metadata","agent"])(!(i in t)||t[i]===void 0||t[i]===null)&&v(e,`Missing required key: '${i}'`);let o=t.rcan_version;if(o&&(/^\d+\.\d+$/.test(o)||v(e,`rcan_version '${o}' must match pattern N.N (e.g. '1.2')`)),r.manufacturer||v(e,"L1: metadata.manufacturer is required (\xA72)"),r.model||v(e,"L1: metadata.model is required (\xA72)"),!r.device_id&&!r.robot_name&&v(e,"L1: metadata.device_id (or robot_name) is required (\xA72)"),s.jwt_auth?.enabled||L(e,"L2: jwt_auth not enabled (required for L2 conformance, \xA78)"),(!n.confidence_gates||n.confidence_gates.length===0)&&L(e,"L2: confidence_gates not configured (\xA716)"),(!n.hitl_gates||n.hitl_gates.length===0)&&L(e,"L3: hitl_gates not configured (\xA716)"),n.commitment_chain?.enabled||L(e,"L3: commitment_chain not enabled (\xA716)"),r.rrn?b(e,`\u2705 RRN registered: ${r.rrn}`):L(e,"Robot not registered \u2014 visit rcan.dev/registry/register"),e.ok&&e.issues.length===0){let i=!e.warnings.some(l=>l.startsWith("L1")),a=i&&!e.warnings.some(l=>l.startsWith("L2")),u=a&&!e.warnings.some(l=>l.startsWith("L3"))?"L3":a?"L2":i?"L1":"FAIL";b(e,`\u2705 Config valid \u2014 conformance level: ${u}`)}return e}var _=class extends Error{constructor(e){super(e),this.name="RCANError",Object.setPrototypeOf(this,new.target.prototype)}},ce=class extends _{constructor(e){super(e),this.name="RCANAddressError",Object.setPrototypeOf(this,new.target.prototype)}},de=class extends _{constructor(e){super(e),this.name="RCANValidationError",Object.setPrototypeOf(this,new.target.prototype)}},ue=class extends _{constructor(r,n,s,o){super(r);this.gateType=n;this.value=s;this.threshold=o;this.name="RCANGateError",Object.setPrototypeOf(this,new.target.prototype)}},fe=class extends _{constructor(e){super(e),this.name="RCANSignatureError",Object.setPrototypeOf(this,new.target.prototype)}},j=class extends _{constructor(e){super(e),this.name="RCANRegistryError",Object.setPrototypeOf(this,new.target.prototype)}},q=class t extends _{constructor(r,n){super(r);this.nodeUrl=n;this.name="RCANNodeError",Object.setPrototypeOf(this,t.prototype)}},k=class t extends q{constructor(r,n){super(`RRN not found in federation: ${r}`,n);this.rrn=r;this.name="RCANNodeNotFoundError",Object.setPrototypeOf(this,t.prototype)}},R=class t extends q{constructor(r,n,s){super(r,n);this.cause=s;this.name="RCANNodeSyncError",Object.setPrototypeOf(this,t.prototype)}},H=class t extends q{reason;constructor(e,r){super(`Node trust verification failed: ${e}`,r),this.name="RCANNodeTrustError",this.reason=e,Object.setPrototypeOf(this,t.prototype)}},le=class t extends _{constructor(e,r){super(`VERSION_INCOMPATIBLE: incoming=${e}, local=${r}`),this.name="RCANVersionIncompatibleError",Object.setPrototypeOf(this,t.prototype)}},me=class t extends _{constructor(e){super(`REPLAY_DETECTED: ${e}`),this.name="RCANReplayAttackError",Object.setPrototypeOf(this,t.prototype)}},pe=class t extends _{constructor(e){super(`DELEGATION_CHAIN_ERROR: ${e}`),this.name="RCANDelegationChainError",Object.setPrototypeOf(this,t.prototype)}},ge=class t extends _{constructor(e){super(`CONFIG_AUTH_ERROR: ${e}`),this.name="RCANConfigAuthorizationError",Object.setPrototypeOf(this,t.prototype)}};var zr="https://rcan-spec.pages.dev",he=class{baseUrl;apiKey;timeout;constructor(e){this.baseUrl=(e?.baseUrl??zr).replace(/\/$/,""),this.apiKey=e?.apiKey,this.timeout=e?.timeout??1e4}async _fetch(e,r={}){let n=`${this.baseUrl}${e}`,s=new AbortController,o=setTimeout(()=>s.abort(),this.timeout);try{return await fetch(n,{...r,signal:s.signal,headers:{"Content-Type":"application/json",...r.headers??{}}})}finally{clearTimeout(o)}}_authHeaders(){if(!this.apiKey)throw new j("API key required for write operations. Pass apiKey to RegistryClient.");return{Authorization:`Bearer ${this.apiKey}`}}async _checkResponse(e){if(!e.ok){let r=`Registry API error: ${e.status}`;try{let n=await e.json();n?.error&&(r=n.error)}catch{}throw new j(r)}return await e.json()}async register(e){let r=await this._fetch("/api/v1/robots",{method:"POST",body:JSON.stringify(e)});return this._checkResponse(r)}async get(e){let r=await this._fetch(`/api/v1/robots/${encodeURIComponent(e)}`);return this._checkResponse(r)}async list(e){let r=new URLSearchParams;e?.limit!==void 0&&r.set("limit",String(e.limit)),e?.offset!==void 0&&r.set("offset",String(e.offset)),e?.tier&&r.set("tier",e.tier);let n=r.toString()?`?${r}`:"",s=await this._fetch(`/api/v1/robots${n}`);return this._checkResponse(s)}async patch(e,r){let n=await this._fetch(`/api/v1/robots/${encodeURIComponent(e)}`,{method:"PATCH",headers:this._authHeaders(),body:JSON.stringify(r)});return this._checkResponse(n)}async delete(e){let r=await this._fetch(`/api/v1/robots/${encodeURIComponent(e)}`,{method:"DELETE",headers:this._authHeaders()});r.ok||await this._checkResponse(r)}async search(e){let r=new URLSearchParams;e.q&&r.set("q",e.q),e.manufacturer&&r.set("manufacturer",e.manufacturer),e.model&&r.set("model",e.model),e.tier&&r.set("tier",e.tier);let n=r.toString()?`?${r}`:"",s=await this._fetch(`/api/v1/robots/search${n}`);if(!s.ok){let i=await this._fetch(`/api/v1/robots${n}`),a=await this._checkResponse(i);return"robots"in a?a.robots:"results"in a&&a.results?a.results:[]}let o=await s.json();return Array.isArray(o)?o:"results"in o&&o.results?o.results:"robots"in o?o.robots:[]}};var Qr="https://rcan.dev",Xr="/.well-known/rcan-node.json",Zr=new Set(["root","authoritative","resolver","cache"]);function en(t){let e=t.match(/^RRN-([A-Z0-9]{2,8})-(\d{8,16})$/);if(e)return{type:"delegated",prefix:e[1],serial:e[2]};let r=t.match(/^RRN-(\d{8,16})$/);return r?{type:"root",serial:r[1]}:null}var ye=class{rootUrl;timeoutMs;constructor(e=Qr,r=1e4){this.rootUrl=e.replace(/\/$/,""),this.timeoutMs=r}async _fetch(e){let r=new AbortController,n=setTimeout(()=>r.abort(),this.timeoutMs);try{return await globalThis.fetch(e,{signal:r.signal})}catch(s){throw s instanceof Error&&s.name==="AbortError"?new R(`Request timed out: ${e}`,e,s):new R(`Network error fetching ${e}: ${s.message}`,e,s instanceof Error?s:void 0)}finally{clearTimeout(n)}}async getNodeManifest(e){let r=`${e.replace(/\/$/,"")}${Xr}`,n=await this._fetch(r);if(!n.ok)throw n.status===404?new k(r,e):new R(`Failed to fetch node manifest from ${e}: HTTP ${n.status}`,e);let s;try{s=await n.json()}catch(o){throw new R(`Invalid JSON in node manifest from ${e}`,e,o instanceof Error?o:void 0)}if(!this.verifyNode(s))throw new H("missing_pubkey",e);return s}async listNodes(e){let r=e?`?prefix=${encodeURIComponent(e)}`:"",n=`${this.rootUrl}/api/v1/nodes${r}`,s=await this._fetch(n);if(!s.ok)throw new R(`Failed to list nodes from ${n}: HTTP ${s.status}`,n);let o;try{o=await s.json()}catch(i){throw new R(`Invalid JSON in nodes list from ${n}`,n,i instanceof Error?i:void 0)}return Array.isArray(o)?o:o&&typeof o=="object"&&"nodes"in o?o.nodes:[]}async discover(e){let r=en(e);if(!r)throw new k(e,this.rootUrl);if(r.type==="root")return this.getNodeManifest(this.rootUrl);let n=await this.listNodes(r.prefix);if(n.length===0)throw new k(e,this.rootUrl);return n[0]}async resolve(e){let r=`${this.rootUrl}/api/v1/resolve/${encodeURIComponent(e)}`,n;try{n=await this._fetch(r)}catch(a){throw a}if(n.ok)try{return await n.json()}catch(a){throw new R(`Invalid JSON in resolve response for ${e}`,this.rootUrl,a instanceof Error?a:void 0)}if(n.status!==404)throw new R(`Unexpected HTTP ${n.status} resolving ${e}`,this.rootUrl);let s=await this.discover(e),o=`${s.api_base.replace(/\/$/,"")}/robots/${encodeURIComponent(e)}`,i=await this._fetch(o);if(!i.ok)throw i.status===404?new k(e,s.api_base):new R(`HTTP ${i.status} from authoritative node for ${e}`,s.api_base);try{return await i.json()}catch(a){throw new R(`Invalid JSON in fallback resolve response for ${e}`,s.api_base,a instanceof Error?a:void 0)}}verifyNode(e){if(!e||typeof e!="object")return!1;let r=e;return!(typeof r.rcan_node_version!="string"||!r.rcan_node_version||typeof r.node_type!="string"||!Zr.has(r.node_type)||typeof r.operator!="string"||!r.operator||typeof r.namespace_prefix!="string"||!r.namespace_prefix||typeof r.public_key!="string"||!r.public_key.startsWith("ed25519:")||typeof r.api_base!="string"||!r.api_base.startsWith("https://"))}};var tn="https://rcan.dev/schemas",je=new Map;async function Re(t){if(je.has(t))return je.get(t);try{let e=new AbortController,r=setTimeout(()=>e.abort(),5e3);r.unref?.();let n=await fetch(`${tn}/${t}`,{signal:e.signal});if(clearTimeout(r),!n.ok)return null;let s=await n.json();return je.set(t,s),s}catch{return null}}async function Tt(t){let e=await Re("rcan-config.schema.json");if(!e)return{valid:!0,skipped:!0};let r=[];if(typeof t!="object"||t===null)return{valid:!1,errors:["Config must be an object"]};let n=t,s=e.required??[];for(let o of s)o in n||r.push(`Missing required field: ${o}`);return r.length===0?{valid:!0}:{valid:!1,errors:r}}async function vt(t){let e=await Re("rcan-node.schema.json");if(!e)return{valid:!0,skipped:!0};let r=[];if(typeof t!="object"||t===null)return{valid:!1,errors:["Manifest must be an object"]};let n=t,s=e.required??[];for(let o of s)o in n||r.push(`Missing required field: ${o}`);return r.length===0?{valid:!0}:{valid:!1,errors:r}}var qe=(n=>(n[n.FIRE_AND_FORGET=0]="FIRE_AND_FORGET",n[n.ACKNOWLEDGED=1]="ACKNOWLEDGED",n[n.EXACTLY_ONCE=2]="EXACTLY_ONCE",n))(qe||{}),_e=class t extends Error{constructor(e){super(`ACK timeout for message ${e} \u2014 safety halt required`),this.name="QoSAckTimeoutError",Object.setPrototypeOf(this,t.prototype)}},Se=class{_send;_waitForAck;constructor(e,r){this._send=e,this._waitForAck=r}async sendWithQoS(e,r={}){let n=r.qos??0,s=r.maxRetries??3,o=r.initialBackoffMs??100,i=r.ackTimeoutMs??500;if(n===0)return await this._send(e),{delivered:!0,attempts:1,reason:"fire-and-forget"};let a=e.message_id??e.msg_id??"unknown",d=0,u=o;for(;d<=s;){if(await this._send(e),d++,await this._waitForAck(a,i))return{delivered:!0,attempts:d,reason:n===2?"exactly-once":"acknowledged"};if(d>s)break;await nn(u),u=Math.min(u*2,5e3)}return{delivered:!1,attempts:d,reason:`ACK not received after ${s} retries`}}};function Ot(t,e){return{message_type:6,ruri:t,safety_event:"ESTOP",reason:e.slice(0,512),timestamp_ms:Date.now(),message_id:rn(),qos:2}}function rn(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();let t=Array.from({length:16},()=>Math.floor(Math.random()*256));t[6]=t[6]&15|64,t[8]=t[8]&63|128;let e=t.map(r=>r.toString(16).padStart(2,"0"));return`${e.slice(0,4).join("")}-${e.slice(4,6).join("")}-${e.slice(6,8).join("")}-${e.slice(8,10).join("")}-${e.slice(10).join("")}`}function nn(t){return new Promise(e=>setTimeout(e,t))}var Fe=6;function Ee(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();let t=Array.from({length:16},()=>Math.floor(Math.random()*256));t[6]=t[6]&15|64,t[8]=t[8]&63|128;let e=t.map(r=>r.toString(16).padStart(2,"0"));return`${e.slice(0,4).join("")}-${e.slice(4,6).join("")}-${e.slice(6,8).join("")}-${e.slice(8,10).join("")}-${e.slice(10).join("")}`}function Nt(t,e){return{message_type:6,ruri:t,safety_event:"ESTOP",reason:e.slice(0,512),timestamp_ms:Date.now(),message_id:Ee(),qos:2}}function kt(t,e){return{message_type:6,ruri:t,safety_event:"STOP",reason:e.slice(0,512),timestamp_ms:Date.now(),message_id:Ee()}}function It(t,e){return{message_type:6,ruri:t,safety_event:"RESUME",reason:e.slice(0,512),timestamp_ms:Date.now(),message_id:Ee()}}function Mt(t){return typeof t=="object"&&t!==null&&t.message_type===Fe}function Ut(t){let e=[];return t.message_type!==6&&e.push("message_type must be 6"),t.ruri||e.push("ruri is required"),["ESTOP","STOP","RESUME"].includes(t.safety_event??"")||e.push("safety_event must be ESTOP, STOP, or RESUME"),(!t.reason||t.reason.length===0)&&e.push("reason is required"),t.message_id||e.push("message_id is required"),(!t.timestamp_ms||t.timestamp_ms<=0)&&e.push("timestamp_ms must be positive"),e}function Pt(t,e,r){return{message_type:11,ruri:t,disclosure:e,timestamp_ms:Date.now(),message_id:Ee(),delegation_chain:r}}var be=class{windowSeconds;maxSize;_seen;constructor(e=30,r=1e4){this.windowSeconds=e,this.maxSize=r,this._seen=new Map}checkAndRecord(e,r,n=!1){let s=Date.now();this._evict(s);let o=n?Math.min(this.windowSeconds,10):this.windowSeconds,i=sn(r);if(i===null)return{allowed:!1,reason:`invalid timestamp format: ${r}`};let a=s-i,d=o*1e3;if(a>d)return{allowed:!1,reason:`message too old: age=${Math.round(a/1e3)}s > window=${o}s`};if(i>s+5e3)return{allowed:!1,reason:"message timestamp is in the future"};if(this._seen.has(e))return{allowed:!1,reason:`replay detected: msg_id ${e} already seen`};if(this._seen.size>=this.maxSize){let l=this._seen.keys().next().value;this._seen.delete(l)}let u=s+d;return this._seen.set(e,u),{allowed:!0,reason:"ok"}}_evict(e){for(let[r,n]of this._seen)n<=e&&this._seen.delete(r)}get size(){return this._seen.size}};function Dt(t,e){let r=t,n=r.message_id??r.msg_id;if(!n)return{valid:!1,reason:"missing message_id / msg_id"};let s;if(typeof r.timestamp_ms=="number"?s=String(r.timestamp_ms/1e3):r.timestamp!==void 0&&(s=String(r.timestamp)),!s)return{valid:!1,reason:"missing timestamp"};let o=r.message_type===6||r.message_type===6,i=e.checkAndRecord(n,s,o);return{valid:i.allowed,reason:i.reason}}function sn(t){if(t.includes("T")||t.includes("-")){let r=new Date(t);if(!isNaN(r.getTime()))return r.getTime()}let e=parseFloat(t);return isNaN(e)?null:e>1e12?e:e*1e3}var G=class t extends Error{offsetSeconds;constructor(e,r){super(`Clock drift too large: offset=${e.toFixed(3)}s > max=${r}s`),this.name="ClockDriftError",this.offsetSeconds=e,Object.setPrototypeOf(this,t.prototype)}};async function He(t){let e=t??"https://worldtimeapi.org/api/ip";try{let r=Date.now(),n=await fetch(e,{method:"HEAD",signal:AbortSignal.timeout(3e3)}),s=Date.now(),o=n.headers.get("Date")??n.headers.get("date");if(!o)return{synchronized:!0,offsetSeconds:0,source:"assumed (no Date header)"};let i=new Date(o).getTime();if(isNaN(i))return{synchronized:!0,offsetSeconds:0,source:"assumed (unparseable Date header)"};let d=((r+s)/2-i)/1e3;return{synchronized:Math.abs(d)<=5,offsetSeconds:d,source:e}}catch{return{synchronized:!0,offsetSeconds:0,source:"assumed (network unavailable)"}}}async function $t(t=5){let e=await He();if(!e.synchronized||Math.abs(e.offsetSeconds)>t)throw new G(e.offsetSeconds,t)}async function on(t){let e=JSON.stringify(t,Object.keys(t).sort());if(typeof crypto<"u"&&crypto.subtle){let n=new TextEncoder().encode(e),s=await crypto.subtle.digest("SHA-256",n);return Array.from(new Uint8Array(s)).map(o=>o.toString(16).padStart(2,"0")).join("")}let r=2166136261;for(let n=0;n<e.length;n++)r^=e.charCodeAt(n),r=r*16777619>>>0;return r.toString(16).padStart(8,"0")}async function Lt(t,e,r,n="rcan://local/config",s=!1){let o=await on(t);return new m({rcan:h,cmd:"CONFIG_UPDATE",target:n,params:{message_type:5,diff:t,rollback:r,scope:e,config_hash:o,safety_overrides:s}})}function jt(t){let e=t.params;return!e.diff||typeof e.diff!="object"?{valid:!1,reason:"missing required field: params.diff"}:!e.config_hash||typeof e.config_hash!="string"?{valid:!1,reason:"missing required field: params.config_hash"}:"rollback"in e?e.safety_overrides===!0&&e.scope!=="creator"?{valid:!1,reason:"safety_overrides=true requires scope=creator (owner is insufficient)"}:{valid:!0,reason:"ok"}:{valid:!1,reason:"missing required field: params.rollback"}}function an(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2)}`}var Ae=class{_keys=[];addKey(e){this._keys.push(e)}getJWKS(){return{keys:[...this._keys]}}findKey(e){return this._keys.find(r=>r.kid===e)}isKeyValid(e,r){let n=this.findKey(e);if(!n)return!1;let s=(r??Date.now())/1e3;return!(n.revoked_at!==void 0&&n.revoked_at<=s||n.exp!==void 0&&n.exp<s)}expireKey(e,r){let n=this.findKey(e);n&&(n.exp=r??Math.floor(Date.now()/1e3))}revokeKey(e){let r=this.findKey(e);r&&(r.revoked_at=Math.floor(Date.now()/1e3))}validKeys(e){return this._keys.filter(r=>this.isKeyValid(r.kid,e))}};function qt(t,e,r=120,n="rcan://local/keys"){let s=an().slice(0,8);return new m({rcan:h,cmd:"KEY_ROTATION",target:n,params:{message_type:5,new_public_key:t,new_kid:s,old_kid:e,overlap_seconds:r,initiated_at:new Date().toISOString()},keyId:s})}function cn(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2)}`}function Ce(t){let e=t.requestId??cn();return new m({rcan:h,cmd:"CONSENT_REQUEST",target:t.targetRuri,params:{message_type:20,requester_ruri:t.requesterRuri,requester_owner:t.requesterOwner,target_ruri:t.targetRuri,requested_scopes:t.requestedScopes,duration_hours:t.durationHours,justification:t.justification,request_id:e,consent_type:t.consentType??"cross_robot",data_categories:t.dataCategories??[]}})}function we(t){let e=t.expiresAt??new Date(Date.now()+864e5).toISOString();return new m({rcan:h,cmd:"CONSENT_GRANT",target:"rcan://local/consent",params:{message_type:21,request_id:t.requestId,granted_scopes:t.grantedScopes??[],expires_at:e,reason:t.reason??"approved"}})}function xe(t){return new m({rcan:h,cmd:"CONSENT_DENY",target:"rcan://local/consent",params:{message_type:22,request_id:t.requestId,reason:t.reason??"denied"}})}function Ft(t){let e=t.cmd,r=t.params,n=r.message_type;return e==="CONSENT_REQUEST"?n!==20?{valid:!1,reason:"message_type must be CONSENT_REQUEST (20)"}:r.requester_ruri?r.target_ruri?!r.requested_scopes||!Array.isArray(r.requested_scopes)||r.requested_scopes.length===0?{valid:!1,reason:"requested_scopes must be a non-empty array"}:r.request_id?r.justification?{valid:!0,reason:"ok"}:{valid:!1,reason:"missing justification"}:{valid:!1,reason:"missing request_id"}:{valid:!1,reason:"missing target_ruri"}:{valid:!1,reason:"missing requester_ruri"}:e==="CONSENT_GRANT"?n!==21?{valid:!1,reason:"message_type must be CONSENT_GRANT (21)"}:r.request_id?r.expires_at?{valid:!0,reason:"ok"}:{valid:!1,reason:"missing expires_at"}:{valid:!1,reason:"missing request_id"}:e==="CONSENT_DENY"?n!==22?{valid:!1,reason:"message_type must be CONSENT_DENY (22)"}:r.request_id?{valid:!0,reason:"ok"}:{valid:!1,reason:"missing request_id"}:{valid:!1,reason:`unknown consent command: ${e}`}}var dn=3600*1e3,W=class{_cache=new Map;get(e,r){let n=this._cache.get(e);if(!n)return;let s=r??Date.now();if(n.cachedUntil!==void 0&&n.cachedUntil<s){this._cache.delete(e);return}return n}set(e,r){let n=r??Date.now();this._cache.set(e.rrn,{...e,cachedUntil:n+dn})}invalidate(e){this._cache.delete(e)}get size(){return this._cache.size}};async function Ht(t,e,r){let n=r??new W,s=n.get(t);if(s)return s;let o=`${e.replace(/\/$/,"")}/api/v1/robots/${encodeURIComponent(t)}/revocation-status`;try{let i=await fetch(o,{signal:AbortSignal.timeout(5e3)});if(!i.ok){let u={rrn:t,status:"active",reason:`registry returned ${i.status}`};return n.set(u),u}let a=await i.json(),d={rrn:t,status:a.status??"active",revokedAt:a.revokedAt,reason:a.reason,authority:a.authority};return n.set(d),d}catch{return{rrn:t,status:"active",reason:"network unavailable"}}}function Bt(t,e){return new m({rcan:h,cmd:"ROBOT_REVOCATION",target:"rcan://broadcast/revocation",params:{message_type:19,rrn:t,reason:e,revoked_at:new Date().toISOString()}})}var Be=(o=>(o.VIDEO="video",o.AUDIO="audio",o.LOCATION="location",o.BIOMETRIC="biometric",o.TELEMETRY="telemetry",o))(Be||{});function Vt(t){return Ce({requesterRuri:t.requesterRuri,requesterOwner:t.requesterOwner,targetRuri:t.targetRuri,requestedScopes:["training_data"],durationHours:t.durationHours,justification:t.justification,requestId:t.requestId,consentType:"training_data",dataCategories:t.dataCategories})}function Kt(t){return we(t)}function Jt(t){return xe(t)}function Gt(t){if(t.params.message_type!==36)return{valid:!1,reason:"not a TRAINING_DATA message"};let e=t.params.consent_token;return!e||typeof e!="string"||e.trim()===""?{valid:!1,reason:"TRAINING_DATA message missing consent_token (\xA717)"}:{valid:!0,reason:"ok"}}var Te=class{crossOwnerGraceS;keyTtlS;_cachedKeys=[];constructor(e=3600,r=86400){this.crossOwnerGraceS=e,this.keyTtlS=r}canAcceptCommand(e,r,n,s=!0,o=!1,i,a){if(e&&e.message_type===6&&e.safety_event==="ESTOP")return{allowed:!0,reason:"ESTOP always accepted (Protocol 66)"};if(!r)return{allowed:!0,reason:"online mode"};if(!n)return{allowed:!1,reason:"offline mode: cross-network commands blocked"};if(!s)return{allowed:!1,reason:"offline mode: only owner-role commands accepted from local network"};if(o&&i!==void 0){let u=((a??Date.now())-i)/1e3;if(u>this.crossOwnerGraceS)return{allowed:!1,reason:`offline mode: cross-owner grace period expired (${Math.round(u)}s > ${this.crossOwnerGraceS}s)`}}return{allowed:!0,reason:"offline mode: owner command on local network accepted"}}cacheKey(e,r){let n=r??Date.now();this._cachedKeys=this._cachedKeys.filter(s=>s.kid!==e.kid),this._cachedKeys.push({...e,cachedAtMs:n,ttlSeconds:this.keyTtlS})}getCachedKey(e,r){let n=r??Date.now(),s=this._cachedKeys.find(i=>i.kid===e);if(!s)return;if((n-s.cachedAtMs)/1e3>s.ttlSeconds){this._cachedKeys=this._cachedKeys.filter(i=>i.kid!==e);return}return s}getManifestFields(e,r){if(e===void 0)return{offline_mode:!1,offline_since_s:0};let n=r??Date.now();return{offline_mode:!0,offline_since_s:Math.round((n-e)/1e3)}}};var Ve=(g=>(g.SENSOR_PROXIMITY_FAILURE="SENSOR_PROXIMITY_FAILURE",g.SENSOR_CAMERA_FAILURE="SENSOR_CAMERA_FAILURE",g.SENSOR_IMU_FAILURE="SENSOR_IMU_FAILURE",g.MOTOR_OVERCURRENT="MOTOR_OVERCURRENT",g.MOTOR_OVERTEMP="MOTOR_OVERTEMP",g.MOTOR_STALL="MOTOR_STALL",g.BATTERY_CRITICAL="BATTERY_CRITICAL",g.BATTERY_LOW="BATTERY_LOW",g.NETWORK_TIMEOUT="NETWORK_TIMEOUT",g.NETWORK_REGISTRY_UNREACHABLE="NETWORK_REGISTRY_UNREACHABLE",g.SAFETY_ESTOP_STUCK="SAFETY_ESTOP_STUCK",g.SAFETY_WATCHDOG_TIMEOUT="SAFETY_WATCHDOG_TIMEOUT",g.UNKNOWN="UNKNOWN",g))(Ve||{});function Wt(t){return new m({rcan:h,cmd:"FAULT_REPORT",target:t.target??"rcan://local/fault",params:{message_type:26,fault_code:t.faultCode,severity:t.severity,subsystem:t.subsystem,affects_safety:t.affectsSafety,safe_to_continue:t.safeToContinue,description:t.description??"",reported_at:new Date().toISOString()}})}var D=(a=>(a[a.GUEST=1]="GUEST",a[a.OPERATOR=2]="OPERATOR",a[a.CONTRIBUTOR=3]="CONTRIBUTOR",a[a.ADMIN=4]="ADMIN",a[a.M2M_PEER=5]="M2M_PEER",a[a.CREATOR=6]="CREATOR",a[a.M2M_TRUSTED=7]="M2M_TRUSTED",a))(D||{}),Yt=D,B={1:1,2:2,3:2.5,4:3,5:4,6:5,7:6},un=new Map(Object.entries(B).map(([t,e])=>[e,Number(t)]));function Y(t){return un.get(t)}var Ke={status:1,discover:1,chat:1,observer:1,contribute:3,control:2,teleop:2,training:4,training_data:4,config:4,authority:4,admin:6,safety:6,estop:6,"fleet.trusted":7};var zt={minRoleForDiscover:1,minRoleForStatus:1,minRoleForChat:1,minRoleForControl:1,minRoleForSafety:1},Qt={minRoleForDiscover:1,minRoleForStatus:1,minRoleForChat:1,minRoleForControl:2,minRoleForSafety:6};function Xt(t){try{let e=t.split(".");if(e.length<2)return null;let r=(e[1]??"").replace(/-/g,"+").replace(/_/g,"/"),n=r+"=".repeat((4-r.length%4)%4);return JSON.parse(atob(n))}catch{return null}}function Je(t){let e=Xt(t);if(!e)return 1;let r=e.rcan_role;if(r!=null){let s=Y(Number(r));if(s!==void 0)return s}let n=e.loa;if(n!=null){let s=Y(Number(n));if(s!==void 0)return s}return 1}function ve(t){return Je(t)}function Zt(t){let e=Xt(t);if(!e)return{sub:"",role:1,jwtLevel:1,scopes:[]};let r=e.rcan_role,n=e.loa,s=r!==void 0?Number(r):n!==void 0?Number(n):1,o=Y(s)??1,i=Array.isArray(e.rcan_scopes)?e.rcan_scopes:Array.isArray(e.scopes)?e.scopes:[];return{sub:String(e.sub??""),role:o,jwtLevel:B[o],registryUrl:e.registry_url,scopes:i,verifiedAt:e.verified_at,peerRrn:e.peer_rrn,fleetRrns:Array.isArray(e.fleet_rrns)?e.fleet_rrns:void 0}}function Ge(t,e){let r=Ke[e.toLowerCase()];return r===void 0?t>=2?{ok:!0,reason:""}:{ok:!1,reason:`Unknown scope '${e}': applying OPERATOR minimum. Caller has ${D[t]}.`}:t>=r?{ok:!0,reason:""}:{ok:!1,reason:`Scope '${e}' requires ${D[r]} (JWT level ${B[r]}), but caller has ${D[t]} (JWT level ${B[t]})`}}function er(t,e){return Ge(t,e)}var We=(n=>(n.ROOT="root",n.AUTHORITATIVE="authoritative",n.COMMUNITY="community",n))(We||{}),Ye=(n=>(n.CONSENT="consent",n.REVOCATION="revocation",n.KEY="key",n))(Ye||{}),fn=1440*60*1e3,Oe=class{store=new Map;set(e){this.store.set(e.registryUrl,{identity:e,expiresAt:Date.now()+fn})}lookup(e){let r=this.store.get(e);if(r){if(Date.now()>r.expiresAt){this.store.delete(e);return}return r.identity}}async discoverViaDns(e){let r=`_rcan-registry.${e}`,n;try{n=await re("dns").promises.resolveTxt(r)}catch{return}for(let s of n){let o=s.join("");try{let i=JSON.parse(o);if(i.registryUrl&&i.tier&&i.publicKeyPem&&i.domain){let a={registryUrl:i.registryUrl,tier:i.tier,publicKeyPem:i.publicKeyPem,domain:i.domain,verifiedAt:new Date().toISOString()};return this.set(a),a}}catch{}}}async verifyRegistryJwt(e,r){let n=this.lookup(r);if(!n)throw new Error(`REGISTRY_UNKNOWN: ${r} is not in the trust cache`);let s;try{let i=(e.split(".")[1]??"").replace(/-/g,"+").replace(/_/g,"/"),a=i+"=".repeat((4-i.length%4)%4),d;typeof atob<"u"?d=atob(a):d=Buffer.from(a,"base64").toString("utf-8");let u=JSON.parse(d);s=typeof u.iss=="string"?u.iss:void 0}catch{throw new Error("REGISTRY_JWT_MALFORMED: cannot decode token payload")}if(s!==r)throw new Error(`REGISTRY_JWT_ISS_MISMATCH: expected iss=${r}, got iss=${s??"(none)"}`);return n}};function ln(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();let t=Array.from({length:16},()=>Math.floor(Math.random()*256));t[6]=(t[6]??0)&15|64,t[8]=(t[8]??0)&63|128;let e=t.map(r=>r.toString(16).padStart(2,"0"));return`${e.slice(0,4).join("")}-${e.slice(4,6).join("")}-${e.slice(6,8).join("")}-${e.slice(8,10).join("")}-${e.slice(10).join("")}`}function tr(t,e,r,n){return new m({rcan:"2.1.0",rcanVersion:"2.1.0",cmd:"federation_sync",target:e,params:{msg_type:23,msg_id:ln(),source_registry:t,target_registry:e,sync_type:r,payload:n},timestamp:new Date().toISOString()})}async function rr(t,e,r){let n=t.params?.msg_type;if(n===6||n===6||t.cmd==="estop"||t.cmd==="ESTOP")return{valid:!0,reason:"ESTOP always permitted (P66 invariant)"};let o=t.params?.source_registry??t.params?.from_registry;if(!o||o===e)return{valid:!0,reason:"local registry; no federation check needed"};if(!r.lookup(o))return{valid:!1,reason:`REGISTRY_UNKNOWN: ${o} is not in the local trust cache`};let a=1,d=t.params?.registry_jwt;return d?a=ve(d):typeof t.loa=="number"&&(a=t.loa),a<2?{valid:!1,reason:`LOA_INSUFFICIENT: cross-registry commands require LoA>=2 (OPERATOR), got role=${a}`}:{valid:!0,reason:"cross-registry command accepted"}}var w=class t extends Error{constructor(e){super(e),this.name="TransportError",Object.setPrototypeOf(this,t.prototype)}},Xe=(s=>(s.HTTP="http",s.COMPACT="compact",s.MINIMAL="minimal",s.BLE="ble",s))(Xe||{}),ze={msg_type:"t",msg_id:"i",timestamp:"ts",from_rrn:"f",to_rrn:"to",scope:"s",payload:"p",signature:"sig"},nr=Object.fromEntries(Object.entries(ze).map(([t,e])=>[e,t]));function Ze(t){let e=t.toJSON(),r={};for(let[o,i]of Object.entries(e)){let a=ze[o];r[a??o]=i}if(r.p&&typeof r.p=="object"){let o=r.p,i={};for(let[a,d]of Object.entries(o)){let u=ze[a];i[u??a]=d}r.p=i}let n=JSON.stringify(r);return new TextEncoder().encode(n)}function et(t){let r=new TextDecoder().decode(t),n=JSON.parse(r),s={};for(let[o,i]of Object.entries(n)){let a=nr[o];s[a??o]=i}if(s.payload&&typeof s.payload=="object"){let o=s.payload,i={};for(let[a,d]of Object.entries(o)){let u=nr[a];i[u??a]=d}s.payload=i}return new m({rcan:s.rcan??"1.6",rcanVersion:s.rcanVersion,cmd:s.cmd,target:s.target,params:s.params??s.payload??{},timestamp:s.timestamp,confidence:s.confidence,signature:s.signature})}var Q=32,Qe=6;async function sr(t){let e=new TextEncoder().encode(t),r=new ArrayBuffer(e.byteLength);new Uint8Array(r).set(e);let s=await(globalThis.crypto?.subtle??(await import("crypto")).webcrypto.subtle).digest("SHA-256",r);return new Uint8Array(s)}async function or(t){let e=t.params?.msg_type??0;if(e!==Qe)throw new w(`encodeMinimal only supports SAFETY (type 6) messages; got type=${e}`);let r=t.params?.from_rrn??t.target??"",n=t.params?.to_rrn??t.target??"",s=await sr(r),o=await sr(n),i=(t.signature?.sig??"").replace(/[^A-Za-z0-9+/=]/g,""),a;try{if(typeof atob<"u"){let O=atob(i.slice(0,16));a=new Uint8Array(O.length);for(let y=0;y<O.length;y++)a[y]=O.charCodeAt(y)}else a=Buffer.from(i.slice(0,16),"base64")}catch{a=new Uint8Array(8)}let u=(t.timestamp?Math.floor(new Date(t.timestamp).getTime()/1e3):Math.floor(Date.now()/1e3))>>>0,l=new Uint8Array(Q),V=new DataView(l.buffer);V.setUint16(0,Qe,!1),l.set(s.subarray(0,8),2),l.set(o.subarray(0,8),10),V.setUint32(18,u,!1);let A=new Uint8Array(8);A.set(a.subarray(0,Math.min(8,a.length))),l.set(A,22);let g=0;for(let O=0;O<30;O++)g^=l[O]??0;if(V.setUint16(30,g&65535,!1),l.length!==Q)throw new w(`encodeMinimal assertion failed: expected ${Q} bytes, got ${l.length}`);return l}function ir(t){if(t.length!==Q)throw new w(`decodeMinimal: expected ${Q} bytes, got ${t.length}`);let e=new DataView(t.buffer,t.byteOffset,t.byteLength),r=e.getUint16(0,!1),n=t.subarray(2,10),s=t.subarray(10,18),o=e.getUint32(18,!1),i=t.subarray(22,30),a=new Date(o*1e3).toISOString(),d=u=>Array.from(u).map(l=>l.toString(16).padStart(2,"0")).join("");return{params:{msg_type:r,from_hash:d(n),to_hash:d(s),timestamp_s:o,sig_truncated:d(i)},timestamp:a}}var mn=251,z=3;function ar(t,e=mn){let r=Ze(t),n=e-z;if(n<=0)throw new w(`MTU ${e} is too small (need at least ${z+1})`);let s=Math.ceil(r.length/n),o=[];for(let i=0;i<s;i++){let a=r.subarray(i*n,(i+1)*n),d=new Uint8Array(z+a.length);d[0]=i,d[1]=s,d[2]=i===s-1?1:0,d.set(a,z),o.push(d)}return o}function cr(t){if(t.length===0)throw new w("decodeBleFrames: no frames provided");let e=[...t].sort((a,d)=>(a[0]??0)-(d[0]??0)),r=e[0]?.[1]??e.length;if(e.length!==r)throw new w(`decodeBleFrames: expected ${r} frames, got ${e.length}`);let n=e.map(a=>a.subarray(z)),s=n.reduce((a,d)=>a+d.length,0),o=new Uint8Array(s),i=0;for(let a of n)o.set(a,i),i+=a.length;return et(o)}function dr(t,e){let n=(e.params?.msg_type??0)===Qe,s=o=>t.includes(o);if(n){if(s("minimal"))return"minimal";if(s("ble"))return"ble";if(s("compact"))return"compact";if(s("http"))return"http"}else{if(s("http"))return"http";if(s("compact"))return"compact";if(s("ble"))return"ble"}throw new w(`No suitable transport available from: [${t.join(", ")}]`)}var tt=(r=>(r.BASE64="base64",r.REF="ref",r))(tt||{});function X(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();let t=Array.from({length:16},()=>Math.floor(Math.random()*256));t[6]=(t[6]??0)&15|64,t[8]=(t[8]??0)&63|128;let e=t.map(r=>r.toString(16).padStart(2,"0"));return`${e.slice(0,4).join("")}-${e.slice(4,6).join("")}-${e.slice(6,8).join("")}-${e.slice(8,10).join("")}-${e.slice(10).join("")}`}async function rt(t){let e=globalThis.crypto?.subtle??(await import("crypto")).webcrypto.subtle,r=new ArrayBuffer(t.byteLength);new Uint8Array(r).set(t);let n=await e.digest("SHA-256",r),s=new Uint8Array(n);return Array.from(s).map(o=>o.toString(16).padStart(2,"0")).join("")}function ur(t){if(typeof Buffer<"u")return Buffer.from(t).toString("base64");let e="";for(let r=0;r<t.length;r++)e+=String.fromCharCode(t[r]??0);return btoa(e)}function nt(t,e){let r={...t.toJSON(),...e};return m.fromJSON(r)}async function st(t,e,r){let n=await rt(e),s=ur(e),o={chunkId:X(),mimeType:r,encoding:"base64",hashSha256:n,dataB64:s,sizeBytes:e.length},i=t.mediaChunks??[];return nt(t,{mediaChunks:[...i,o]})}function fr(t,e,r,n,s){let o={chunkId:X(),mimeType:r,encoding:"ref",hashSha256:n,refUrl:e,sizeBytes:s},i=t.mediaChunks??[];return nt(t,{mediaChunks:[...i,o]})}async function lr(t){let e=t.mediaChunks??[];if(e.length===0)return{valid:!0,reason:"no media chunks"};for(let r=0;r<e.length;r++){let n=e[r];if(!n.chunkId)return{valid:!1,reason:`chunk[${r}]: missing chunkId`};if(!n.mimeType)return{valid:!1,reason:`chunk[${r}]: missing mimeType`};if(!n.hashSha256)return{valid:!1,reason:`chunk[${r}]: missing hashSha256`};if(n.sizeBytes<0)return{valid:!1,reason:`chunk[${r}]: sizeBytes must be >= 0`};if(n.encoding==="base64"){if(!n.dataB64)return{valid:!1,reason:`chunk[${r}]: BASE64 encoding requires dataB64`};let s;try{if(typeof Buffer<"u")s=Buffer.from(n.dataB64,"base64");else{let i=atob(n.dataB64);s=new Uint8Array(i.length);for(let a=0;a<i.length;a++)s[a]=i.charCodeAt(a)}}catch{return{valid:!1,reason:`chunk[${r}]: failed to decode base64 data`}}let o=await rt(s);if(o!==n.hashSha256)return{valid:!1,reason:`chunk[${r}]: SHA-256 mismatch (expected ${n.hashSha256}, got ${o})`}}else if(n.encoding==="ref"){if(!n.refUrl)return{valid:!1,reason:`chunk[${r}]: REF encoding requires refUrl`}}else return{valid:!1,reason:`chunk[${r}]: unknown encoding '${n.encoding}'`}}return{valid:!0,reason:"ok"}}async function mr(t){let e=new m({rcan:"1.6",rcanVersion:"1.6",cmd:"training_data",target:"rcan://training/data",params:{msg_type:36,msg_id:X()},timestamp:new Date().toISOString()});for(let r of t)e=await st(e,r.data,r.mimeType);return e}async function pr(t,e,r,n,s){let o=await rt(e),i=ur(e),a={chunkId:X(),mimeType:r,encoding:"base64",hashSha256:o,dataB64:i,sizeBytes:e.length},d={streamId:t,chunkIndex:n,isFinal:s,chunk:a},u=new m({rcan:"1.6",rcanVersion:"1.6",cmd:"stream_chunk",target:"rcan://streaming/chunk",params:{msg_type:29,msg_id:X(),stream_chunk:d},timestamp:new Date().toISOString()});return u=nt(u,{mediaChunks:[a]}),u}var ot=2.5,pn=0;function gn(){return`cr-${Date.now()}-${++pn}`}function gr(t={}){return{type:33,request_id:t.request_id??gn(),project_id:t.project_id??"",project_name:t.project_name??"",work_unit_id:t.work_unit_id??"",resource_type:t.resource_type??"cpu",estimated_duration_s:t.estimated_duration_s??0,priority:t.priority??0,payload:t.payload??{},timestamp:t.timestamp??Date.now()/1e3}}function hr(t={}){let e={type:34,request_id:t.request_id??"",work_unit_id:t.work_unit_id??"",status:t.status??"completed",resource_type:t.resource_type??"cpu",duration_s:t.duration_s??0,compute_units:t.compute_units??0,result_payload:t.result_payload??{},timestamp:t.timestamp??Date.now()/1e3};return t.error_message!==void 0&&(e.error_message=t.error_message),e}function yr(t={}){return{type:35,request_id:t.request_id??"",work_unit_id:t.work_unit_id??"",reason:t.reason??"",timestamp:t.timestamp??Date.now()/1e3}}function Rr(t,e="request"){return e==="request"||e==="result"?t>=ot:e==="cancel"?t>=2:!1}function _r(t){return t>=3}var it=2,hn=0;function yn(){return`run-${Date.now()}-${++hn}`}function Sr(t={}){return{type:37,competition_id:t.competition_id??"",competition_format:t.competition_format??"sprint",hardware_tier:t.hardware_tier??"",model_id:t.model_id??"",robot_rrn:t.robot_rrn??"",entered_at:t.entered_at??Date.now()/1e3}}function Er(t={}){let e=t.score??0;if(e<0||e>1)throw new Error(`score must be in [0.0, 1.0], got ${e}`);return{type:38,competition_id:t.competition_id??"",candidate_id:t.candidate_id??"",score:e,hardware_tier:t.hardware_tier??"",verified:t.verified??!1,submitted_at:t.submitted_at??Date.now()/1e3}}function br(t={}){return{type:39,season_id:t.season_id??"",class_id:t.class_id??"",standings:t.standings??[],days_remaining:t.days_remaining??0,broadcast_at:t.broadcast_at??Date.now()/1e3}}function Ar(t={}){let e=t.score??0;if(e<0||e>1)throw new Error(`score must be in [0.0, 1.0], got ${e}`);return{type:40,run_id:t.run_id??yn(),run_type:t.run_type??"personal",candidate_id:t.candidate_id??"",score:e,hardware_tier:t.hardware_tier??"",model_id:t.model_id??"",owner_uid:t.owner_uid??"",metrics:t.metrics??{success_rate:0,p66_rate:0,token_efficiency:0,latency_score:0},submitted_to_community:t.submitted_to_community??!1,created_at:t.created_at??Date.now()/1e3}}function Cr(t){return t>=it}var wr="/.well-known/rcan-firmware-manifest.json";function xr(t){let e={rrn:t.rrn,firmware_version:t.firmwareVersion,build_hash:t.buildHash,components:t.components,signed_at:t.signedAt};return t.signature&&(e.signature=t.signature),e}function Tr(t){return{rrn:t.rrn,firmwareVersion:t.firmware_version,buildHash:t.build_hash,components:t.components??[],signedAt:t.signed_at??"",signature:t.signature}}function vr(t){let e={build_hash:t.buildHash,components:t.components.map(r=>({hash:r.hash,name:r.name,version:r.version})),firmware_version:t.firmwareVersion,rrn:t.rrn,signed_at:t.signedAt};return JSON.stringify(e)}var Ne=class extends Error{constructor(e){super(e),this.name="FirmwareIntegrityError"}};function Or(t){let e=[];t.rrn||e.push("rrn is required"),t.firmwareVersion||e.push("firmwareVersion is required"),t.buildHash||e.push("buildHash is required"),t.buildHash.startsWith("sha256:")||e.push("buildHash must start with 'sha256:'"),t.signedAt||e.push("signedAt is required"),t.signature||e.push("signature is required (manifest must be signed)");for(let[r,n]of t.components.entries())n.name||e.push(`components[${r}].name is required`),n.version||e.push(`components[${r}].version is required`),n.hash.startsWith("sha256:")||e.push(`components[${r}].hash must start with 'sha256:'`);return e}function Nr(t){return{request_id:t.requestId,authority_id:t.authorityId,requested_data:t.requestedData,justification:t.justification,expires_at:t.expiresAt}}function kr(t){return{requestId:t.request_id,authorityId:t.authority_id,requestedData:t.requested_data??[],justification:t.justification??"",expiresAt:t.expires_at??0}}function at(t){let e=[];return t.requestId||e.push("requestId is required"),t.authorityId||e.push("authorityId is required"),(!t.requestedData||t.requestedData.length===0)&&e.push("requestedData must include at least one category"),t.justification||e.push("justification is required"),(!t.expiresAt||t.expiresAt<=0)&&e.push("expiresAt must be a positive Unix timestamp"),t.expiresAt<Date.now()/1e3&&e.push("expiresAt is in the past \u2014 request has expired"),e}function Ir(t){return Date.now()/1e3<t.expiresAt&&at(t).length===0}var Mr={NOT_RECOGNIZED:"AUTHORITY_NOT_RECOGNIZED",REQUEST_EXPIRED:"AUTHORITY_REQUEST_EXPIRED",INVALID_TOKEN:"AUTHORITY_INVALID_TOKEN",RATE_LIMITED:"AUTHORITY_RATE_LIMITED"};var ct="https://api.rrf.rcan.dev/v2/revocations",ke="rrf.rcan.dev",dt=55e3;var S=class extends Error{constructor(e){super(e),this.name="M2MAuthError"}};function Ur(t){let e=t.split(".");if(e.length<2)throw new S("Invalid JWT structure");let r=(e[1]??"").replace(/-/g,"+").replace(/_/g,"/"),n=r+"=".repeat((4-r.length%4)%4);try{return JSON.parse(atob(n))}catch(s){throw new S(`JWT payload decode failed: ${String(s)}`)}}function Pr(t){let e=Ur(t),r=Number(e.exp??0);if(r>0&&Date.now()/1e3>r)throw new S(`M2M_PEER token expired (sub=${String(e.sub)})`);let n=String(e.peer_rrn??"");if(!n)throw new S("M2M_PEER token missing peer_rrn claim");return{sub:String(e.sub??""),peerRrn:n,scopes:Array.isArray(e.rcan_scopes)?e.rcan_scopes:Array.isArray(e.scopes)?e.scopes:[],exp:r,iss:String(e.iss??"")}}function ut(t){let e=Ur(t),r=String(e.iss??"");if(r!==ke)throw new S(`M2M_TRUSTED issuer must be '${ke}', got '${r}'`);let n=Array.isArray(e.rcan_scopes)?e.rcan_scopes:Array.isArray(e.scopes)?e.scopes:[];if(!n.includes("fleet.trusted"))throw new S("M2M_TRUSTED token missing required 'fleet.trusted' scope");let s=Number(e.exp??0);if(s>0&&Date.now()/1e3>s)throw new S(`M2M_TRUSTED token expired (sub=${String(e.sub)})`);let o=String(e.rrf_sig??"");if(!o)throw new S("M2M_TRUSTED token missing rrf_sig claim");let i=Array.isArray(e.fleet_rrns)?e.fleet_rrns:[];return{sub:String(e.sub??""),fleetRrns:i,scopes:n,exp:s,iss:r,rrfSig:o}}function ft(t,e){let r=ut(t);if(!r.fleetRrns.includes(e))throw new S(`M2M_TRUSTED token does not authorize commanding '${e}'. Authorized fleet: [${r.fleetRrns.join(", ")}]`);return r}var $=null;async function lt(t=ct){let e=Date.now();if($&&e-$.fetchedAt<dt)return $;try{let n=await(await fetch(t,{signal:AbortSignal.timeout?.(5e3)})).json();$={revokedOrchestrators:new Set(n.revoked_orchestrators??[]),revokedJtis:new Set(n.revoked_jtis??[]),fetchedAt:e}}catch{if($)return $;$={revokedOrchestrators:new Set,revokedJtis:new Set,fetchedAt:e}}return $}async function mt(t,e){let r=await lt();return!!(r.revokedOrchestrators.has(t.sub)||e&&r.revokedJtis.has(e))}async function Dr(t,e,r){let n=ft(t,e);if(!r?.skipRevocationCheck&&await mt(n))throw new S(`M2M_TRUSTED orchestrator '${n.sub}' is on the RRF revocation list`);return n}var Rn="0.6.0",_n="1.6";return Jr(Sn);})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@continuonai/rcan-ts",
3
- "version": "0.8.0",
3
+ "version": "1.1.0",
4
4
  "description": "Official TypeScript SDK for the RCAN v1.6 robot communication protocol",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",