forgeframe 0.0.6 → 0.0.10

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.
@@ -1,5 +1,5 @@
1
- (function(u,p){typeof exports=="object"&&typeof module<"u"?p(exports):typeof define=="function"&&define.amd?define(["exports"],p):(u=typeof globalThis<"u"?globalThis:u||self,p(u.ForgeFrame={}))})(this,(function(u){"use strict";const p={IFRAME:"iframe",POPUP:"popup"},m={RENDER:"render",RENDERED:"rendered",PRERENDER:"prerender",PRERENDERED:"prerendered",DISPLAY:"display",ERROR:"error",CLOSE:"close",DESTROY:"destroy",PROPS:"props",RESIZE:"resize",FOCUS:"focus"},O={JSON:"json",BASE64:"base64",DOTIFY:"dotify"},H={REQUEST:"request",RESPONSE:"response"},h={INIT:"forgeframe_init",PROPS:"forgeframe_props",CLOSE:"forgeframe_close",RESIZE:"forgeframe_resize",FOCUS:"forgeframe_focus",SHOW:"forgeframe_show",HIDE:"forgeframe_hide",ERROR:"forgeframe_error",EXPORT:"forgeframe_export",CALL:"forgeframe_call",CONSUMER_EXPORT:"forgeframe_consumer_export",GET_SIBLINGS:"forgeframe_get_siblings"},$="__forgeframe__",Y=(()=>{if("0.0.6".trim().length===0)throw new Error("ForgeFrame VERSION injection is missing. Configure __FORGEFRAME_VERSION__ in build/test tooling.");return"0.0.6"})();class pe{listeners=new Map;on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>this.off(e,t)}once(e,t){const n=r=>(this.off(e,n),t(r));return this.on(e,n)}emit(e,t){const n=this.listeners.get(e);if(n)for(const r of n)try{const i=r(t);i&&typeof i=="object"&&"catch"in i&&typeof i.catch=="function"&&i.catch(o=>{console.error(`Error in async event handler for "${e}":`,o)})}catch(i){console.error(`Error in event handler for "${e}":`,i)}}off(e,t){if(!t){this.listeners.delete(e);return}const n=this.listeners.get(e);n&&(n.delete(t),n.size===0&&this.listeners.delete(e))}removeAllListeners(){this.listeners.clear()}listenerCount(e){return this.listeners.get(e)?.size??0}}function Ke(){const s=Date.now().toString(36),e=Math.random().toString(36).slice(2,11);return`${s}_${e}`}function A(){return Math.random().toString(36).slice(2,11)}class qe{tasks=[];cleaned=!1;register(e){if(this.cleaned){Promise.resolve().then(()=>e()).catch(t=>{console.error("Error in cleanup task:",t)});return}this.tasks.push(e)}async cleanup(){if(this.cleaned)return;this.cleaned=!0;const e=this.tasks.reverse();this.tasks=[];for(const t of e)try{await t()}catch(n){console.error("Error in cleanup task:",n)}}isCleaned(){return this.cleaned}reset(){this.tasks=[],this.cleaned=!1}}function fe(){let s,e;return{promise:new Promise((n,r)=>{s=n,e=r}),resolve:s,reject:e}}function Je(s,e,t="Operation timed out"){return new Promise((n,r)=>{const i=setTimeout(()=>{r(new Error(`${t} (${e}ms)`))},e);s.then(o=>{clearTimeout(i),n(o)}).catch(o=>{clearTimeout(i),r(o)})})}const v=new Map,Xe=200;function Ye(s){return s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ge(s){if(!s.includes("*"))return null;const e=v.get(s);if(e)return e;const t=s.split("*").map(r=>Ye(r)).join(".*"),n=new RegExp(`^${t}$`);if(v.size>=Xe){const r=v.keys().next().value;r&&v.delete(r)}return v.set(s,n),n}function Ze(s,e){return s.global||s.sticky?new RegExp(s.source,s.flags.replace(/[gy]/g,"")).test(e):s.test(e)}function G(s=window){try{return s.location.origin}catch{return""}}function Qe(s,e=window){try{return s.location.origin===e.location.origin}catch{return!1}}function C(s,e){if(typeof s=="string"){if(s==="*")return!0;const t=Ge(s);return t?t.test(e):s===e}return s instanceof RegExp?Ze(s,e):Array.isArray(s)?s.some(t=>C(t,e)):!1}function Z(s){if(!s)return!0;try{return s.closed}catch{return!0}}function et(s=window){try{return s.opener}catch{return null}}function tt(s=window){try{const e=s.parent;return e&&e!==s?e:null}catch{return null}}function st(s=window){try{return s.parent!==s}catch{return!0}}function nt(s=window){try{return s.opener!==null&&s.opener!==void 0}catch{return!1}}const me=100,E=new Map;function rt(){const s=[];for(const[e,t]of E.entries())Z(t)&&s.push(e);for(const e of s)E.delete(e)}function it(s,e){if(E.size>=me&&rt(),E.size>=me){const t=E.keys().next().value;t&&E.delete(t)}E.set(s,e)}function ot(s){E.delete(s)}function at(s,e){return s.global||s.sticky?new RegExp(s.source,s.flags.replace(/[gy]/g,"")).test(e):s.test(e)}class w{_optional=!1;_nullable=!1;_default;"~standard"={version:1,vendor:"forgeframe",validate:e=>e===null?this._nullable?{value:null}:{issues:[{message:"Expected a value, got null"}]}:e===void 0?this._default!==void 0?{value:typeof this._default=="function"?this._default():this._default}:this._optional?{value:void 0}:{issues:[{message:"Required"}]}:this._validate(e)};optional(){const e=this._clone();return e._optional=!0,e}nullable(){const e=this._clone();return e._nullable=!0,e}default(e){const t=this._clone();return t._default=e,t}}class L extends w{_minLength;_maxLength;_pattern;_patternMessage;_trim=!1;_validate(e){if(typeof e!="string")return{issues:[{message:`Expected string, got ${typeof e}`}]};const t=this._trim?e.trim():e;return this._minLength!==void 0&&t.length<this._minLength?{issues:[{message:`String must be at least ${this._minLength} characters`}]}:this._maxLength!==void 0&&t.length>this._maxLength?{issues:[{message:`String must be at most ${this._maxLength} characters`}]}:this._pattern&&!at(this._pattern,t)?{issues:[{message:this._patternMessage||`String must match pattern ${this._pattern}`}]}:{value:t}}_clone(){const e=new L;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e._minLength=this._minLength,e._maxLength=this._maxLength,e._pattern=this._pattern,e._patternMessage=this._patternMessage,e._trim=this._trim,e}min(e){const t=this._clone();return t._minLength=e,t}max(e){const t=this._clone();return t._maxLength=e,t}length(e){const t=this._clone();return t._minLength=e,t._maxLength=e,t}pattern(e,t){const n=this._clone();return n._pattern=e,n._patternMessage=t,n}email(){return this.pattern(/^[^\s@]+@[^\s@]+\.[^\s@]+$/,"Invalid email address")}url(){return this.pattern(/^https?:\/\/.+/,"Invalid URL")}uuid(){return this.pattern(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,"Invalid UUID")}trim(){const e=this._clone();return e._trim=!0,e}nonempty(){const e=this._clone();return e._minLength=1,e}}class z extends w{_min;_max;_int=!1;_validate(e){return typeof e!="number"||Number.isNaN(e)?{issues:[{message:`Expected number, got ${typeof e}`}]}:this._int&&!Number.isInteger(e)?{issues:[{message:"Expected integer"}]}:this._min!==void 0&&e<this._min?{issues:[{message:`Number must be >= ${this._min}`}]}:this._max!==void 0&&e>this._max?{issues:[{message:`Number must be <= ${this._max}`}]}:{value:e}}_clone(){const e=new z;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e._min=this._min,e._max=this._max,e._int=this._int,e}min(e){const t=this._clone();return t._min=e,t}max(e){const t=this._clone();return t._max=e,t}int(){const e=this._clone();return e._int=!0,e}positive(){const e=this._clone();return e._min=Number.MIN_VALUE,e}nonnegative(){const e=this._clone();return e._min=0,e}negative(){const e=this._clone();return e._max=-Number.MIN_VALUE,e}}class k extends w{_validate(e){return typeof e!="boolean"?{issues:[{message:`Expected boolean, got ${typeof e}`}]}:{value:e}}_clone(){const e=new k;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class M extends w{_validate(e){return typeof e!="function"?{issues:[{message:`Expected function, got ${typeof e}`}]}:{value:e}}_clone(){const e=new M;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class I extends w{_itemSchema;_minLength;_maxLength;_validate(e){if(!Array.isArray(e))return{issues:[{message:`Expected array, got ${typeof e}`}]};if(this._minLength!==void 0&&e.length<this._minLength)return{issues:[{message:`Array must have at least ${this._minLength} items`}]};if(this._maxLength!==void 0&&e.length>this._maxLength)return{issues:[{message:`Array must have at most ${this._maxLength} items`}]};if(this._itemSchema){const t=[];for(let n=0;n<e.length;n++){const r=this._itemSchema["~standard"].validate(e[n]);if(r instanceof Promise)throw new Error("Async schema validation is not supported. Use synchronous schemas.");if(r.issues)return{issues:r.issues.map(i=>({...i,path:[n,...i.path||[]]}))};t.push(r.value)}return{value:t}}return{value:e}}_clone(){const e=new I;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e._itemSchema=this._itemSchema,e._minLength=this._minLength,e._maxLength=this._maxLength,e}of(e){const t=new I;return t._optional=this._optional,t._nullable=this._nullable,t._itemSchema=e,t._minLength=this._minLength,t._maxLength=this._maxLength,t}min(e){const t=this._clone();return t._minLength=e,t}max(e){const t=this._clone();return t._maxLength=e,t}nonempty(){return this.min(1)}}class x extends w{_shape;_strict=!1;_validate(e){if(typeof e!="object"||e===null||Array.isArray(e))return{issues:[{message:`Expected object, got ${Array.isArray(e)?"array":typeof e}`}]};const t=e,n={};if(this._shape){if(this._strict){const r=new Set(Object.keys(this._shape));for(const i of Object.keys(t))if(!r.has(i))return{issues:[{message:`Unknown key: ${i}`,path:[i]}]}}for(const[r,i]of Object.entries(this._shape)){const o=i["~standard"].validate(t[r]);if(o instanceof Promise)throw new Error("Async schema validation is not supported. Use synchronous schemas.");if(o.issues)return{issues:o.issues.map(a=>({...a,path:[r,...a.path||[]]}))};n[r]=o.value}if(!this._strict)for(const r of Object.keys(t))r in this._shape||(n[r]=t[r]);return{value:n}}return{value:e}}_clone(){const e=new x;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e._shape=this._shape,e._strict=this._strict,e}shape(e){const t=new x;return t._optional=this._optional,t._nullable=this._nullable,t._shape=e,t._strict=this._strict,t}strict(){const e=this._clone();return e._strict=!0,e}}class W extends w{_value;constructor(e){super(),this._value=e}_validate(e){return e!==this._value?{issues:[{message:`Expected ${JSON.stringify(this._value)}, got ${JSON.stringify(e)}`}]}:{value:e}}_clone(){const e=new W(this._value);return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class B extends w{_values;_valueSet;constructor(e){super(),this._values=e,this._valueSet=new Set(e)}_validate(e){return this._valueSet.has(e)?{value:e}:{issues:[{message:`Expected one of [${this._values.map(t=>JSON.stringify(t)).join(", ")}], got ${JSON.stringify(e)}`}]}}_clone(){const e=new B(this._values);return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class j extends w{constructor(){super(),this._nullable=!0}_validate(e){return{value:e}}_clone(){const e=new j;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}const f={string:()=>new L,number:()=>new z,boolean:()=>new k,function:()=>new M,array:()=>new I,object:()=>new x,literal:s=>new W(s),enum:s=>new B(s),any:()=>new j},b={uid:{schema:f.string().optional(),sendToHost:!0},tag:{schema:f.string().optional(),sendToHost:!0},dimensions:{schema:f.object().default(()=>({width:"100%",height:"100%"})),sendToHost:!1},timeout:{schema:f.number().default(1e4),sendToHost:!1},cspNonce:{schema:f.string().optional(),sendToHost:!0},onDisplay:{schema:f.function().optional(),sendToHost:!1},onRendered:{schema:f.function().optional(),sendToHost:!1},onRender:{schema:f.function().optional(),sendToHost:!1},onPrerendered:{schema:f.function().optional(),sendToHost:!1},onPrerender:{schema:f.function().optional(),sendToHost:!1},onClose:{schema:f.function().optional(),sendToHost:!1},onDestroy:{schema:f.function().optional(),sendToHost:!1},onResize:{schema:f.function().optional(),sendToHost:!1},onFocus:{schema:f.function().optional(),sendToHost:!1},onError:{schema:f.function().optional(),sendToHost:!1},onProps:{schema:f.function().optional(),sendToHost:!1}};function D(s){return typeof s=="object"&&s!==null&&"~standard"in s&&typeof s["~standard"]=="object"&&s["~standard"]!==null&&s["~standard"].version===1&&typeof s["~standard"].vendor=="string"&&typeof s["~standard"].validate=="function"}function ct(s,e,t){const n=s["~standard"].validate(e);if(n instanceof Promise)throw new Error(`Prop "${t}" uses an async schema. ForgeFrame only supports synchronous schema validation. Please use a synchronous schema or remove async operations (like database lookups) from your schema definition.`);if(n.issues){const r=n.issues.map(i=>`${lt(i.path,t)}: ${i.message}`);throw new Error(`Validation failed: ${r.join("; ")}`)}return n.value}function lt(s,e){if(!s||s.length===0)return e;const t=s.map(n=>{if(typeof n=="object"&&n!==null){if("key"in n&&n.key!==void 0)return String(n.key);if("index"in n&&typeof n.index=="number")return String(n.index)}return String(n)});return`${e}.${t.join(".")}`}function T(s){const e=D(s);return{isDirectSchema:e,definition:e?{schema:s}:s}}function ge(s,e,t){const n={...b,...e},r={};for(const[i,o]of Object.entries(n)){const{definition:a}=T(o);let c;const l=a.alias,d=i in s,g=l&&l in s;if(d)c=s[i];else if(g)c=s[l];else if(a.value)c=a.value(t);else if(a.default!==void 0)c=typeof a.default=="function"?a.default(t):a.default;else if(a.schema&&D(a.schema)){const y=a.schema["~standard"].validate(void 0);!(y instanceof Promise)&&!y.issues&&(c=y.value)}c!==void 0&&a.decorate&&(c=a.decorate({value:c,props:r})),r[i]=c}return r}function ye(s,e){const t={...b,...e};for(const[n,r]of Object.entries(t)){const{isDirectSchema:i,definition:o}=T(r);let a=s[n];if(o.required&&a===void 0)throw new Error(`Prop "${n}" is required but was not provided`);if(o.schema&&D(o.schema))(a!==void 0||i)&&(a=ct(o.schema,a,n),s[n]=a);else if(a===void 0)continue;o.validate&&o.validate({value:a,props:s})}}function we(s,e,t,n){const r={...b,...e},i={};for(const[o,a]of Object.entries(r)){const{definition:c}=T(a),l=s[o];if(c.sendToHost===!1||c.sameDomain&&!n)continue;if(c.trustedDomains){const g=c.trustedDomains;if(!C(g,t))continue}let d=l;c.hostDecorate&&l!==void 0&&(d=c.hostDecorate({value:l,props:s})),i[o]=d}return i}function ut(s,e){const t=new URLSearchParams,n={...b,...e};for(const[r,i]of Object.entries(n)){const{definition:o}=T(i),a=s[r];if(a===void 0||typeof a=="function"||!o.queryParam)continue;const c=typeof o.queryParam=="string"?o.queryParam:r;let l;typeof o.queryParam=="function"?l=o.queryParam({value:a}):typeof a=="object"?l=JSON.stringify(a):l=String(a),t.set(c,l)}return t}function ht(s,e){const t=new URLSearchParams,n={...b,...e};for(const[r,i]of Object.entries(n)){const{definition:o}=T(i),a=s[r];if(a===void 0||typeof a=="function"||!o.bodyParam)continue;const c=typeof o.bodyParam=="string"?o.bodyParam:r;let l;typeof o.bodyParam=="function"?l=o.bodyParam({value:a}):typeof a=="object"?l=JSON.stringify(a):l=String(a),t.set(c,l)}return t}const _e=500,dt=new Set(["__proto__"]);function Pe(s){return!dt.has(s)}class Q{constructor(e){this.messenger=e,this.setupCallHandler()}localFunctions=new Map;remoteFunctions=new Map;currentBatchIds=new Set;serialize(e,t){if(this.localFunctions.size>=_e){const r=this.localFunctions.keys().next().value;r&&this.localFunctions.delete(r)}const n=A();return this.localFunctions.set(n,e),this.currentBatchIds.add(n),{__type__:"function",__id__:n,__name__:t||e.name||"anonymous"}}deserialize(e,t,n){const r=`${e.__id__}`,i=this.remoteFunctions.get(r);if(i)return i;if(this.remoteFunctions.size>=_e){const a=this.remoteFunctions.keys().next().value;a&&this.remoteFunctions.delete(a)}const o=async(...a)=>this.messenger.send(t,n,h.CALL,{id:e.__id__,args:a});return Object.defineProperty(o,"name",{value:e.__name__,configurable:!0}),this.remoteFunctions.set(r,o),o}static isFunctionRef(e){return typeof e=="object"&&e!==null&&e.__type__==="function"&&typeof e.__id__=="string"}setupCallHandler(){this.messenger.on(h.CALL,async({id:e,args:t})=>{const n=this.localFunctions.get(e);if(!n)throw new Error(`Function with id "${e}" not found`);return n(...t)})}removeLocal(e){this.localFunctions.delete(e)}startBatch(){this.currentBatchIds.clear()}finishBatch(e=!1){if(e){this.currentBatchIds.clear();return}for(const t of this.localFunctions.keys())this.currentBatchIds.has(t)||this.localFunctions.delete(t);this.currentBatchIds.clear()}clearRemote(){this.remoteFunctions.clear()}get localFunctionCount(){return this.localFunctions.size}get remoteFunctionCount(){return this.remoteFunctions.size}destroy(){this.localFunctions.clear(),this.remoteFunctions.clear(),this.currentBatchIds.clear()}}function ee(s,e,t=new WeakSet){if(typeof s=="function")return e.serialize(s);if(Array.isArray(s)){if(t.has(s))throw new Error("Circular reference detected in props - arrays cannot contain circular references");t.add(s);try{return s.map(n=>ee(n,e,t))}finally{t.delete(s)}}if(typeof s=="object"&&s!==null){if(t.has(s))throw new Error("Circular reference detected in props - objects cannot contain circular references");t.add(s);try{const n={};for(const[r,i]of Object.entries(s))Pe(r)&&(n[r]=ee(i,e,t));return n}finally{t.delete(s)}}return s}function te(s,e,t,n,r=new WeakSet){if(Q.isFunctionRef(s))return e.deserialize(s,t,n);if(Array.isArray(s)){if(r.has(s))throw new Error("Circular reference detected in serialized props");r.add(s);try{return s.map(i=>te(i,e,t,n,r))}finally{r.delete(s)}}if(typeof s=="object"&&s!==null){if(r.has(s))throw new Error("Circular reference detected in serialized props");r.add(s);try{const i={};for(const[o,a]of Object.entries(s))Pe(o)&&(i[o]=te(a,e,t,n,r));return i}finally{r.delete(s)}}return s}const pt=new Set(["__proto__"]);function Ee(s){return!pt.has(s)}function be(s,e=""){const t=[];for(const[n,r]of Object.entries(s)){const i=e?`${e}.${n}`:n;if(r!==null&&typeof r=="object"&&!Array.isArray(r))t.push(be(r,i));else{const o=encodeURIComponent(JSON.stringify(r));t.push(`${i}=${o}`)}}return t.filter(Boolean).join("&")}function ft(s){const e={};if(!s)return e;const t=s.split("&");for(const n of t){const[r,i]=n.split("=");if(!r||i===void 0)continue;let o;try{o=JSON.parse(decodeURIComponent(i))}catch{o=decodeURIComponent(i)}const a=r.split(".");if(a.some(d=>!Ee(d)))continue;let c=e;for(let d=0;d<a.length-1;d++){const g=a[d],y=c[g];(!Object.prototype.hasOwnProperty.call(c,g)||typeof y!="object"||y===null||Array.isArray(y))&&(c[g]={}),c=c[g]}const l=a[a.length-1];c[l]=o}return e}function mt(s){return typeof s=="object"&&s!==null&&s.__type__==="dotify"&&typeof s.__value__=="string"}function gt(s,e,t){const n={...b,...e},r={};for(const[i,o]of Object.entries(s)){if(o===void 0)continue;const a=n[i];r[i]=yt(o,a,t)}return r}function yt(s,e,t){if(typeof s=="function")return t.serialize(s);const n=e?.serialization??O.JSON;if(n===O.BASE64&&typeof s=="object"){const r=JSON.stringify(s);return{__type__:"base64",__value__:btoa(encodeURIComponent(r))}}return n===O.DOTIFY&&typeof s=="object"&&s!==null&&!Array.isArray(s)?{__type__:"dotify",__value__:be(s)}:ee(s,t)}function Re(s,e,t,n,r,i){const o={...b,...e},a={};for(const[c,l]of Object.entries(s)){if(!Ee(c))continue;const d=o[c];a[c]=wt(l,d,t,n,r,i)}return a}function wt(s,e,t,n,r,i){if(_t(s))try{const o=decodeURIComponent(atob(s.__value__));return JSON.parse(o)}catch{return s}if(mt(s))try{return ft(s.__value__)}catch{return s}return te(s,n,r,i)}function _t(s){return typeof s=="object"&&s!==null&&s.__type__==="base64"&&typeof s.__value__=="string"}class Pt{constructor(e,t,n){this.options=e,this.createPropContext=n,this.inputProps={...t};const r=this.inputProps,i=this.createPropContext(r);this.props=ge(r,this.options.props,i)}props;inputProps;pendingPropsUpdate=null;buildNextProps(e){const t={...this.inputProps,...e},n={...this.props,...e},r=this.createPropContext(n),i=ge(n,this.options.props,r);return ye(i,this.options.props),this.options.validate?.({props:i}),{nextInputProps:t,nextProps:i}}updateProps(e,t){return this.queuePropsUpdate(async()=>{const{nextInputProps:n,nextProps:r}=this.buildNextProps(e),i=t.resolveUrl(r),o=t.resolveUrlOrigin(i);t.assertStableRenderedOrigin(o),this.inputProps=n,this.props=r,t.isRendered()||t.syncTrustedDomainForUrl(i),t.shouldSendPropsToHost()&&await t.sendPropsUpdateToHost(r),t.emitPropsUpdated(r)},t.shouldSendPropsToHost)}queuePropsUpdate(e,t){if(!this.pendingPropsUpdate){const r=e();return t()&&this.trackPendingUpdate(r),r}const n=this.pendingPropsUpdate.then(e,e);return this.trackPendingUpdate(n),n}trackPendingUpdate(e){const t=e.then(()=>{},()=>{});this.pendingPropsUpdate=t,t.finally(()=>{this.pendingPropsUpdate===t&&(this.pendingPropsUpdate=null)})}}function S(s,e="100%"){return s===void 0?e:typeof s=="number"?`${s}px`:s}function V(s,e){if(s===void 0)return e;if(typeof s=="number")return s;const t=parseInt(s,10);return isNaN(t)?e:t}function Et(s){try{s.src="about:blank",s.parentNode?.removeChild(s)}catch{}}function bt(s,e){Ot(s,e)}function Rt(s){s.style.display="",s.style.visibility="visible"}function Se(s){s.style.display="none",s.style.visibility="hidden"}function St(s){try{s.focus(),s.contentWindow?.focus()}catch{}}function Ot(s,e){e.width!==void 0&&(s.style.width=S(e.width)),e.height!==void 0&&(s.style.height=S(e.height))}class se extends Error{constructor(e="Popup blocked by browser"){super(e),this.name="PopupOpenError"}}function vt(s){const{url:e,name:t,dimensions:n}=s,r=V(n.width,500),i=V(n.height,500),o=Math.floor(window.screenX+(window.outerWidth-r)/2),a=Math.floor(window.screenY+(window.outerHeight-i)/2),c=[`width=${r}`,`height=${i}`,`left=${o}`,`top=${a}`,"menubar=no","toolbar=no","location=yes","status=no","resizable=yes","scrollbars=yes"].join(","),l=window.open(e,t,c);if(!l||xt(l))throw new se;return l}function Ct(s){try{s.closed||s.close()}catch{}}function It(s){try{s.closed||s.focus()}catch{}}function xt(s){if(!s)return!0;try{return!!(s.closed||s.innerHeight===0||s.innerWidth===0)}catch{return!0}}function Dt(s,e,t={}){const{initialInterval:n=100,maxInterval:r=2e3,multiplier:i=1.5}=t;let o=n,a,c=!1;const l=()=>{try{e()}catch(g){console.error("Error in popup close callback:",g)}},d=()=>{if(!c){try{if(s.closed){l();return}}catch{l();return}o=Math.min(o*i,r),a=setTimeout(d,o)}};return a=setTimeout(d,o),()=>{c=!0,clearTimeout(a)}}function Tt(s,e){try{const t=V(e.width,s.outerWidth),n=V(e.height,s.outerHeight);s.resizeTo(t,n)}catch{}}const Oe="forgeframe-spinner-style";function Ut(s,e){const t=s.getElementById(Oe);if(t){const r=t.getAttribute("nonce");if(!e||r===e)return;t.remove()}const n=s.createElement("style");n.id=Oe,e&&n.setAttribute("nonce",e),n.textContent=`
1
+ (function(u,d){typeof exports=="object"&&typeof module<"u"?d(exports):typeof define=="function"&&define.amd?define(["exports"],d):(u=typeof globalThis<"u"?globalThis:u||self,d(u.ForgeFrame={}))})(this,(function(u){"use strict";const d={IFRAME:"iframe",POPUP:"popup"},g={RENDER:"render",RENDERED:"rendered",PRERENDER:"prerender",PRERENDERED:"prerendered",DISPLAY:"display",ERROR:"error",CLOSE:"close",DESTROY:"destroy",PROPS:"props",RESIZE:"resize",FOCUS:"focus"},x={JSON:"json",BASE64:"base64",DOTIFY:"dotify"},z={REQUEST:"request",RESPONSE:"response"},h={INIT:"forgeframe_init",PROPS:"forgeframe_props",CLOSE:"forgeframe_close",RESIZE:"forgeframe_resize",FOCUS:"forgeframe_focus",SHOW:"forgeframe_show",HIDE:"forgeframe_hide",ERROR:"forgeframe_error",EXPORT:"forgeframe_export",CALL:"forgeframe_call",CONSUMER_EXPORT:"forgeframe_consumer_export",GET_SIBLINGS:"forgeframe_get_siblings"},k="__forgeframe__",W=(()=>{if("0.0.10".trim().length===0)throw new Error("ForgeFrame VERSION injection is missing. Configure __FORGEFRAME_VERSION__ in build/test tooling.");return"0.0.10"})();class Oe{listeners=new Map;on(e,n){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(n),()=>this.off(e,n)}once(e,n){const s=r=>(this.off(e,s),n(r));return this.on(e,s)}emit(e,n){const s=this.listeners.get(e);if(s)for(const r of s)try{const i=r(n);i&&typeof i=="object"&&"catch"in i&&typeof i.catch=="function"&&i.catch(o=>{console.error(`Error in async event handler for "${e}":`,o)})}catch(i){console.error(`Error in event handler for "${e}":`,i)}}off(e,n){if(!n){this.listeners.delete(e);return}const s=this.listeners.get(e);s&&(s.delete(n),s.size===0&&this.listeners.delete(e))}removeAllListeners(){this.listeners.clear()}listenerCount(e){return this.listeners.get(e)?.size??0}}function lt(){const t=Date.now().toString(36),e=Math.random().toString(36).slice(2,11);return`${t}_${e}`}function j(){return Math.random().toString(36).slice(2,11)}class ut{tasks=[];cleaned=!1;register(e){if(this.cleaned){Promise.resolve().then(()=>e()).catch(n=>{console.error("Error in cleanup task:",n)});return}this.tasks.push(e)}async cleanup(){if(this.cleaned)return;this.cleaned=!0;const e=this.tasks.reverse();this.tasks=[];for(const n of e)try{await n()}catch(s){console.error("Error in cleanup task:",s)}}isCleaned(){return this.cleaned}reset(){this.tasks=[],this.cleaned=!1}}function Re(){let t,e;return{promise:new Promise((s,r)=>{t=s,e=r}),resolve:t,reject:e}}function ht(t,e,n="Operation timed out"){return new Promise((s,r)=>{const i=setTimeout(()=>{r(new Error(`${n} (${e}ms)`))},e);t.then(o=>{clearTimeout(i),s(o)}).catch(o=>{clearTimeout(i),r(o)})})}const v=new Map,dt=200;function ft(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function pt(t){if(!t.includes("*"))return null;const e=v.get(t);if(e)return e;const n=t.split("*").map(r=>ft(r)).join(".*"),s=new RegExp(`^${n}$`);if(v.size>=dt){const r=v.keys().next().value;r&&v.delete(r)}return v.set(t,s),s}function mt(t,e){return t.global||t.sticky?new RegExp(t.source,t.flags.replace(/[gy]/g,"")).test(e):t.test(e)}function B(t=window){try{return t.location.origin}catch{return""}}function Ce(t,e=window){try{return t.location.origin===e.location.origin}catch{return!1}}function T(t,e){if(typeof t=="string"){if(t==="*")return!0;const n=pt(t);return n?n.test(e):t===e}return t instanceof RegExp?mt(t,e):Array.isArray(t)?t.some(n=>T(n,e)):!1}function oe(t){if(!t)return!0;try{return t.closed}catch{return!0}}function gt(t=window){try{return t.opener}catch{return null}}function yt(t=window){try{const e=t.parent;return e&&e!==t?e:null}catch{return null}}function wt(t=window){try{return t.parent!==t}catch{return!0}}function _t(t=window){try{return t.opener!==null&&t.opener!==void 0}catch{return!1}}const Se=100,b=new Map;function Pt(){const t=[];for(const[e,n]of b.entries())oe(n)&&t.push(e);for(const e of t)b.delete(e)}function Et(t,e){if(b.size>=Se&&Pt(),b.size>=Se){const n=b.keys().next().value;n&&b.delete(n)}b.set(t,e)}function bt(t){b.delete(t)}function Ot(t,e){return t.global||t.sticky?new RegExp(t.source,t.flags.replace(/[gy]/g,"")).test(e):t.test(e)}class _{_optional=!1;_nullable=!1;_default;"~standard"={version:1,vendor:"forgeframe",validate:e=>e===null?this._nullable?{value:null}:{issues:[{message:"Expected a value, got null"}]}:e===void 0?this._default!==void 0?{value:typeof this._default=="function"?this._default():this._default}:this._optional?{value:void 0}:{issues:[{message:"Required"}]}:this._validate(e)};optional(){const e=this._clone();return e._optional=!0,e}nullable(){const e=this._clone();return e._nullable=!0,e}default(e){const n=this._clone();return n._default=e,n}}class V extends _{_minLength;_maxLength;_pattern;_patternMessage;_trim=!1;_validate(e){if(typeof e!="string")return{issues:[{message:`Expected string, got ${typeof e}`}]};const n=this._trim?e.trim():e;return this._minLength!==void 0&&n.length<this._minLength?{issues:[{message:`String must be at least ${this._minLength} characters`}]}:this._maxLength!==void 0&&n.length>this._maxLength?{issues:[{message:`String must be at most ${this._maxLength} characters`}]}:this._pattern&&!Ot(this._pattern,n)?{issues:[{message:this._patternMessage||`String must match pattern ${this._pattern}`}]}:{value:n}}_clone(){const e=new V;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e._minLength=this._minLength,e._maxLength=this._maxLength,e._pattern=this._pattern,e._patternMessage=this._patternMessage,e._trim=this._trim,e}min(e){const n=this._clone();return n._minLength=e,n}max(e){const n=this._clone();return n._maxLength=e,n}length(e){const n=this._clone();return n._minLength=e,n._maxLength=e,n}pattern(e,n){const s=this._clone();return s._pattern=e,s._patternMessage=n,s}email(){return this.pattern(/^[^\s@]+@[^\s@]+\.[^\s@]+$/,"Invalid email address")}url(){return this.pattern(/^https?:\/\/.+/,"Invalid URL")}uuid(){return this.pattern(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,"Invalid UUID")}trim(){const e=this._clone();return e._trim=!0,e}nonempty(){const e=this._clone();return e._minLength=1,e}}class Y extends _{_min;_max;_int=!1;_validate(e){return typeof e!="number"||Number.isNaN(e)?{issues:[{message:`Expected number, got ${typeof e}`}]}:this._int&&!Number.isInteger(e)?{issues:[{message:"Expected integer"}]}:this._min!==void 0&&e<this._min?{issues:[{message:`Number must be >= ${this._min}`}]}:this._max!==void 0&&e>this._max?{issues:[{message:`Number must be <= ${this._max}`}]}:{value:e}}_clone(){const e=new Y;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e._min=this._min,e._max=this._max,e._int=this._int,e}min(e){const n=this._clone();return n._min=e,n}max(e){const n=this._clone();return n._max=e,n}int(){const e=this._clone();return e._int=!0,e}positive(){const e=this._clone();return e._min=Number.MIN_VALUE,e}nonnegative(){const e=this._clone();return e._min=0,e}negative(){const e=this._clone();return e._max=-Number.MIN_VALUE,e}}class J extends _{_validate(e){return typeof e!="boolean"?{issues:[{message:`Expected boolean, got ${typeof e}`}]}:{value:e}}_clone(){const e=new J;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class q extends _{_validate(e){return typeof e!="function"?{issues:[{message:`Expected function, got ${typeof e}`}]}:{value:e}}_clone(){const e=new q;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class U extends _{_itemSchema;_minLength;_maxLength;_validate(e){if(!Array.isArray(e))return{issues:[{message:`Expected array, got ${typeof e}`}]};if(this._minLength!==void 0&&e.length<this._minLength)return{issues:[{message:`Array must have at least ${this._minLength} items`}]};if(this._maxLength!==void 0&&e.length>this._maxLength)return{issues:[{message:`Array must have at most ${this._maxLength} items`}]};if(this._itemSchema){const n=[];for(let s=0;s<e.length;s++){const r=this._itemSchema["~standard"].validate(e[s]);if(r instanceof Promise)throw new Error("Async schema validation is not supported. Use synchronous schemas.");if(r.issues)return{issues:r.issues.map(i=>({...i,path:[s,...i.path||[]]}))};n.push(r.value)}return{value:n}}return{value:e}}_clone(){const e=new U;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e._itemSchema=this._itemSchema,e._minLength=this._minLength,e._maxLength=this._maxLength,e}of(e){const n=new U;return n._optional=this._optional,n._nullable=this._nullable,n._itemSchema=e,n._minLength=this._minLength,n._maxLength=this._maxLength,n}min(e){const n=this._clone();return n._minLength=e,n}max(e){const n=this._clone();return n._maxLength=e,n}nonempty(){return this.min(1)}}class N extends _{_shape;_strict=!1;_validate(e){if(typeof e!="object"||e===null||Array.isArray(e))return{issues:[{message:`Expected object, got ${Array.isArray(e)?"array":typeof e}`}]};const n=e,s={};if(this._shape){if(this._strict){const r=new Set(Object.keys(this._shape));for(const i of Object.keys(n))if(!r.has(i))return{issues:[{message:`Unknown key: ${i}`,path:[i]}]}}for(const[r,i]of Object.entries(this._shape)){const o=i["~standard"].validate(n[r]);if(o instanceof Promise)throw new Error("Async schema validation is not supported. Use synchronous schemas.");if(o.issues)return{issues:o.issues.map(a=>({...a,path:[r,...a.path||[]]}))};s[r]=o.value}if(!this._strict)for(const r of Object.keys(n))r in this._shape||(s[r]=n[r]);return{value:s}}return{value:e}}_clone(){const e=new N;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e._shape=this._shape,e._strict=this._strict,e}shape(e){const n=new N;return n._optional=this._optional,n._nullable=this._nullable,n._shape=e,n._strict=this._strict,n}strict(){const e=this._clone();return e._strict=!0,e}}class K extends _{_value;constructor(e){super(),this._value=e}_validate(e){return e!==this._value?{issues:[{message:`Expected ${JSON.stringify(this._value)}, got ${JSON.stringify(e)}`}]}:{value:e}}_clone(){const e=new K(this._value);return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class X extends _{_values;_valueSet;constructor(e){super(),this._values=e,this._valueSet=new Set(e)}_validate(e){return this._valueSet.has(e)?{value:e}:{issues:[{message:`Expected one of [${this._values.map(n=>JSON.stringify(n)).join(", ")}], got ${JSON.stringify(e)}`}]}}_clone(){const e=new X(this._values);return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}class G extends _{constructor(){super(),this._nullable=!0}_validate(e){return{value:e}}_clone(){const e=new G;return e._optional=this._optional,e._nullable=this._nullable,e._default=this._default,e}}const m={string:()=>new V,number:()=>new Y,boolean:()=>new J,function:()=>new q,array:()=>new U,object:()=>new N,literal:t=>new K(t),enum:t=>new X(t),any:()=>new G},R={uid:{schema:m.string().optional(),sendToHost:!0},tag:{schema:m.string().optional(),sendToHost:!0},dimensions:{schema:m.object().default(()=>({width:"100%",height:"100%"})),sendToHost:!1},timeout:{schema:m.number().default(1e4),sendToHost:!1},cspNonce:{schema:m.string().optional(),sendToHost:!0},onDisplay:{schema:m.function().optional(),sendToHost:!1},onRendered:{schema:m.function().optional(),sendToHost:!1},onRender:{schema:m.function().optional(),sendToHost:!1},onPrerendered:{schema:m.function().optional(),sendToHost:!1},onPrerender:{schema:m.function().optional(),sendToHost:!1},onClose:{schema:m.function().optional(),sendToHost:!1},onDestroy:{schema:m.function().optional(),sendToHost:!1},onResize:{schema:m.function().optional(),sendToHost:!1},onFocus:{schema:m.function().optional(),sendToHost:!1},onError:{schema:m.function().optional(),sendToHost:!1},onProps:{schema:m.function().optional(),sendToHost:!1}};function C(t){return typeof t=="object"&&t!==null&&"~standard"in t&&typeof t["~standard"]=="object"&&t["~standard"]!==null&&t["~standard"].version===1&&typeof t["~standard"].vendor=="string"&&typeof t["~standard"].validate=="function"}function Rt(t,e,n){const s=t["~standard"].validate(e);if(s instanceof Promise)throw new Error(`Prop "${n}" uses an async schema. ForgeFrame only supports synchronous schema validation. Please use a synchronous schema or remove async operations (like database lookups) from your schema definition.`);if(s.issues){const r=s.issues.map(i=>`${Ct(i.path,n)}: ${i.message}`);throw new Error(`Validation failed: ${r.join("; ")}`)}return s.value}function Ct(t,e){if(!t||t.length===0)return e;const n=t.map(s=>{if(typeof s=="object"&&s!==null){if("key"in s&&s.key!==void 0)return String(s.key);if("index"in s&&typeof s.index=="number")return String(s.index)}return String(s)});return`${e}.${n.join(".")}`}function F(t){const e=C(t);return{isDirectSchema:e,definition:e?{schema:t}:t}}function De(t,e,n){const s={...R,...e},r={};for(const[i,o]of Object.entries(s)){const{definition:a}=F(o);let c;const l=a.alias,p=i in t,y=l&&l in t;if(p)c=t[i];else if(y)c=t[l];else if(a.value)c=a.value(n);else if(a.default!==void 0)c=typeof a.default=="function"?a.default(n):a.default;else if(a.schema&&C(a.schema)){const f=a.schema["~standard"].validate(void 0);!(f instanceof Promise)&&!f.issues&&(c=f.value)}c!==void 0&&a.decorate&&(c=a.decorate({value:c,props:r})),r[i]=c}return r}function H(t,e){const n={...R,...e};for(const[s,r]of Object.entries(n)){const{isDirectSchema:i,definition:o}=F(r);let a=t[s];if(o.required&&a===void 0)throw new Error(`Prop "${s}" is required but was not provided`);if(o.schema&&C(o.schema))(a!==void 0||i)&&(a=Rt(o.schema,a,s),t[s]=a);else if(a===void 0)continue;o.validate&&o.validate({value:a,props:t})}}function Ie(t,e,n,s){const r={...R,...e},i={};for(const[o,a]of Object.entries(r)){const{definition:c}=F(a),l=t[o];if(c.sendToHost===!1||c.sameDomain&&!s)continue;if(c.trustedDomains){const y=c.trustedDomains;if(!T(y,n))continue}let p=l;c.hostDecorate&&l!==void 0&&(p=c.hostDecorate({value:l,props:t})),i[o]=p}return i}function St(t,e){const n=new URLSearchParams,s={...R,...e};for(const[r,i]of Object.entries(s)){const{definition:o}=F(i),a=t[r];if(a===void 0||typeof a=="function"||!o.queryParam)continue;const c=typeof o.queryParam=="string"?o.queryParam:r;let l;typeof o.queryParam=="function"?l=o.queryParam({value:a}):typeof a=="object"?l=JSON.stringify(a):l=String(a),n.set(c,l)}return n}function Dt(t,e){const n=new URLSearchParams,s={...R,...e};for(const[r,i]of Object.entries(s)){const{definition:o}=F(i),a=t[r];if(a===void 0||typeof a=="function"||!o.bodyParam)continue;const c=typeof o.bodyParam=="string"?o.bodyParam:r;let l;typeof o.bodyParam=="function"?l=o.bodyParam({value:a}):typeof a=="object"?l=JSON.stringify(a):l=String(a),n.set(c,l)}return n}const xe=500,It=new Set(["__proto__"]);function ve(t){return!It.has(t)}class ae{constructor(e){this.messenger=e,this.setupCallHandler()}localFunctions=new Map;remoteFunctions=new Map;currentBatchIds=new Set;serialize(e,n){if(this.localFunctions.size>=xe){const r=this.localFunctions.keys().next().value;r&&this.localFunctions.delete(r)}const s=j();return this.localFunctions.set(s,e),this.currentBatchIds.add(s),{__type__:"function",__id__:s,__name__:n||e.name||"anonymous"}}deserialize(e,n,s){const r=`${e.__id__}`,i=this.remoteFunctions.get(r);if(i)return i;if(this.remoteFunctions.size>=xe){const a=this.remoteFunctions.keys().next().value;a&&this.remoteFunctions.delete(a)}const o=async(...a)=>this.messenger.send(n,s,h.CALL,{id:e.__id__,args:a});return Object.defineProperty(o,"name",{value:e.__name__,configurable:!0}),this.remoteFunctions.set(r,o),o}static isFunctionRef(e){return typeof e=="object"&&e!==null&&e.__type__==="function"&&typeof e.__id__=="string"}setupCallHandler(){this.messenger.on(h.CALL,async({id:e,args:n})=>{const s=this.localFunctions.get(e);if(!s)throw new Error(`Function with id "${e}" not found`);return s(...n)})}removeLocal(e){this.localFunctions.delete(e)}startBatch(){this.currentBatchIds.clear()}finishBatch(e=!1){if(e){this.currentBatchIds.clear();return}for(const n of this.localFunctions.keys())this.currentBatchIds.has(n)||this.localFunctions.delete(n);this.currentBatchIds.clear()}clearRemote(){this.remoteFunctions.clear()}get localFunctionCount(){return this.localFunctions.size}get remoteFunctionCount(){return this.remoteFunctions.size}destroy(){this.localFunctions.clear(),this.remoteFunctions.clear(),this.currentBatchIds.clear()}}function ce(t,e,n=new WeakSet){if(typeof t=="function")return e.serialize(t);if(Array.isArray(t)){if(n.has(t))throw new Error("Circular reference detected in props - arrays cannot contain circular references");n.add(t);try{return t.map(s=>ce(s,e,n))}finally{n.delete(t)}}if(typeof t=="object"&&t!==null){if(n.has(t))throw new Error("Circular reference detected in props - objects cannot contain circular references");n.add(t);try{const s={};for(const[r,i]of Object.entries(t))ve(r)&&(s[r]=ce(i,e,n));return s}finally{n.delete(t)}}return t}function le(t,e,n,s,r=new WeakSet){if(ae.isFunctionRef(t))return e.deserialize(t,n,s);if(Array.isArray(t)){if(r.has(t))throw new Error("Circular reference detected in serialized props");r.add(t);try{return t.map(i=>le(i,e,n,s,r))}finally{r.delete(t)}}if(typeof t=="object"&&t!==null){if(r.has(t))throw new Error("Circular reference detected in serialized props");r.add(t);try{const i={};for(const[o,a]of Object.entries(t))ve(o)&&(i[o]=le(a,e,n,s,r));return i}finally{r.delete(t)}}return t}const xt=new Set(["__proto__"]),Te="__forgeframe.dotify_path__:",Z="__forgeframe.dotify_empty_object_path__:",Ue="__forgeframe.dotify_empty_object__";function Ne(t){return!xt.has(t)}function Fe(t){if(t===null||typeof t!="object"||Array.isArray(t))return!1;const e=Object.getPrototypeOf(t);return e===Object.prototype||e===null}function He(t,e=Te){return`${e}${encodeURIComponent(JSON.stringify(t))}`}function vt(t){return encodeURIComponent(JSON.stringify(t))}function Tt(t,e){return`${He(t)}=${vt(e)}`}function Ut(t){return`${He(t,Z)}=1`}function Nt(t,e,n){Object.defineProperty(t,e,{configurable:!0,enumerable:!0,writable:!0,value:n})}function $e(t,e=[]){const n=Object.entries(t);if(n.length===0&&Fe(t))return e.length===0?Ue:Ut(e);const s=[];for(const[r,i]of n){if(i===void 0)continue;const o=[...e,r];Fe(i)?s.push($e(i,o)):s.push(Tt(o,i))}return s.filter(Boolean).join("&")}function Ft(t){const e={};if(!t||t===Ue)return e;const n=t.split("&");for(const s of n){const r=s.indexOf("=");if(r===-1)continue;const i=s.slice(0,r),o=s.slice(r+1);if(!i||o===void 0)continue;const a=i.startsWith(Z);let c;if(a){if(o!=="1")throw new Error("Invalid empty-object DOTIFY entry");c={}}else try{c=JSON.parse(decodeURIComponent(o))}catch{c=decodeURIComponent(o)}const l=Ht(i);if(l.some(f=>!Ne(f)))continue;let p=e;for(let f=0;f<l.length-1;f++){const O=l[f],D=p[O];(!Object.prototype.hasOwnProperty.call(p,O)||typeof D!="object"||D===null||Array.isArray(D))&&(p[O]={}),p=p[O]}const y=l[l.length-1];Nt(p,y,c)}return e}function Ht(t){const e=t.startsWith(Z)?Z:Te;if(!t.startsWith(e))throw new Error("Invalid DOTIFY path framing");const n=decodeURIComponent(t.slice(e.length)),s=JSON.parse(n);if(Array.isArray(s)&&s.length>0&&s.every(r=>typeof r=="string"))return s;throw new Error("Invalid DOTIFY path framing")}function $t(t){return typeof t=="object"&&t!==null&&t.__type__==="dotify"&&typeof t.__value__=="string"}function At(t,e,n){const s={...R,...e},r={};for(const[i,o]of Object.entries(t)){if(o===void 0)continue;const a=s[i];r[i]=Lt(o,a,n)}return r}function Lt(t,e,n){if(typeof t=="function")return n.serialize(t);const s=e?.serialization??x.JSON;if(s===x.BASE64&&typeof t=="object"){const r=JSON.stringify(t);return{__type__:"base64",__value__:btoa(encodeURIComponent(r))}}return s===x.DOTIFY&&typeof t=="object"&&t!==null&&!Array.isArray(t)?{__type__:"dotify",__value__:$e(t)}:ce(t,n)}function Ae(t,e,n,s,r,i){const o={...R,...e},a={};for(const[c,l]of Object.entries(t)){if(!Ne(c))continue;const p=o[c];a[c]=Mt(l,p,n,s,r,i)}return a}function Mt(t,e,n,s,r,i){if(zt(t))try{const o=decodeURIComponent(atob(t.__value__));return JSON.parse(o)}catch{return t}if($t(t))try{return Ft(t.__value__)}catch{return t}return le(t,s,r,i)}function zt(t){return typeof t=="object"&&t!==null&&t.__type__==="base64"&&typeof t.__value__=="string"}class kt{constructor(e,n,s){this.options=e,this.createPropContext=s,this.inputProps={...n};const r=this.inputProps,i=this.createPropContext(r);this.props=De(r,this.options.props,i)}props;inputProps;pendingPropsUpdate=null;buildNextProps(e){const n={...this.inputProps,...e},s={...this.props,...e},r=this.createPropContext(s),i=De(s,this.options.props,r);return H(i,this.options.props),this.options.validate?.({props:i}),{nextInputProps:n,nextProps:i}}updateProps(e,n){return this.queuePropsUpdate(async()=>{const{nextInputProps:s,nextProps:r}=this.buildNextProps(e),i=n.resolveUrl(r),o=n.resolveUrlOrigin(i);n.assertStableRenderedOrigin(o),this.inputProps=s,this.props=r,n.isRendered()||n.syncTrustedDomainForUrl(i),n.shouldSendPropsToHost()&&await n.sendPropsUpdateToHost(r),n.emitPropsUpdated(r)},n.shouldSendPropsToHost)}syncCurrentPropsToHost(e){return this.queuePropsUpdate(async()=>{e.shouldSendPropsToHost()&&await e.sendPropsUpdateToHost(this.props)},e.shouldSendPropsToHost)}queuePropsUpdate(e,n){if(!this.pendingPropsUpdate){const r=e();return n()&&this.trackPendingUpdate(r),r}const s=this.pendingPropsUpdate.then(e,e);return this.trackPendingUpdate(s),s}trackPendingUpdate(e){const n=e.then(()=>{},()=>{});this.pendingPropsUpdate=n,n.finally(()=>{this.pendingPropsUpdate===n&&(this.pendingPropsUpdate=null)})}}function I(t,e="100%"){return t===void 0?e:typeof t=="number"?`${t}px`:t}function Q(t,e){if(t===void 0)return e;if(typeof t=="number")return t;const n=parseInt(t,10);return isNaN(n)?e:n}function Wt(t){const{name:e,dimensions:n,attributes:s={},style:r={}}=t,i=document.createElement("iframe");return i.name=e,i.setAttribute("frameborder","0"),i.setAttribute("allowtransparency","true"),i.setAttribute("scrolling","auto"),Me(i,n),qt(i,s),Jt(i,r),Kt(i,s),i}function jt(t){try{t.src="about:blank",t.parentNode?.removeChild(t)}catch{}}function Bt(t,e){Me(t,e)}function Vt(t){t.style.display="",t.style.visibility="visible"}function Le(t){t.style.display="none",t.style.visibility="hidden"}function Yt(t){try{t.focus(),t.contentWindow?.focus()}catch{}}function Me(t,e){e.width!==void 0&&(t.style.width=I(e.width)),e.height!==void 0&&(t.style.height=I(e.height))}function Jt(t,e){for(const[n,s]of Object.entries(e)){if(s===void 0)continue;const r=typeof s=="number"?`${s}px`:s;t.style.setProperty(n.replace(/([A-Z])/g,"-$1").toLowerCase(),r)}}function qt(t,e){for(const[n,s]of Object.entries(e))if(s!==void 0){if(typeof s=="boolean"){s&&t.setAttribute(n,"");continue}t.setAttribute(n,s)}}function Kt(t,e){e.sandbox===void 0&&t.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups")}class ue extends Error{constructor(e="Popup blocked by browser"){super(e),this.name="PopupOpenError"}}function Xt(t){const{url:e,name:n,dimensions:s}=t,r=Q(s.width,500),i=Q(s.height,500),o=Math.floor(window.screenX+(window.outerWidth-r)/2),a=Math.floor(window.screenY+(window.outerHeight-i)/2),c=[`width=${r}`,`height=${i}`,`left=${o}`,`top=${a}`,"menubar=no","toolbar=no","location=yes","status=no","resizable=yes","scrollbars=yes"].join(","),l=window.open(e,n,c);if(!l||Qt(l))throw new ue;return l}function Gt(t){try{t.closed||t.close()}catch{}}function Zt(t){try{t.closed||t.focus()}catch{}}function Qt(t){if(!t)return!0;try{return!!(t.closed||t.innerHeight===0||t.innerWidth===0)}catch{return!0}}function en(t,e,n={}){const{initialInterval:s=100,maxInterval:r=2e3,multiplier:i=1.5}=n;let o=s,a,c=!1;const l=()=>{try{e()}catch(y){console.error("Error in popup close callback:",y)}},p=()=>{if(!c){try{if(t.closed){l();return}}catch{l();return}o=Math.min(o*i,r),a=setTimeout(p,o)}};return a=setTimeout(p,o),()=>{c=!0,clearTimeout(a)}}function tn(t,e){try{const n=Q(e.width,t.outerWidth),s=Q(e.height,t.outerHeight);t.resizeTo(n,s)}catch{}}const ze="forgeframe-spinner-style";function nn(t,e){const n=t.getElementById(ze);if(n){const r=n.getAttribute("nonce");if(!e||r===e)return;n.remove()}const s=t.createElement("style");s.id=ze,e&&s.setAttribute("nonce",e),s.textContent=`
2
2
  @keyframes forgeframe-spin {
3
3
  to { transform: rotate(360deg); }
4
4
  }
5
- `,(s.head??s.documentElement).appendChild(n)}function Nt(s){const{doc:e,dimensions:t,uid:n,tag:r}=s,i=e.createElement("div");return i.id=`forgeframe-container-${n}`,i.setAttribute("data-forgeframe-tag",r),Object.assign(i.style,{display:"inline-block",position:"relative",width:S(t.width),height:S(t.height),overflow:"hidden"}),i}function Ft(s){const{doc:e,dimensions:t,cspNonce:n}=s;Ut(e,n);const r=e.createElement("div");Object.assign(r.style,{display:"flex",alignItems:"center",justifyContent:"center",width:S(t.width),height:S(t.height),backgroundColor:"#f5f5f5",position:"absolute",top:"0",left:"0",zIndex:"100"});const i=e.createElement("div");return Object.assign(i.style,{width:"40px",height:"40px",border:"3px solid #e0e0e0",borderTopColor:"#3498db",borderRadius:"50%",animation:"forgeframe-spin 1s linear infinite"}),r.appendChild(i),r}function Ht(s,e=200){return new Promise(t=>{s.style.opacity="0",s.style.transition=`opacity ${e}ms ease-in`,s.offsetHeight,s.style.opacity="1",setTimeout(t,e)})}function $t(s,e=200){return new Promise(t=>{s.style.transition=`opacity ${e}ms ease-out`,s.style.opacity="0",setTimeout(t,e)})}async function At(s,e,t){e&&(await $t(e,150),e.remove()),t.style.display="",t.style.visibility="visible",t.style.opacity="0",await Ht(t,150)}class Lt{constructor(e,t,n,r,i){this.options=e,this.uid=t,this.getProps=n,this.resolveDimensions=r,this.callbacks=i,this.context=this.options.defaultContext}context;iframe=null;container=null;prerenderElement=null;resolveContainer(e){if(!e)throw new Error("Container is required for rendering");if(typeof e=="string"){const t=document.querySelector(e);if(!t)throw new Error(`Container "${e}" not found`);return t}return e}async prerender(e,t){if(!this.container)return;const n=this.getProps(),r=this.options.prerenderTemplate??Ft,i=this.options.containerTemplate??Nt,o=this.resolveDimensions(),a=n.cspNonce;if(this.context===p.IFRAME){const g=t();this.iframe=e(g),Se(this.iframe)}const c={uid:this.uid,tag:this.options.tag,context:this.context,dimensions:o,props:n,doc:document,container:this.container,frame:this.iframe,prerenderFrame:null,close:()=>this.callbacks.close(),focus:()=>this.callbacks.focus(),cspNonce:a};this.prerenderElement=r(c);const l={uid:this.uid,tag:this.options.tag,context:this.context,dimensions:o,props:n,doc:document,container:this.container,frame:this.iframe,prerenderFrame:this.prerenderElement,close:()=>this.callbacks.close(),focus:()=>this.callbacks.focus(),cspNonce:a},d=i(l);d&&(this.container.appendChild(d),this.container=d),this.prerenderElement&&!this.prerenderElement.parentNode&&this.container.appendChild(this.prerenderElement),this.iframe&&!this.iframe.parentNode&&this.container.appendChild(this.iframe)}createIframeElement(e){const t=document.createElement("iframe"),n=this.resolveDimensions(),r=this.getProps(),i=typeof this.options.attributes=="function"?this.options.attributes(r):this.options.attributes??{},o=typeof this.options.style=="function"?this.options.style(r):this.options.style??{};t.name=e,t.setAttribute("frameborder","0"),t.setAttribute("allowtransparency","true"),t.setAttribute("scrolling","auto"),n.width!==void 0&&(t.style.width=typeof n.width=="number"?`${n.width}px`:n.width),n.height!==void 0&&(t.style.height=typeof n.height=="number"?`${n.height}px`:n.height);for(const[a,c]of Object.entries(i))c!==void 0&&(typeof c=="boolean"?c&&t.setAttribute(a,""):t.setAttribute(a,c));for(const[a,c]of Object.entries(o)){if(c===void 0)continue;const l=typeof c=="number"?`${c}px`:c;t.style.setProperty(a.replace(/([A-Z])/g,"-$1").toLowerCase(),String(l))}return i.sandbox||t.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox"),t}open(e){const t=e.buildUrl(e.baseUrl),n=e.buildBodyParams(),r=n.toString().length>0;if(this.context===p.IFRAME){if(!this.iframe)throw new Error("Iframe not created during prerender");return r?e.submitBodyForm(this.iframe.name,t,n):this.iframe.src=t,this.iframe.contentWindow}const i=e.buildWindowName(),o=vt({url:r?"about:blank":t,name:i,dimensions:this.resolveDimensions()});r&&e.submitBodyForm(i,t,n);const a=Dt(o,()=>{e.onPopupClose()});return e.registerCleanup(a),o}async swapPrerenderContentIfNeeded(){this.context===p.IFRAME&&this.iframe&&this.container&&(await At(this.container,this.prerenderElement,this.iframe),this.prerenderElement=null)}submitBodyForm(e,t,n){const r=this.container?.ownerDocument??document,i=r.body??r.documentElement;if(!i)throw new Error("Document root is unavailable for bodyParam form submission");const o=r.createElement("form");o.method="POST",o.action=t,o.target=e,o.style.display="none";for(const[a,c]of n.entries()){const l=r.createElement("input");l.type="hidden",l.name=a,l.value=c,o.appendChild(l)}i.appendChild(o);try{o.submit()}finally{o.remove()}}focus(e){this.context===p.IFRAME&&this.iframe?St(this.iframe):this.context===p.POPUP&&e&&It(e)}resize(e,t){this.context===p.IFRAME&&this.iframe?bt(this.iframe,e):this.context===p.POPUP&&t&&Tt(t,e)}show(){this.context===p.IFRAME&&this.iframe&&Rt(this.iframe)}hide(){this.context===p.IFRAME&&this.iframe&&Se(this.iframe)}destroy(e){this.iframe&&(Et(this.iframe),this.iframe=null),this.context===p.POPUP&&e&&Ct(e),this.prerenderElement&&(this.prerenderElement.remove(),this.prerenderElement=null)}}const ne="forgeframe:";function re(s){return ne+JSON.stringify(s)}function zt(s){if(typeof s!="string"||!s.startsWith(ne))return null;try{const e=s.slice(ne.length),t=JSON.parse(e);return!t.id||!t.type||!t.name||!t.source?null:t}catch{return null}}function ve(s,e,t,n){return{id:s,type:H.REQUEST,name:e,data:t,source:n}}function kt(s,e,t,n){return{id:s,type:H.RESPONSE,name:"response",data:e,source:t,error:n?{message:n.message,stack:n.stack}:void 0}}function Mt(s){return s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Wt(s){if(!s.includes("*"))return null;const e=s.split("*").map(t=>Mt(t)).join(".*");return new RegExp(`^${e}$`)}function Bt(s,e){return s.global||s.sticky?new RegExp(s.source,s.flags.replace(/[gy]/g,"")).test(e):s.test(e)}class Ce{constructor(e,t=window,n=window.location.origin,r){this.uid=e,this.win=t,this.domain=n,this.allowedOrigins.add(n),r&&this.addTrustedDomain(r),this.setupListener()}pending=new Map;handlers=new Map;listener=null;destroyed=!1;allowedOrigins=new Set;allowedOriginPatterns=[];wildcardPatternRegistry=new Map;sourceUidRegistry=new WeakMap;addTrustedDomain(e){if(Array.isArray(e))for(const t of e)this.addTrustedDomain(t);else if(e instanceof RegExp)this.allowedOriginPatterns.push(e);else{const t=Wt(e);t?this.wildcardPatternRegistry.has(e)||(this.wildcardPatternRegistry.set(e,t),this.allowedOriginPatterns.push(t)):this.allowedOrigins.add(e)}}removeTrustedDomain(e){if(Array.isArray(e))for(const t of e)this.removeTrustedDomain(t);else if(e instanceof RegExp)this.allowedOriginPatterns=this.allowedOriginPatterns.filter(t=>t!==e);else{const t=this.wildcardPatternRegistry.get(e);t&&(this.allowedOriginPatterns=this.allowedOriginPatterns.filter(n=>n!==t),this.wildcardPatternRegistry.delete(e)),this.allowedOrigins.delete(e)}}isOriginTrusted(e){if(this.allowedOrigins.has(e))return!0;for(const t of this.allowedOriginPatterns)if(Bt(t,e))return!0;return!1}resolveVerifiedSource(e,t,n){const r=e,i=this.sourceUidRegistry.get(r);if(i)return{uid:i,domain:t};const o=n&&typeof n.uid=="string"&&n.uid.length>0?n.uid:A();return this.sourceUidRegistry.set(r,o),{uid:o,domain:t}}async send(e,t,n,r,i=1e4){if(this.destroyed)throw new Error("Messenger has been destroyed");const o=A(),a=ve(o,n,r,{uid:this.uid,domain:this.domain}),c=fe(),l=setTimeout(()=>{this.pending.delete(o),c.reject(new Error(`Message "${n}" timed out after ${i}ms`))},i);this.pending.set(o,{deferred:c,timeout:l});try{e.postMessage(re(a),t)}catch(d){throw this.pending.delete(o),clearTimeout(l),d}return c.promise}post(e,t,n,r){if(this.destroyed)throw new Error("Messenger has been destroyed");const i=A(),o=ve(i,n,r,{uid:this.uid,domain:this.domain});e.postMessage(re(o),t)}on(e,t){return this.handlers.set(e,t),()=>this.handlers.delete(e)}setupListener(){this.listener=e=>{if(e.source===this.win||!this.isOriginTrusted(e.origin))return;const t=zt(e.data);if(!t)return;const n=e.source;!n||typeof n.postMessage!="function"||this.handleMessage(t,n,e.origin)},this.win.addEventListener("message",this.listener)}async handleMessage(e,t,n){if(e.type===H.RESPONSE){const r=this.pending.get(e.id);if(r)if(this.pending.delete(e.id),clearTimeout(r.timeout),e.error){const i=new Error(e.error.message);i.stack=e.error.stack,r.deferred.reject(i)}else r.deferred.resolve(e.data);return}if(e.type===H.REQUEST){const r=this.handlers.get(e.name);if(!r)return;let i,o;try{const c=this.resolveVerifiedSource(t,n,e.source);i=await r(e.data,c)}catch(c){o=c instanceof Error?c:new Error(String(c))}const a=kt(e.id,i,{uid:this.uid,domain:this.domain},o);try{t.postMessage(re(a),n)}catch{}}}destroy(){if(!this.destroyed){this.destroyed=!0,this.listener&&(this.win.removeEventListener("message",this.listener),this.listener=null);for(const e of this.pending.values())clearTimeout(e.timeout),e.deferred.reject(new Error("Messenger destroyed"));this.pending.clear(),this.handlers.clear()}}isDestroyed(){return this.destroyed}}const Ie=32*1024;function jt(s){const e=Vt(s);return`${$}${e}`}function xe(s){if(!s||!s.startsWith($))return null;const e=s.slice($.length);return Kt(e)}function ie(s=window){try{return s.name.startsWith($)}catch{return!1}}function oe(s,e=window){return xe(e.name)?.tag===s}function Vt(s){try{const e=JSON.stringify(s),t=btoa(encodeURIComponent(e)),n=new Blob([t]).size;if(n>Ie)throw new Error(`Payload size (${Math.round(n/1024)}KB) exceeds maximum allowed size (${Ie/1024}KB). Consider reducing the amount of data passed via props.`);return t}catch(e){throw e instanceof Error&&e.message.includes("Payload size")?e:new Error(`Failed to encode payload: ${e}`)}}function Kt(s){try{const e=decodeURIComponent(atob(s));return JSON.parse(e)}catch{return null}}function qt(s){return{uid:s.uid,tag:s.tag,version:Y,context:s.context,consumerDomain:s.consumerDomain,props:s.props,exports:s.exports,children:s.children}}function Jt(s=window){return xe(s.name)}class Xt{constructor(e,t,n,r){this.uid=e,this.options=t,this.resolveUrl=n,this.resolveUrlOrigin=r;const i=this.buildTrustedDomains();this.messenger=new Ce(this.uid,window,G(),i),this.bridge=new Q(this.messenger)}messenger;bridge;hostWindow=null;openedHostDomain=null;dynamicUrlTrustedOrigin=null;initPromise=null;hostInitialized=!1;buildTrustedDomains(){const e=[],t=this.resolveUrlOrigin(this.resolveUrl());if(t&&(e.push(t),this.dynamicUrlTrustedOrigin=t),this.options.domain&&(typeof this.options.domain=="string"?e.push(this.options.domain):Array.isArray(this.options.domain)?e.push(...this.options.domain):this.options.domain instanceof RegExp&&e.push(this.options.domain)),e.length!==0)return e.length===1?e[0]:e}isExplicitDomainTrust(e){return this.options.domain?C(this.options.domain,e):!1}syncTrustedDomainForUrl(e){const t=this.resolveUrlOrigin(e);if(!t)return;const n=this.dynamicUrlTrustedOrigin;n&&n!==t&&!this.isExplicitDomainTrust(n)&&this.messenger.removeTrustedDomain(n),this.messenger.addTrustedDomain(t),this.dynamicUrlTrustedOrigin=t}getHostDomain(){return this.openedHostDomain?this.openedHostDomain:this.resolveUrlOrigin(this.resolveUrl())??"*"}isHostConnected(){return!!(this.hostWindow&&!Z(this.hostWindow))}serializePropsForHost(e,t,n){this.bridge.startBatch();const r=n?.finishBatch??!0;try{const i=gt(e,t,this.bridge);return r&&this.bridge.finishBatch(),i}catch(i){throw this.bridge.finishBatch(!0),i}}async sendPropsUpdateToHost(e,t){if(!this.hostWindow||Z(this.hostWindow))return;const n=this.getHostDomain(),r=we(e,t,n,Qe(this.hostWindow)),i=this.serializePropsForHost(r,t,{finishBatch:!1});try{await this.messenger.send(this.hostWindow,n,h.PROPS,i),this.bridge.finishBatch()}catch(o){throw this.bridge.finishBatch(!0),o}}buildWindowName(e){const t=e.hostDomain??this.getHostDomain(),n=we(e.props,e.propDefinitions,t,!1),r=this.serializePropsForHost(n,e.propDefinitions),i=qt({uid:this.uid,tag:e.tag,context:e.context,consumerDomain:G(),props:r,exports:e.exports,children:e.children});return jt(i)}async waitForHost(e,t,n){if(this.hostInitialized)return;const r=fe();this.initPromise=r;try{await Je(r.promise,e,`Host component "${t}" (uid: ${this.uid}) did not initialize within ${e}ms. Check that the host page loads correctly and calls the initialization code.`)}catch(i){throw n(i),i}finally{this.initPromise===r&&(this.initPromise=null)}}setupMessageHandlers(e){this.messenger.on(h.INIT,()=>(this.hostInitialized=!0,this.initPromise&&this.initPromise.resolve(),{success:!0})),this.messenger.on(h.CLOSE,async()=>(await e.onClose(),{success:!0})),this.messenger.on(h.RESIZE,async t=>(await e.onResize(t),{success:!0})),this.messenger.on(h.FOCUS,async()=>(await e.onFocus(),{success:!0})),this.messenger.on(h.SHOW,async()=>(await e.onShow(),{success:!0})),this.messenger.on(h.HIDE,async()=>(await e.onHide(),{success:!0})),this.messenger.on(h.ERROR,async t=>{const n=new Error(t.message);return n.stack=t.stack,e.onError(n),{success:!0}}),this.messenger.on(h.EXPORT,async t=>(e.onExport(t),{success:!0})),this.messenger.on(h.CONSUMER_EXPORT,async t=>(e.onConsumerExport(t),{success:!0})),this.messenger.on(h.GET_SIBLINGS,async t=>e.onGetSiblings(t))}destroy(){this.messenger.destroy(),this.bridge.destroy()}}class ae{event;state={};exports;consumerExports;_uid;get uid(){return this._uid}options;cleanup;transport;renderer;propsPipeline;rendered=!1;destroyed=!1;get props(){return this.propsPipeline?this.propsPipeline.props:{}}set props(e){this.propsPipeline&&(this.propsPipeline.props=e)}get inputProps(){return this.propsPipeline?this.propsPipeline.inputProps:{}}set inputProps(e){this.propsPipeline&&(this.propsPipeline.inputProps=e)}get pendingPropsUpdate(){return this.propsPipeline?this.propsPipeline.pendingPropsUpdate:null}set pendingPropsUpdate(e){this.propsPipeline&&(this.propsPipeline.pendingPropsUpdate=e)}get context(){return this.renderer?this.renderer.context:this.options.defaultContext}set context(e){this.renderer&&(this.renderer.context=e)}get hostWindow(){return this.transport?this.transport.hostWindow:null}set hostWindow(e){this.transport&&(this.transport.hostWindow=e)}get openedHostDomain(){return this.transport?this.transport.openedHostDomain:null}set openedHostDomain(e){this.transport&&(this.transport.openedHostDomain=e)}get dynamicUrlTrustedOrigin(){return this.transport?this.transport.dynamicUrlTrustedOrigin:null}set dynamicUrlTrustedOrigin(e){this.transport&&(this.transport.dynamicUrlTrustedOrigin=e)}get iframe(){return this.renderer?this.renderer.iframe:null}set iframe(e){this.renderer&&(this.renderer.iframe=e)}get container(){return this.renderer?this.renderer.container:null}set container(e){this.renderer&&(this.renderer.container=e)}get initPromise(){return this.transport?this.transport.initPromise:null}set initPromise(e){this.transport&&(this.transport.initPromise=e)}get hostInitialized(){return this.transport?this.transport.hostInitialized:!1}set hostInitialized(e){this.transport&&(this.transport.hostInitialized=e)}get messenger(){if(!this.transport)throw new Error("Consumer transport is not initialized");return this.transport.messenger}get bridge(){if(!this.transport)throw new Error("Consumer transport is not initialized");return this.transport.bridge}constructor(e,t={}){this._uid=Ke(),this.options=this.normalizeOptions(e),this.event=new pe,this.cleanup=new qe,this.renderer=new Lt(this.options,this.uid,()=>this.props,()=>this.resolveDimensions(),{close:()=>this.close(),focus:()=>this.focus()}),this.propsPipeline=new Pt(this.options,{...t},n=>this.createPropContext(n)),this.transport=new Xt(this.uid,this.options,()=>this.resolveUrl(),n=>this.resolveUrlOrigin(n)),this.setupMessageHandlers(),this.setupCleanup()}async render(e,t){if(this.destroyed)throw new Error("Component has been destroyed");if(this.rendered)throw new Error("Component has already been rendered");this.context=t??this.options.defaultContext,this.checkEligibility(),ye(this.props,this.options.props),this.options.validate?.({props:this.props}),this.container=this.resolveContainer(e),this.event.emit(m.PRERENDER),this.callPropCallback("onPrerender"),await this.prerender(),this.event.emit(m.PRERENDERED),this.callPropCallback("onPrerendered"),this.event.emit(m.RENDER),this.callPropCallback("onRender");try{await this.open(),await this.waitForHost(),this.context===p.IFRAME&&this.iframe&&await this.renderer.swapPrerenderContentIfNeeded()}catch(n){throw await this.destroy().catch(()=>{}),n}this.rendered=!0,this.event.emit(m.RENDERED),this.callPropCallback("onRendered"),this.event.emit(m.DISPLAY),this.callPropCallback("onDisplay")}async renderTo(e,t,n){if(e!==window)throw new Error("Cross-window renderTo is not supported; pass the current window");return this.render(t,n)}async close(){this.destroyed||(this.event.emit(m.CLOSE),await this.destroy())}async focus(){this.renderer.focus(this.hostWindow),this.event.emit(m.FOCUS),this.callPropCallback("onFocus")}async resize(e){this.renderer.resize(e,this.hostWindow),this.event.emit(m.RESIZE,e),this.callPropCallback("onResize",e)}async show(){this.renderer.show()}async hide(){this.renderer.hide()}async updateProps(e){return this.applyPropsUpdate(e)}async applyPropsUpdate(e){const t={resolveUrl:n=>this.resolveUrl(n),resolveUrlOrigin:n=>this.resolveUrlOrigin(n),assertStableRenderedOrigin:n=>this.assertStableRenderedOrigin(n),isRendered:()=>this.rendered,syncTrustedDomainForUrl:n=>this.syncTrustedDomainForUrl(n),shouldSendPropsToHost:()=>this.transport.isHostConnected(),sendPropsUpdateToHost:n=>this.sendPropsUpdateToHost(n),emitPropsUpdated:()=>this.emitPropsUpdated()};await this.propsPipeline.updateProps(e,t)}assertStableRenderedOrigin(e){if(this.rendered&&this.openedHostDomain&&e&&e!==this.openedHostDomain)throw new Error(`Cannot change component URL origin after render (from "${this.openedHostDomain}" to "${e}")`)}async sendPropsUpdateToHost(e){await this.transport.sendPropsUpdateToHost(e,this.options.props)}emitPropsUpdated(){this.event.emit(m.PROPS,this.props),this.callPropCallback("onProps",this.props)}clone(){const e=new ae(this.options,this.props);return e.inputProps={...this.inputProps},e}isEligible(){return this.options.eligible?this.options.eligible({props:this.props}).eligible:!0}normalizeOptions(e){return{...e,props:e.props??{},defaultContext:e.defaultContext??p.IFRAME,dimensions:e.dimensions??{width:"100%",height:"100%"},timeout:e.timeout??1e4,children:e.children}}resolveUrl(e=this.props){return typeof this.options.url=="function"?this.options.url(e):this.options.url}resolveDimensions(){return typeof this.options.dimensions=="function"?this.options.dimensions(this.props):this.options.dimensions}resolveUrlOrigin(e){try{return new URL(e,window.location.origin).origin}catch{return null}}isExplicitDomainTrust(e){return this.transport.isExplicitDomainTrust(e)}syncTrustedDomainForUrl(e){const t=this.resolveUrlOrigin(e);t&&this.isExplicitDomainTrust(t),this.transport.syncTrustedDomainForUrl(e)}createPropContext(e=this.props){return{props:e,state:this.state,close:()=>this.close(),focus:()=>this.focus(),onError:t=>this.handleError(t),container:this.container,uid:this.uid,tag:this.options.tag}}resolveContainer(e){return this.renderer.resolveContainer(e)}checkEligibility(){if(!this.options.eligible)return;const e=this.options.eligible({props:this.props});if(!e.eligible)throw new Error(`Component not eligible: ${e.reason??"Unknown reason"}`)}async prerender(){await this.renderer.prerender(e=>this.createIframeElement(e),()=>this.buildWindowName())}createIframeElement(e){return this.renderer.createIframeElement(e)}async open(){const e=this.resolveUrl();this.syncTrustedDomainForUrl(e),this.openedHostDomain=this.resolveUrlOrigin(e),this.hostWindow=this.renderer.open({baseUrl:e,buildUrl:t=>this.buildUrl(t),buildBodyParams:()=>this.buildBodyParams(),buildWindowName:()=>this.buildWindowName(),submitBodyForm:(t,n,r)=>this.submitBodyForm(t,n,r),onPopupClose:()=>{this.close()},registerCleanup:t=>{this.cleanup.register(t)}}),this.hostWindow&&it(this.uid,this.hostWindow)}buildUrl(e=this.resolveUrl()){const n=ut(this.props,this.options.props).toString();if(!n)return e;const r=e.includes("?")?"&":"?";return`${e}${r}${n}`}buildBodyParams(){return ht(this.props,this.options.props)}submitBodyForm(e,t,n){this.renderer.submitBodyForm(e,t,n)}buildWindowName(){return this.transport.buildWindowName({tag:this.options.tag,context:this.context,props:this.props,propDefinitions:this.options.props,hostDomain:this.getHostDomain(),children:this.buildNestedHostRefs(),exports:this.createConsumerExports()})}buildNestedHostRefs(){if(!this.options.children)return;const e=this.options.children({props:this.props}),t={};for(const[n,r]of Object.entries(e)){const i=is(r);if(!i)throw new Error(`Nested component "${n}" is missing component metadata`);if(typeof i.url!="string")throw new Error(`Nested component "${n}" must use a static string URL. Function URLs are not supported in children.`);t[n]={tag:i.tag,url:i.url,props:i.props,dimensions:typeof i.dimensions=="function"?void 0:i.dimensions,defaultContext:i.defaultContext}}return Object.keys(t).length>0?t:void 0}createConsumerExports(){return{init:h.INIT,close:h.CLOSE,resize:h.RESIZE,show:h.SHOW,hide:h.HIDE,onError:h.ERROR,updateProps:h.PROPS,export:h.EXPORT}}getHostDomain(){return this.transport.getHostDomain()}async waitForHost(){await this.transport.waitForHost(this.options.timeout,this.options.tag,e=>this.handleError(e))}setupMessageHandlers(){this.transport.setupMessageHandlers({onClose:async()=>this.close(),onResize:async e=>this.resize(e),onFocus:async()=>this.focus(),onShow:async()=>this.show(),onHide:async()=>this.hide(),onError:e=>this.handleError(e),onExport:e=>{this.exports=e},onConsumerExport:e=>{this.consumerExports=e},onGetSiblings:e=>this.getSiblingInstances(e)})}getSiblingInstances(e){const t=[];if(e.options?.anyConsumer){for(const n of rs())n.instance.uid!==e.uid&&t.push({uid:n.instance.uid,tag:n.tag,exports:n.instance.exports});return t}for(const n of ns(e.tag))n.uid!==e.uid&&t.push({uid:n.uid,tag:e.tag,exports:n.exports});return t}setupCleanup(){this.cleanup.register(()=>{this.messenger.destroy(),this.bridge.destroy(),ot(this.uid)})}handleError(e){this.event.emit(m.ERROR,e),this.callPropCallback("onError",e)}callPropCallback(e,...t){const n=this.props[e];if(typeof n=="function")try{const r=n(...t);r&&typeof r=="object"&&"catch"in r&&typeof r.catch=="function"&&r.catch(i=>{console.error(`Error in async ${e} callback:`,i)})}catch(r){console.error(`Error in ${e} callback:`,r)}}async destroy(){this.destroyed||(this.destroyed=!0,this.initPromise&&(this.initPromise.reject(new Error(`Component "${this.options.tag}" was destroyed before initialization completed`)),this.initPromise=null),this.hostInitialized=!1,this.renderer.destroy(this.hostWindow),this.hostWindow=null,this.openedHostDomain=null,this.dynamicUrlTrustedOrigin=null,this.pendingPropsUpdate=null,await this.cleanup.cleanup(),this.event.emit(m.DESTROY),this.callPropCallback("onDestroy"),this.event.removeAllListeners())}}const U=new Map,N=new Map;function Yt(s,e){const t=e;U.get(t.uid)&&De(t.uid);let r=N.get(s);r||(r=new Map,N.set(s,r)),r.set(t.uid,t),U.set(t.uid,{tag:s,instance:t})}function De(s){const e=U.get(s);if(!e)return;U.delete(s);const t=N.get(e.tag);t&&(t.delete(s),t.size===0&&N.delete(e.tag))}function Gt(s){return Array.from(N.get(s)?.values()??[])}function Zt(){return Array.from(U.values())}const Te="Could not resolve consumer window",Qt=new Set(["uid","tag","close","focus","resize","show","hide","onProps","onError","getConsumer","getConsumerDomain","export","consumer","getPeerInstances","children"]);class es{constructor(e,t={},n,r=!1){this.propDefinitions=t,this.allowedConsumerDomains=n,this.deferInit=r,this.uid=e.uid,this.tag=e.tag,this.consumerDomain=e.consumerDomain,this.validateConsumerDomain(),this.event=new pe,this.messenger=new Ce(this.uid,window,G(),this.consumerDomain);let i=null;try{this.setupMessageHandlers(),this.consumerWindow=this.resolveConsumerWindow(),i=new Q(this.messenger),this.bridge=i,this.hostProps=this.buildHostProps(e),this.exposeHostProps(),this.deferInit||this.flushInit()}catch(o){throw i?.destroy(),this.messenger.destroy(),this.event.removeAllListeners(),this.propsHandlers.clear(),o}}hostProps;event;uid;tag;consumerWindow;consumerDomain;messenger;bridge;propsHandlers=new Set;consumerProps;initError=null;destroyed=!1;initSent=!1;deferredInitFlushScheduled=!1;flushInit(){this.destroyed||this.initSent||(this.initSent=!0,this.sendInit())}scheduleDeferredInitFlush(){this.deferredInitFlushScheduled||this.destroyed||this.initSent||(this.deferredInitFlushScheduled=!0,queueMicrotask(()=>{this.deferredInitFlushScheduled=!1,this.flushInit()}))}exposeHostProps(){const e=window;try{Object.defineProperty(e,"hostProps",{configurable:!0,enumerable:!0,get:()=>(this.deferInit&&!this.initSent&&!this.destroyed&&this.scheduleDeferredInitFlush(),this.hostProps),set:t=>{t&&(this.hostProps=t)}})}catch{e.hostProps=this.hostProps}}validateConsumerDomain(){if(this.allowedConsumerDomains&&!C(this.allowedConsumerDomains,this.consumerDomain))throw new Error(`Consumer domain "${this.consumerDomain}" is not allowed for component "${this.tag}"`)}getProps(){return this.hostProps}resolveConsumerWindow(){if(st()){const e=tt();if(e)return e}if(nt()){const e=et();if(e)return e}throw new Error(Te)}buildHostProps(e){const t=Re(e.props,this.propDefinitions,this.messenger,this.bridge,this.consumerWindow,this.consumerDomain);return this.consumerProps=t,{...t,uid:this.uid,tag:this.tag,close:()=>this.close(),focus:()=>this.focus(),resize:n=>this.resize(n),show:()=>this.show(),hide:()=>this.hide(),onProps:n=>this.onProps(n),onError:n=>this.onError(n),getConsumer:()=>this.consumerWindow,getConsumerDomain:()=>this.consumerDomain,export:n=>this.exportData(n),consumer:{props:this.consumerProps,export:n=>this.consumerExport(n)},getPeerInstances:n=>this.getPeerInstances(n),children:this.buildNestedComponents(e.children)}}async sendInit(){try{await this.messenger.send(this.consumerWindow,this.consumerDomain,h.INIT,{uid:this.uid,tag:this.tag})}catch(e){const t=e instanceof Error?e:new Error(String(e));this.initError=t,this.event.emit(m.ERROR,{type:"init_failed",message:`Failed to initialize host component: ${t.message}`,error:t}),console.error("Failed to send init message:",e)}}getInitError(){return this.initError}async close(){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.CLOSE,{})}async focus(){window.focus(),await this.messenger.send(this.consumerWindow,this.consumerDomain,h.FOCUS,{})}async resize(e){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.RESIZE,e)}async show(){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.SHOW,{})}async hide(){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.HIDE,{})}onProps(e){return this.propsHandlers.add(e),{cancel:()=>this.propsHandlers.delete(e)}}async onError(e){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.ERROR,{message:e.message,stack:e.stack})}async exportData(e){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.EXPORT,e)}async consumerExport(e){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.CONSUMER_EXPORT,e)}async getPeerInstances(e){return await this.messenger.send(this.consumerWindow,this.consumerDomain,h.GET_SIBLINGS,{uid:this.uid,tag:this.tag,options:e})??[]}buildNestedComponents(e){if(!e)return;const t={};for(const[n,r]of Object.entries(e))try{t[n]=ce({tag:r.tag,url:r.url,props:r.props,dimensions:r.dimensions,defaultContext:r.defaultContext})}catch(i){console.warn(`Failed to create nested component "${n}":`,i)}return Object.keys(t).length>0?t:void 0}setupMessageHandlers(){this.messenger.on(h.PROPS,e=>{try{const t=this.consumerProps,n=Re(e,this.propDefinitions,this.messenger,this.bridge,this.consumerWindow,this.consumerDomain);this.removeStaleHostProps(t,n),this.consumerProps=n,Object.assign(this.hostProps,n),this.hostProps.consumer.props=this.consumerProps;for(const r of this.propsHandlers)try{r(n)}catch(i){console.error("Error in props handler:",i)}return this.event.emit(m.PROPS,n),{success:!0}}catch(t){const n=t instanceof Error?t:new Error(String(t));throw console.error("Error deserializing props:",n),this.event.emit(m.ERROR,n),n}})}removeStaleHostProps(e,t){for(const n of Object.keys(e))n in t||Qt.has(n)||delete this.hostProps[n]}destroy(){this.destroyed||(this.destroyed=!0,this.deferredInitFlushScheduled=!1,this.messenger.destroy(),this.bridge.destroy(),this.event.removeAllListeners(),this.propsHandlers.clear())}}let P=null;function K(s,e,t={}){if(P){if(e){const r=P.getProps().getConsumerDomain();if(!C(e,r))throw ts(),new Error(`Consumer domain "${r}" is not allowed for this host component`)}return t.deferInit||P.flushInit(),P}if(!ie())return null;const n=Jt();if(!n)return console.error("Failed to parse ForgeFrame payload from window.name"),null;try{P=new es(n,s,e,t.deferInit??!1)}catch(r){if(r instanceof Error&&r.message===Te)return null;throw r}return P}function Ue(){return ie()}function Ne(){return ie()}function Fe(){return window.hostProps}function ts(){P&&(P.destroy(),P=null),delete window.hostProps}const q=new Map,He=Symbol("forgeframe.component.options");function ss(s){if(!s.tag)throw new Error("Component tag is required");if(!/^[a-z][a-z0-9-]*$/.test(s.tag))throw new Error(`Invalid component tag "${s.tag}". Must start with lowercase letter and contain only lowercase letters, numbers, and hyphens.`);if(!s.url)throw new Error("Component url is required");if(typeof s.url=="string")try{new URL(s.url,window.location.origin)}catch{throw new Error(`Invalid component URL "${s.url}". Must be a valid absolute or relative URL.`)}if(q.has(s.tag))throw new Error(`Component "${s.tag}" is already registered`)}function ce(s){ss(s);const e=[];let t;if(oe(s.tag)){const r=K(s.props,s.allowedConsumerDomains);r&&(t=r.hostProps)}const n=function(r={}){const i=new ae(s,r);return e.push(i),Yt(s.tag,i),i.event.once("destroy",()=>{const o=e.indexOf(i);o!==-1&&e.splice(o,1),De(i.uid)}),i};return n.instances=e,n.isHost=()=>oe(s.tag),n.isEmbedded=()=>oe(s.tag),n.hostProps=t,n[He]=s,n.canRenderTo=async r=>r===window,q.set(s.tag,n),n}function ns(s){return Gt(s)}function rs(){return Zt()}function is(s){return s[He]}async function $e(s){await s.close()}async function le(s){const e=q.get(s);if(!e)return;const t=[...e.instances];await Promise.all(t.map(n=>n.close()))}async function Ae(){const s=Array.from(q.keys());await Promise.all(s.map(e=>le(e)))}function os(s,e){const t=Object.keys(s),n=Object.keys(e);if(t.length!==n.length)return!1;for(const r of t)if(!Object.prototype.hasOwnProperty.call(e,r)||!Object.is(s[r],e[r]))return!1;return!0}function Le(s,e){const{React:t}=e,{createElement:n,useRef:r,useEffect:i,useState:o,forwardRef:a}=t,c=a(function(g,y){const{onRendered:ke,onError:ue,onClose:Me,context:cs,className:We,style:Be,...je}=g,J=r(null),he=r(null),de=r(null),X=r(ue),[Ve,ls]=o(null);return i(()=>{X.current=ue},[ue]),i(()=>{const F=J.current;if(!F)return;const _=s(je);return he.current=_,ke&&_.event.once("rendered",ke),Me&&_.event.once("close",Me),_.event.on("error",R=>{X.current?.(R)}),_.render(F,cs).catch(R=>{ls(R),X.current?.(R)}),()=>{_.close().catch(()=>{}),he.current=null,de.current=null}},[]),i(()=>{const F=he.current;if(!F)return;const _=je,R=de.current;R&&os(R,_)||(de.current=_,F.updateProps(_).catch(us=>{X.current?.(us)}))}),i(()=>{y&&typeof y=="object"&&J.current&&(y.current=J.current)},[y]),Ve?n("div",{className:We,style:{color:"red",padding:"16px",...Be}},`Error: ${Ve.message}`):n("div",{ref:J,className:We,style:{display:"inline-block",...Be}})}),l=`ForgeFrame(${s.name||"Component"})`;return c.displayName=l,c}function as(s){return function(t){return Le(t,{React:s})}}K(void 0,void 0,{deferInit:!0});const ze={create:ce,destroy:$e,destroyByTag:le,destroyAll:Ae,isHost:Ue,isEmbedded:Ne,getHostProps:Fe,initHost:K,PROP_SERIALIZATION:O,CONTEXT:p,EVENT:m,PopupOpenError:se,VERSION:Y,isStandardSchema:D,prop:f};u.AnySchema=j,u.ArraySchema=I,u.BooleanSchema=k,u.CONTEXT=p,u.EVENT=m,u.EnumSchema=B,u.ForgeFrame=ze,u.FunctionSchema=M,u.LiteralSchema=W,u.NumberSchema=z,u.ObjectSchema=x,u.PROP_SERIALIZATION=O,u.PopupOpenError=se,u.PropSchema=w,u.StringSchema=L,u.VERSION=Y,u.create=ce,u.createReactComponent=Le,u.default=ze,u.destroy=$e,u.destroyAll=Ae,u.destroyByTag=le,u.getHostProps=Fe,u.initHost=K,u.isEmbedded=Ne,u.isHost=Ue,u.isStandardSchema=D,u.prop=f,u.withReactComponent=as,Object.defineProperties(u,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
5
+ `,(t.head??t.documentElement).appendChild(s)}function sn(t){const{doc:e,dimensions:n,uid:s,tag:r}=t,i=e.createElement("div");return i.id=`forgeframe-container-${s}`,i.setAttribute("data-forgeframe-tag",r),Object.assign(i.style,{display:"inline-block",position:"relative",width:I(n.width),height:I(n.height),overflow:"hidden"}),i}function rn(t){const{doc:e,dimensions:n,cspNonce:s}=t;nn(e,s);const r=e.createElement("div");Object.assign(r.style,{display:"flex",alignItems:"center",justifyContent:"center",width:I(n.width),height:I(n.height),backgroundColor:"#f5f5f5",position:"absolute",top:"0",left:"0",zIndex:"100"});const i=e.createElement("div");return Object.assign(i.style,{width:"40px",height:"40px",border:"3px solid #e0e0e0",borderTopColor:"#3498db",borderRadius:"50%",animation:"forgeframe-spin 1s linear infinite"}),r.appendChild(i),r}function on(t,e=200){return new Promise(n=>{t.style.opacity="0",t.style.transition=`opacity ${e}ms ease-in`,t.offsetHeight,t.style.opacity="1",setTimeout(n,e)})}function an(t,e=200){return new Promise(n=>{t.style.transition=`opacity ${e}ms ease-out`,t.style.opacity="0",setTimeout(n,e)})}async function cn(t,e,n){e&&(await an(e,150),e.remove()),n.style.display="",n.style.visibility="visible",n.style.opacity="0",await on(n,150)}class ln{constructor(e,n,s,r,i){this.options=e,this.uid=n,this.getProps=s,this.resolveDimensions=r,this.callbacks=i,this.context=this.options.defaultContext}context;iframe=null;container=null;prerenderElement=null;ownedContainer=null;resolveContainer(e){if(!e)throw new Error("Container is required for rendering");if(typeof e=="string"){const n=document.querySelector(e);if(!n)throw new Error(`Container "${e}" not found`);return n}return e}async prerender(e,n){if(!this.container)return;const s=this.container;this.ownedContainer=null;const r=this.getProps(),i=this.options.prerenderTemplate??rn,o=this.options.containerTemplate??sn,a=this.resolveDimensions(),c=r.cspNonce;if(this.context===d.IFRAME){const f=n();this.iframe=e(f),Le(this.iframe)}const l={uid:this.uid,tag:this.options.tag,context:this.context,dimensions:a,props:r,doc:document,container:s,frame:this.iframe,prerenderFrame:null,close:()=>this.callbacks.close(),focus:()=>this.callbacks.focus(),cspNonce:c};this.prerenderElement=i(l);const p={uid:this.uid,tag:this.options.tag,context:this.context,dimensions:a,props:r,doc:document,container:s,frame:this.iframe,prerenderFrame:this.prerenderElement,close:()=>this.callbacks.close(),focus:()=>this.callbacks.focus(),cspNonce:c},y=o(p);if(y){if(y!==s){const f=!y.parentNode;s.appendChild(y),f&&(this.ownedContainer=y)}this.container=y}this.prerenderElement&&!this.prerenderElement.parentNode&&this.container.appendChild(this.prerenderElement),this.iframe&&!this.iframe.parentNode&&this.container.appendChild(this.iframe)}createIframeElement(e){const n=this.resolveDimensions(),s=this.getProps(),r=typeof this.options.attributes=="function"?this.options.attributes(s):this.options.attributes??{},i=typeof this.options.style=="function"?this.options.style(s):this.options.style??{};return Wt({name:e,dimensions:n,attributes:r,style:i})}open(e){const n=e.buildUrl(e.baseUrl),s=e.buildBodyParams(),r=s.toString().length>0;if(this.context===d.IFRAME){if(!this.iframe)throw new Error("Iframe not created during prerender");return r?e.submitBodyForm(this.iframe.name,n,s):this.iframe.src=n,this.iframe.contentWindow}const i=e.buildWindowName(),o=Xt({url:r?"about:blank":n,name:i,dimensions:this.resolveDimensions()});r&&e.submitBodyForm(i,n,s);const a=en(o,()=>{e.onPopupClose()});return e.registerCleanup(a),o}async swapPrerenderContentIfNeeded(){this.context===d.IFRAME&&this.iframe&&this.container&&(await cn(this.container,this.prerenderElement,this.iframe),this.prerenderElement=null)}submitBodyForm(e,n,s){const r=this.container?.ownerDocument??document,i=r.body??r.documentElement;if(!i)throw new Error("Document root is unavailable for bodyParam form submission");const o=r.createElement("form");o.method="POST",o.action=n,o.target=e,o.style.display="none";for(const[a,c]of s.entries()){const l=r.createElement("input");l.type="hidden",l.name=a,l.value=c,o.appendChild(l)}i.appendChild(o);try{o.submit()}finally{o.remove()}}focus(e){this.context===d.IFRAME&&this.iframe?Yt(this.iframe):this.context===d.POPUP&&e&&Zt(e)}resize(e,n){this.context===d.IFRAME&&this.iframe?Bt(this.iframe,e):this.context===d.POPUP&&n&&tn(n,e)}show(){this.context===d.IFRAME&&this.iframe&&Vt(this.iframe)}hide(){this.context===d.IFRAME&&this.iframe&&Le(this.iframe)}destroy(e){this.iframe&&(jt(this.iframe),this.iframe=null),this.context===d.POPUP&&e&&Gt(e),this.prerenderElement&&(this.prerenderElement.remove(),this.prerenderElement=null),this.ownedContainer&&(this.ownedContainer.remove(),this.ownedContainer=null),this.container=null}}const he="forgeframe:";function de(t){return he+JSON.stringify(t)}function un(t){if(typeof t!="string"||!t.startsWith(he))return null;try{const e=t.slice(he.length),n=JSON.parse(e);return!n.id||!n.type||!n.name||!n.source?null:n}catch{return null}}function ke(t,e,n,s){return{id:t,type:z.REQUEST,name:e,data:n,source:s}}function hn(t,e,n,s){return{id:t,type:z.RESPONSE,name:"response",data:e,source:n,error:s?{message:s.message,stack:s.stack}:void 0}}function dn(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function fn(t){if(!t.includes("*"))return null;const e=t.split("*").map(n=>dn(n)).join(".*");return new RegExp(`^${e}$`)}function pn(t,e){return t.global||t.sticky?new RegExp(t.source,t.flags.replace(/[gy]/g,"")).test(e):t.test(e)}function mn(t,e,n){return e!==t.targetWin?!1:t.expectedOrigin==="*"?!0:n===t.expectedOrigin}function gn(t,e){if(t==="*")return"*";if(t==="/")return e;try{return new URL(t,e).origin}catch{return t}}class We{constructor(e,n=window,s=window.location.origin,r){this.uid=e,this.win=n,this.domain=s,this.allowedOrigins.add(s),r&&this.addTrustedDomain(r),this.setupListener()}pending=new Map;handlers=new Map;listener=null;destroyed=!1;allowedOrigins=new Set;allowedOriginPatterns=[];wildcardPatternRegistry=new Map;sourceUidRegistry=new WeakMap;addTrustedDomain(e){if(Array.isArray(e))for(const n of e)this.addTrustedDomain(n);else if(e instanceof RegExp)this.allowedOriginPatterns.push(e);else{const n=fn(e);n?this.wildcardPatternRegistry.has(e)||(this.wildcardPatternRegistry.set(e,n),this.allowedOriginPatterns.push(n)):this.allowedOrigins.add(e)}}removeTrustedDomain(e){if(Array.isArray(e))for(const n of e)this.removeTrustedDomain(n);else if(e instanceof RegExp)this.allowedOriginPatterns=this.allowedOriginPatterns.filter(n=>n!==e);else{const n=this.wildcardPatternRegistry.get(e);n&&(this.allowedOriginPatterns=this.allowedOriginPatterns.filter(s=>s!==n),this.wildcardPatternRegistry.delete(e)),this.allowedOrigins.delete(e)}}isOriginTrusted(e){if(this.allowedOrigins.has(e))return!0;for(const n of this.allowedOriginPatterns)if(pn(n,e))return!0;return!1}resolveVerifiedSource(e,n,s){const r=e,i=this.sourceUidRegistry.get(r);if(i)return{uid:i,domain:n};const o=s&&typeof s.uid=="string"&&s.uid.length>0?s.uid:j();return this.sourceUidRegistry.set(r,o),{uid:o,domain:n}}async send(e,n,s,r,i=1e4){if(this.destroyed)throw new Error("Messenger has been destroyed");const o=j(),a=ke(o,s,r,{uid:this.uid,domain:this.domain}),c=Re(),l=setTimeout(()=>{this.pending.delete(o),c.reject(new Error(`Message "${s}" timed out after ${i}ms`))},i);this.pending.set(o,{deferred:c,timeout:l,targetWin:e,expectedOrigin:gn(n,this.domain)});try{e.postMessage(de(a),n)}catch(p){throw this.pending.delete(o),clearTimeout(l),p}return c.promise}post(e,n,s,r){if(this.destroyed)throw new Error("Messenger has been destroyed");const i=j(),o=ke(i,s,r,{uid:this.uid,domain:this.domain});e.postMessage(de(o),n)}on(e,n){return this.handlers.set(e,n),()=>this.handlers.delete(e)}setupListener(){this.listener=e=>{if(e.source===this.win||!this.isOriginTrusted(e.origin))return;const n=un(e.data);if(!n)return;const s=e.source;!s||typeof s.postMessage!="function"||this.handleMessage(n,s,e.origin)},this.win.addEventListener("message",this.listener)}async handleMessage(e,n,s){if(e.type===z.RESPONSE){const r=this.pending.get(e.id);if(r){if(!mn(r,n,s))return;if(this.pending.delete(e.id),clearTimeout(r.timeout),e.error){const i=new Error(e.error.message);i.stack=e.error.stack,r.deferred.reject(i)}else r.deferred.resolve(e.data)}return}if(e.type===z.REQUEST){const r=this.handlers.get(e.name);if(!r)return;let i,o;try{const c=this.resolveVerifiedSource(n,s,e.source);i=await r(e.data,c)}catch(c){o=c instanceof Error?c:new Error(String(c))}const a=hn(e.id,i,{uid:this.uid,domain:this.domain},o);try{n.postMessage(de(a),s)}catch{}}}destroy(){if(!this.destroyed){this.destroyed=!0,this.listener&&(this.win.removeEventListener("message",this.listener),this.listener=null);for(const e of this.pending.values())clearTimeout(e.timeout),e.deferred.reject(new Error("Messenger destroyed"));this.pending.clear(),this.handlers.clear()}}isDestroyed(){return this.destroyed}}const yn=["init","close","resize","show","hide","onError","updateProps","export"],je=32*1024;function wn(t){const e=Rn(t);return`${k}${e}`}function Be(t){if(!t||!t.startsWith(k))return null;const e=t.slice(k.length);return Cn(e)}function S(t){return typeof t=="object"&&t!==null}function _n(t){return S(t)}function Pn(t){return S(t)&&yn.every(e=>typeof t[e]=="string"&&t[e].length>0)}function En(t){if(!S(t)||typeof t.tag!="string"||t.tag.length===0||typeof t.url!="string"||t.url.length===0||t.props!==void 0&&!S(t.props)||t.defaultContext!==void 0&&t.defaultContext!==d.IFRAME&&t.defaultContext!==d.POPUP)return!1;if(t.dimensions!==void 0){if(!S(t.dimensions))return!1;const{width:e,height:n}=t.dimensions;if(e!==void 0&&typeof e!="string"&&typeof e!="number"||n!==void 0&&typeof n!="string"&&typeof n!="number")return!1}return!0}function bn(t){return S(t)?Object.values(t).every(e=>En(e)):!1}function On(t){return!(!S(t)||typeof t.uid!="string"||t.uid.length===0||typeof t.tag!="string"||t.tag.length===0||typeof t.version!="string"||t.version.length===0||t.version!==W||t.context!==d.IFRAME&&t.context!==d.POPUP||typeof t.consumerDomain!="string"||t.consumerDomain.length===0||!_n(t.props)||!Pn(t.exports)||t.children!==void 0&&!bn(t.children))}function fe(t=window){try{return t.name.startsWith(k)}catch{return!1}}function pe(t,e=window){return Be(e.name)?.tag===t}function Rn(t){try{const e=JSON.stringify(t),n=btoa(encodeURIComponent(e)),s=new Blob([n]).size;if(s>je)throw new Error(`Payload size (${Math.round(s/1024)}KB) exceeds maximum allowed size (${je/1024}KB). Consider reducing the amount of data passed via props.`);return n}catch(e){throw e instanceof Error&&e.message.includes("Payload size")?e:new Error(`Failed to encode payload: ${e}`)}}function Cn(t){try{const e=decodeURIComponent(atob(t)),n=JSON.parse(e);return On(n)?n:null}catch{return null}}function Sn(t){return{uid:t.uid,tag:t.tag,version:W,context:t.context,consumerDomain:t.consumerDomain,props:t.props,exports:t.exports,children:t.children}}function Dn(t=window){return Be(t.name)}class In{constructor(e,n,s,r){this.uid=e,this.options=n,this.resolveUrl=s,this.resolveUrlOrigin=r;const i=this.buildTrustedDomains();this.messenger=new We(this.uid,window,B(),i),this.bridge=new ae(this.messenger)}messenger;bridge;hostWindow=null;openedHostDomain=null;dynamicUrlTrustedOrigin=null;initPromise=null;hostInitialized=!1;buildTrustedDomains(){const e=[],n=this.resolveUrlOrigin(this.resolveUrl());if(n&&(e.push(n),this.dynamicUrlTrustedOrigin=n),this.options.domain&&(typeof this.options.domain=="string"?e.push(this.options.domain):Array.isArray(this.options.domain)?e.push(...this.options.domain):this.options.domain instanceof RegExp&&e.push(this.options.domain)),e.length!==0)return e.length===1?e[0]:e}isExplicitDomainTrust(e){return this.options.domain?T(this.options.domain,e):!1}syncTrustedDomainForUrl(e){const n=this.resolveUrlOrigin(e);if(!n)return;const s=this.dynamicUrlTrustedOrigin;s&&s!==n&&!this.isExplicitDomainTrust(s)&&this.messenger.removeTrustedDomain(s),this.messenger.addTrustedDomain(n),this.dynamicUrlTrustedOrigin=n}getHostDomain(){return this.openedHostDomain?this.openedHostDomain:this.resolveUrlOrigin(this.resolveUrl())??"*"}isHostConnected(){return!!(this.hostWindow&&!oe(this.hostWindow))}serializePropsForHost(e,n,s){this.bridge.startBatch();const r=s?.finishBatch??!0;try{const i=At(e,n,this.bridge);return r&&this.bridge.finishBatch(),i}catch(i){throw this.bridge.finishBatch(!0),i}}async sendPropsUpdateToHost(e,n){if(!this.hostWindow||oe(this.hostWindow))return;const s=this.getHostDomain(),r=Ie(e,n,s,Ce(this.hostWindow)),i=this.serializePropsForHost(r,n,{finishBatch:!1});try{await this.messenger.send(this.hostWindow,s,h.PROPS,i),this.bridge.finishBatch()}catch(o){throw this.bridge.finishBatch(!0),o}}buildWindowName(e){const n=e.hostDomain??this.getHostDomain(),s=Ie(e.props,e.propDefinitions,n,!1),r=this.serializePropsForHost(s,e.propDefinitions),i=Sn({uid:this.uid,tag:e.tag,context:e.context,consumerDomain:B(),props:r,exports:e.exports,children:e.children});return wn(i)}async waitForHost(e,n,s){if(this.hostInitialized)return;const r=Re();this.initPromise=r;try{await ht(r.promise,e,`Host component "${n}" (uid: ${this.uid}) did not initialize within ${e}ms. Check that the host page loads correctly and calls the initialization code.`)}catch(i){throw s(i),i}finally{this.initPromise===r&&(this.initPromise=null)}}setupMessageHandlers(e){this.messenger.on(h.INIT,()=>(this.hostInitialized=!0,this.initPromise&&this.initPromise.resolve(),e.onInit&&queueMicrotask(()=>{Promise.resolve(e.onInit?.()).catch(n=>{e.onError(n)})}),{success:!0})),this.messenger.on(h.CLOSE,async()=>(await e.onClose(),{success:!0})),this.messenger.on(h.RESIZE,async n=>(await e.onResize(n),{success:!0})),this.messenger.on(h.FOCUS,async()=>(await e.onFocus(),{success:!0})),this.messenger.on(h.SHOW,async()=>(await e.onShow(),{success:!0})),this.messenger.on(h.HIDE,async()=>(await e.onHide(),{success:!0})),this.messenger.on(h.ERROR,async n=>{const s=new Error(n.message);return s.stack=n.stack,e.onError(s),{success:!0}}),this.messenger.on(h.EXPORT,async n=>(e.onExport(n),{success:!0})),this.messenger.on(h.CONSUMER_EXPORT,async n=>(e.onConsumerExport(n),{success:!0})),this.messenger.on(h.GET_SIBLINGS,async n=>e.onGetSiblings(n))}destroy(){this.messenger.destroy(),this.bridge.destroy()}}class me{event;state={};exports;consumerExports;_uid;get uid(){return this._uid}options;cleanup;transport;renderer;propsPipeline;rendered=!1;destroyed=!1;closing=!1;get props(){return this.propsPipeline?this.propsPipeline.props:{}}set props(e){this.propsPipeline&&(this.propsPipeline.props=e)}get inputProps(){return this.propsPipeline?this.propsPipeline.inputProps:{}}set inputProps(e){this.propsPipeline&&(this.propsPipeline.inputProps=e)}get pendingPropsUpdate(){return this.propsPipeline?this.propsPipeline.pendingPropsUpdate:null}set pendingPropsUpdate(e){this.propsPipeline&&(this.propsPipeline.pendingPropsUpdate=e)}get context(){return this.renderer?this.renderer.context:this.options.defaultContext}set context(e){this.renderer&&(this.renderer.context=e)}get hostWindow(){return this.transport?this.transport.hostWindow:null}set hostWindow(e){this.transport&&(this.transport.hostWindow=e)}get openedHostDomain(){return this.transport?this.transport.openedHostDomain:null}set openedHostDomain(e){this.transport&&(this.transport.openedHostDomain=e)}get dynamicUrlTrustedOrigin(){return this.transport?this.transport.dynamicUrlTrustedOrigin:null}set dynamicUrlTrustedOrigin(e){this.transport&&(this.transport.dynamicUrlTrustedOrigin=e)}get iframe(){return this.renderer?this.renderer.iframe:null}set iframe(e){this.renderer&&(this.renderer.iframe=e)}get container(){return this.renderer?this.renderer.container:null}set container(e){this.renderer&&(this.renderer.container=e)}get initPromise(){return this.transport?this.transport.initPromise:null}set initPromise(e){this.transport&&(this.transport.initPromise=e)}get hostInitialized(){return this.transport?this.transport.hostInitialized:!1}set hostInitialized(e){this.transport&&(this.transport.hostInitialized=e)}get messenger(){if(!this.transport)throw new Error("Consumer transport is not initialized");return this.transport.messenger}get bridge(){if(!this.transport)throw new Error("Consumer transport is not initialized");return this.transport.bridge}constructor(e,n={}){this._uid=lt(),this.options=this.normalizeOptions(e),this.event=new Oe,this.cleanup=new ut,this.renderer=new ln(this.options,this.uid,()=>this.props,()=>this.resolveDimensions(),{close:()=>this.close(),focus:()=>this.focus()}),this.propsPipeline=new kt(this.options,{...n},s=>this.createPropContext(s)),this.transport=new In(this.uid,this.options,()=>this.resolveUrl(),s=>this.resolveUrlOrigin(s)),this.setupMessageHandlers(),this.setupCleanup()}async render(e,n){if(this.destroyed)throw new Error("Component has been destroyed");if(this.rendered)throw new Error("Component has already been rendered");this.context=n??this.options.defaultContext,this.checkEligibility(),H(this.props,this.options.props),this.options.validate?.({props:this.props}),this.container=this.resolveContainer(e),this.event.emit(g.PRERENDER),this.callPropCallback("onPrerender"),await this.prerender(),this.event.emit(g.PRERENDERED),this.callPropCallback("onPrerendered"),this.event.emit(g.RENDER),this.callPropCallback("onRender");try{await this.open(),await this.waitForHost(),this.context===d.IFRAME&&this.iframe&&await this.renderer.swapPrerenderContentIfNeeded()}catch(s){throw await this.destroy().catch(()=>{}),s}this.rendered=!0,this.event.emit(g.RENDERED),this.callPropCallback("onRendered"),this.event.emit(g.DISPLAY),this.callPropCallback("onDisplay")}async renderTo(e,n,s){if(e!==window)throw new Error("Cross-window renderTo is not supported; pass the current window");return this.render(n,s)}async close(){if(!(this.destroyed||this.closing)){this.closing=!0;try{this.event.emit(g.CLOSE),this.callPropCallback("onClose"),await this.destroy()}finally{this.closing=!1}}}async focus(){this.renderer.focus(this.hostWindow),this.event.emit(g.FOCUS),this.callPropCallback("onFocus")}async resize(e){this.renderer.resize(e,this.hostWindow),this.event.emit(g.RESIZE,e),this.callPropCallback("onResize",e)}async show(){this.renderer.show()}async hide(){this.renderer.hide()}async updateProps(e){return this.applyPropsUpdate(e)}async applyPropsUpdate(e){const n={resolveUrl:s=>this.resolveUrl(s),resolveUrlOrigin:s=>this.resolveUrlOrigin(s),assertStableRenderedOrigin:s=>this.assertStableRenderedOrigin(s),isRendered:()=>this.rendered,syncTrustedDomainForUrl:s=>this.syncTrustedDomainForUrl(s),shouldSendPropsToHost:()=>this.transport.isHostConnected(),sendPropsUpdateToHost:s=>this.sendPropsUpdateToHost(s),emitPropsUpdated:()=>this.emitPropsUpdated()};await this.propsPipeline.updateProps(e,n)}assertStableRenderedOrigin(e){if(this.rendered&&this.openedHostDomain&&e&&e!==this.openedHostDomain)throw new Error(`Cannot change component URL origin after render (from "${this.openedHostDomain}" to "${e}")`)}async sendPropsUpdateToHost(e){await this.transport.sendPropsUpdateToHost(e,this.options.props)}emitPropsUpdated(){this.event.emit(g.PROPS,this.props),this.callPropCallback("onProps",this.props)}clone(){const e=new me(this.options,this.props);return e.inputProps={...this.inputProps},e}isEligible(){return this.options.eligible?this.options.eligible({props:this.props}).eligible:!0}normalizeOptions(e){return{...e,props:e.props??{},defaultContext:e.defaultContext??d.IFRAME,dimensions:e.dimensions??{width:"100%",height:"100%"},timeout:e.timeout??1e4,children:e.children}}resolveUrl(e=this.props){return typeof this.options.url=="function"?this.options.url(e):this.options.url}resolveDimensions(){return typeof this.options.dimensions=="function"?this.options.dimensions(this.props):this.options.dimensions}resolveUrlOrigin(e){try{return new URL(e,window.location.origin).origin}catch{return null}}isExplicitDomainTrust(e){return this.transport.isExplicitDomainTrust(e)}syncTrustedDomainForUrl(e){const n=this.resolveUrlOrigin(e);n&&this.isExplicitDomainTrust(n),this.transport.syncTrustedDomainForUrl(e)}createPropContext(e=this.props){return{props:e,state:this.state,close:()=>this.close(),focus:()=>this.focus(),onError:n=>this.handleError(n),container:this.container,uid:this.uid,tag:this.options.tag}}resolveContainer(e){return this.renderer.resolveContainer(e)}checkEligibility(){if(!this.options.eligible)return;const e=this.options.eligible({props:this.props});if(!e.eligible)throw new Error(`Component not eligible: ${e.reason??"Unknown reason"}`)}async prerender(){await this.renderer.prerender(e=>this.createIframeElement(e),()=>this.buildWindowName())}createIframeElement(e){return this.renderer.createIframeElement(e)}async open(){const e=this.resolveUrl();this.syncTrustedDomainForUrl(e),this.openedHostDomain=this.resolveUrlOrigin(e),this.hostWindow=this.renderer.open({baseUrl:e,buildUrl:n=>this.buildUrl(n),buildBodyParams:()=>this.buildBodyParams(),buildWindowName:()=>this.buildWindowName(),submitBodyForm:(n,s,r)=>this.submitBodyForm(n,s,r),onPopupClose:()=>{this.close()},registerCleanup:n=>{this.cleanup.register(n)}}),this.hostWindow&&Et(this.uid,this.hostWindow)}buildUrl(e=this.resolveUrl()){const s=St(this.props,this.options.props).toString();if(!s)return e;const r=e.includes("?")?"&":"?";return`${e}${r}${s}`}buildBodyParams(){return Dt(this.props,this.options.props)}submitBodyForm(e,n,s){this.renderer.submitBodyForm(e,n,s)}buildWindowName(){return this.transport.buildWindowName({tag:this.options.tag,context:this.context,props:this.props,propDefinitions:this.options.props,hostDomain:this.getHostDomain(),children:this.buildNestedHostRefs(),exports:this.createConsumerExports()})}buildNestedHostRefs(){if(!this.options.children)return;const e=this.options.children({props:this.props}),n={};for(const[s,r]of Object.entries(e)){const i=Ln(r);if(!i)throw new Error(`Nested component "${s}" is missing component metadata`);if(typeof i.url!="string")throw new Error(`Nested component "${s}" must use a static string URL. Function URLs are not supported in children.`);n[s]={tag:i.tag,url:i.url,props:i.props,dimensions:typeof i.dimensions=="function"?void 0:i.dimensions,defaultContext:i.defaultContext}}return Object.keys(n).length>0?n:void 0}createConsumerExports(){return{init:h.INIT,close:h.CLOSE,resize:h.RESIZE,show:h.SHOW,hide:h.HIDE,onError:h.ERROR,updateProps:h.PROPS,export:h.EXPORT}}getHostDomain(){return this.transport.getHostDomain()}async waitForHost(){await this.transport.waitForHost(this.options.timeout,this.options.tag,e=>this.handleError(e))}setupMessageHandlers(){this.transport.setupMessageHandlers({onInit:()=>this.syncSameDomainPropsAfterInit(),onClose:async()=>this.close(),onResize:async e=>this.resize(e),onFocus:async()=>this.focus(),onShow:async()=>this.show(),onHide:async()=>this.hide(),onError:e=>this.handleError(e),onExport:e=>{this.exports=e},onConsumerExport:e=>{this.consumerExports=e},onGetSiblings:e=>this.getSiblingInstances(e)})}async syncSameDomainPropsAfterInit(){if(!(!this.hostWindow||!this.transport.isHostConnected())&&Ce(this.hostWindow)&&this.hasSameDomainPropDefinition())try{await this.propsPipeline.syncCurrentPropsToHost({shouldSendPropsToHost:()=>this.transport.isHostConnected(),sendPropsUpdateToHost:e=>this.sendPropsUpdateToHost(e)})}catch(e){this.handleError(e)}}hasSameDomainPropDefinition(){return Object.values(this.options.props).some(e=>!e||C(e)?!1:e.sameDomain===!0)}getSiblingInstances(e){const n=[];if(e.options?.anyConsumer){for(const s of An())s.instance.uid!==e.uid&&n.push({uid:s.instance.uid,tag:s.tag,exports:s.instance.exports});return n}for(const s of $n(e.tag))s.uid!==e.uid&&n.push({uid:s.uid,tag:e.tag,exports:s.exports});return n}setupCleanup(){this.cleanup.register(()=>{this.messenger.destroy(),this.bridge.destroy(),bt(this.uid)})}handleError(e){this.event.emit(g.ERROR,e),this.callPropCallback("onError",e)}callPropCallback(e,...n){const s=this.props[e];if(typeof s=="function")try{const r=s(...n);r&&typeof r=="object"&&"catch"in r&&typeof r.catch=="function"&&r.catch(i=>{console.error(`Error in async ${e} callback:`,i)})}catch(r){console.error(`Error in ${e} callback:`,r)}}async destroy(){this.destroyed||(this.destroyed=!0,this.initPromise&&(this.initPromise.reject(new Error(`Component "${this.options.tag}" was destroyed before initialization completed`)),this.initPromise=null),this.hostInitialized=!1,this.renderer.destroy(this.hostWindow),this.hostWindow=null,this.openedHostDomain=null,this.dynamicUrlTrustedOrigin=null,this.pendingPropsUpdate=null,await this.cleanup.cleanup(),this.event.emit(g.DESTROY),this.callPropCallback("onDestroy"),this.event.removeAllListeners())}}const $=new Map,A=new Map;function xn(t,e){const n=e;$.get(n.uid)&&Ve(n.uid);let r=A.get(t);r||(r=new Map,A.set(t,r)),r.set(n.uid,n),$.set(n.uid,{tag:t,instance:n})}function Ve(t){const e=$.get(t);if(!e)return;$.delete(t);const n=A.get(e.tag);n&&(n.delete(t),n.size===0&&A.delete(e.tag))}function vn(t){return Array.from(A.get(t)?.values()??[])}function Tn(){return Array.from($.values())}const Ye="Could not resolve consumer window",ge="Could not verify consumer origin",Un=new Set(["uid","tag","close","focus","resize","show","hide","onProps","onError","getConsumer","getConsumerDomain","export","consumer","getPeerInstances","children"]);function L(t){const e={};for(const[n,s]of Object.entries(t))Un.has(n)||(e[n]=s);return e}class Nn{constructor(e,n={},s,r=!1){this.propDefinitions=n,this.allowedConsumerDomains=s,this.deferInit=r,this.uid=e.uid,this.tag=e.tag,this.event=new Oe;let i=null,o=null;try{this.consumerWindow=this.resolveConsumerWindow(),this.consumerDomain=this.resolveConsumerDomain(e.consumerDomain),o=new We(this.uid,window,B(),this.consumerDomain),this.messenger=o,this.setupMessageHandlers(),i=new ae(this.messenger),this.bridge=i,this.hostProps=this.buildHostProps(e),this.exposeHostProps(),this.deferInit||this.flushInit()}catch(a){throw i?.destroy(),o?.destroy(),this.event.removeAllListeners(),this.propsHandlers.clear(),a}}hostProps;event;uid;tag;consumerWindow;consumerDomain;consumerDomainVerified=!1;messenger;bridge;propsHandlers=new Set;consumerProps;initError=null;destroyed=!1;initSent=!1;deferredInitFlushScheduled=!1;flushInit(){this.destroyed||this.initSent||(this.initSent=!0,this.sendInit())}scheduleDeferredInitFlush(){this.deferredInitFlushScheduled||this.destroyed||this.initSent||(this.deferredInitFlushScheduled=!0,queueMicrotask(()=>{this.deferredInitFlushScheduled=!1,this.flushInit()}))}exposeHostProps(){const e=window;try{Object.defineProperty(e,"hostProps",{configurable:!0,enumerable:!0,get:()=>(this.deferInit&&!this.initSent&&!this.destroyed&&this.scheduleDeferredInitFlush(),this.hostProps),set:n=>{n&&(this.hostProps=n)}})}catch{e.hostProps=this.hostProps}}validateConsumerDomain(){if(this.allowedConsumerDomains){if(!this.consumerDomain)throw new Error(`${ge} for component "${this.tag}"`);if(!T(this.allowedConsumerDomains,this.consumerDomain))throw new Error(`Consumer domain "${this.consumerDomain}" is not allowed for component "${this.tag}"`)}}getVerifiedConsumerOrigin(){return this.getReferrerOrigin()??this.getAccessibleConsumerOrigin()}setConsumerDomain(e,n){const s=this.consumerDomain;this.consumerDomain=e,this.consumerDomainVerified=n,!(!this.messenger||!s||s===e)&&(this.messenger.removeTrustedDomain(s),this.messenger.addTrustedDomain(e))}applyHostConfiguration(e,n){n!==void 0&&(this.allowedConsumerDomains=n),e!==void 0&&(this.propDefinitions=e,H(this.consumerProps,this.getBootstrapValidationDefinitions()),Object.assign(this.hostProps,L(this.consumerProps)),this.hostProps.consumer.props=this.consumerProps)}resolveConsumerDomain(e){const n=this.getVerifiedConsumerOrigin();if(n)return this.consumerDomainVerified=!0,this.consumerDomain=n,this.validateConsumerDomain(),n;if(this.consumerDomainVerified=!1,this.allowedConsumerDomains)throw new Error(`${ge} for component "${this.tag}"`);return e}assertAllowedConsumerDomain(e){const n=this.getVerifiedConsumerOrigin();if(n&&this.setConsumerDomain(n,!0),!this.consumerDomainVerified)throw new Error(`${ge} for component "${this.tag}"`);if(!T(e,this.consumerDomain))throw new Error(`Consumer domain "${this.consumerDomain}" is not allowed for component "${this.tag}"`)}getReferrerOrigin(){if(!document.referrer)return null;try{return new URL(document.referrer,window.location.href).origin}catch{return null}}getAccessibleConsumerOrigin(){try{return this.consumerWindow.location.origin}catch{return null}}getProps(){return this.hostProps}resolveConsumerWindow(){if(wt()){const e=yt();if(e)return e}if(_t()){const e=gt();if(e)return e}throw new Error(Ye)}buildHostProps(e){const n=Ae(e.props,this.propDefinitions,this.messenger,this.bridge,this.consumerWindow,this.consumerDomain);return H(n,this.getBootstrapValidationDefinitions()),this.consumerProps=n,{...L(n),uid:this.uid,tag:this.tag,close:()=>this.close(),focus:()=>this.focus(),resize:r=>this.resize(r),show:()=>this.show(),hide:()=>this.hide(),onProps:r=>this.onProps(r),onError:r=>this.onError(r),getConsumer:()=>this.consumerWindow,getConsumerDomain:()=>this.consumerDomain,export:r=>this.exportData(r),consumer:{props:this.consumerProps,export:r=>this.consumerExport(r)},getPeerInstances:r=>this.getPeerInstances(r),children:this.buildNestedComponents(e.children)}}getBootstrapValidationDefinitions(){if(!this.consumerDomainVerified||this.consumerDomain!==B())return this.propDefinitions;let e=!1;const n={...this.propDefinitions};for(const[s,r]of Object.entries(this.propDefinitions))!r||C(r)||!r.sameDomain||(e=!0,n[s]={...r,required:!1});return e?n:this.propDefinitions}async sendInit(){try{await this.messenger.send(this.consumerWindow,this.consumerDomain,h.INIT,{uid:this.uid,tag:this.tag})}catch(e){const n=e instanceof Error?e:new Error(String(e));this.initError=n,this.event.emit(g.ERROR,{type:"init_failed",message:`Failed to initialize host component: ${n.message}`,error:n}),console.error("Failed to send init message:",e)}}getInitError(){return this.initError}async close(){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.CLOSE,{})}async focus(){window.focus(),await this.messenger.send(this.consumerWindow,this.consumerDomain,h.FOCUS,{})}async resize(e){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.RESIZE,e)}async show(){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.SHOW,{})}async hide(){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.HIDE,{})}onProps(e){return this.propsHandlers.add(e),{cancel:()=>this.propsHandlers.delete(e)}}async onError(e){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.ERROR,{message:e.message,stack:e.stack})}async exportData(e){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.EXPORT,e)}async consumerExport(e){await this.messenger.send(this.consumerWindow,this.consumerDomain,h.CONSUMER_EXPORT,e)}async getPeerInstances(e){return await this.messenger.send(this.consumerWindow,this.consumerDomain,h.GET_SIBLINGS,{uid:this.uid,tag:this.tag,options:e})??[]}buildNestedComponents(e){if(!e)return;const n={};for(const[s,r]of Object.entries(e))try{n[s]=ye({tag:r.tag,url:r.url,props:r.props,dimensions:r.dimensions,defaultContext:r.defaultContext})}catch(i){console.warn(`Failed to create nested component "${s}":`,i)}return Object.keys(n).length>0?n:void 0}setupMessageHandlers(){this.messenger.on(h.PROPS,e=>{try{const n=this.consumerProps,s=Ae(e,this.propDefinitions,this.messenger,this.bridge,this.consumerWindow,this.consumerDomain);H(s,this.propDefinitions),this.removeStaleHostProps(n,s),this.consumerProps=s,Object.assign(this.hostProps,L(s)),this.hostProps.consumer.props=this.consumerProps;for(const r of this.propsHandlers)try{r(s)}catch(i){console.error("Error in props handler:",i)}return this.event.emit(g.PROPS,s),{success:!0}}catch(n){const s=n instanceof Error?n:new Error(String(n));throw console.error("Error deserializing props:",s),this.event.emit(g.ERROR,s),s}})}removeStaleHostProps(e,n){const s=L(e),r=L(n);for(const i of Object.keys(s))i in r||delete this.hostProps[i]}destroy(){this.destroyed||(this.destroyed=!0,this.deferredInitFlushScheduled=!1,this.messenger.destroy(),this.bridge.destroy(),this.event.removeAllListeners(),this.propsHandlers.clear())}}let P=null;function ee(t,e,n={}){if(P){try{P.applyHostConfiguration(t,e),e&&P.assertAllowedConsumerDomain(e)}catch(r){throw Fn(),r}return n.deferInit||P.flushInit(),P}if(!fe())return null;const s=Dn();if(!s)return console.error("Failed to parse ForgeFrame payload from window.name"),null;try{P=new Nn(s,t,e,n.deferInit??!1)}catch(r){if(r instanceof Error&&r.message===Ye)return null;throw r}return P}function Je(){return fe()}function qe(){return fe()}function Ke(){return window.hostProps}function Fn(){P&&(P.destroy(),P=null),delete window.hostProps}const te=new Map,Xe=Symbol("forgeframe.component.options");function Hn(t){if(!t.tag)throw new Error("Component tag is required");if(!/^[a-z][a-z0-9-]*$/.test(t.tag))throw new Error(`Invalid component tag "${t.tag}". Must start with lowercase letter and contain only lowercase letters, numbers, and hyphens.`);if(!t.url)throw new Error("Component url is required");if(typeof t.url=="string")try{new URL(t.url,window.location.origin)}catch{throw new Error(`Invalid component URL "${t.url}". Must be a valid absolute or relative URL.`)}if(te.has(t.tag))throw new Error(`Component "${t.tag}" is already registered`)}function ye(t){Hn(t);const e=[];let n;if(pe(t.tag)){const r=ee(t.props,t.allowedConsumerDomains);r&&(n=r.hostProps)}const s=function(r={}){const i=new me(t,r);return e.push(i),xn(t.tag,i),i.event.once("destroy",()=>{const o=e.indexOf(i);o!==-1&&e.splice(o,1),Ve(i.uid)}),i};return s.instances=e,s.isHost=()=>pe(t.tag),s.isEmbedded=()=>pe(t.tag),s.hostProps=n,s[Xe]=t,s.canRenderTo=async r=>r===window,te.set(t.tag,s),s}function $n(t){return vn(t)}function An(){return Tn()}function Ln(t){return t[Xe]}async function Ge(t){await t.close()}async function we(t){const e=te.get(t);if(!e)return;const n=[...e.instances];await Promise.all(n.map(s=>s.close()))}async function Ze(){const t=Array.from(te.keys());await Promise.all(t.map(e=>we(e)))}function Mn(t,e){const n=Object.keys(t),s=Object.keys(e);if(n.length!==s.length)return!1;for(const r of n)if(!Object.prototype.hasOwnProperty.call(e,r)||!Object.is(t[r],e[r]))return!1;return!0}function Qe(t,e){const{React:n}=e,{createElement:s,useRef:r,useEffect:i,useState:o,forwardRef:a}=n,c=a(function(y,f){const{onRendered:O,onError:D,onClose:_e,context:tt,className:nt,style:st,...Pe}=y,Ee=r(null),M=r(null),ne=r(null),rt=r(O),se=r(D),it=r(_e),[ot,at]=o(null);return i(()=>{rt.current=O,se.current=D,it.current=_e},[O,D,_e]),i(()=>{const E=Ee.current;if(!E)return;at(null);const w=t(Pe);M.current=w,ne.current=Pe;const re=w.event.once("rendered",()=>{rt.current?.()}),ct=w.event.once("close",()=>{it.current?.()}),be=w.event.on("error",ie=>{se.current?.(ie)});return w.render(E,tt).catch(ie=>{M.current===w&&(at(ie),se.current?.(ie))}),()=>{w.close().catch(()=>{}),re(),ct(),be(),M.current=null,ne.current=null}},[tt]),i(()=>{const E=M.current;if(!E)return;const w=Pe,re=ne.current;re&&Mn(re,w)||(ne.current=w,E.updateProps(w).catch(be=>{M.current===E&&se.current?.(be)}))}),i(()=>{const E=Ee.current;if(typeof f=="function")return f(E),()=>{f(null)};if(f&&typeof f=="object")return f.current=E,()=>{f.current=null}},[f]),ot?s("div",{className:nt,style:{color:"red",padding:"16px",...st}},`Error: ${ot.message}`):s("div",{ref:Ee,className:nt,style:{display:"inline-block",...st}})}),l=`ForgeFrame(${t.name||"Component"})`;return c.displayName=l,c}function zn(t){return function(n){return Qe(n,{React:t})}}ee(void 0,void 0,{deferInit:!0});const et={create:ye,destroy:Ge,destroyByTag:we,destroyAll:Ze,isHost:Je,isEmbedded:qe,getHostProps:Ke,initHost:ee,PROP_SERIALIZATION:x,CONTEXT:d,EVENT:g,PopupOpenError:ue,VERSION:W,isStandardSchema:C,prop:m};u.AnySchema=G,u.ArraySchema=U,u.BooleanSchema=J,u.CONTEXT=d,u.EVENT=g,u.EnumSchema=X,u.ForgeFrame=et,u.FunctionSchema=q,u.LiteralSchema=K,u.NumberSchema=Y,u.ObjectSchema=N,u.PROP_SERIALIZATION=x,u.PopupOpenError=ue,u.PropSchema=_,u.StringSchema=V,u.VERSION=W,u.create=ye,u.createReactComponent=Qe,u.default=et,u.destroy=Ge,u.destroyAll=Ze,u.destroyByTag=we,u.getHostProps=Ke,u.initHost=ee,u.isEmbedded=qe,u.isHost=Je,u.isStandardSchema=C,u.prop=m,u.withReactComponent=zn,Object.defineProperties(u,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
@@ -48,8 +48,8 @@ export declare function deserializeProps<P extends Record<string, unknown>>(seri
48
48
  * Creates a deep clone of props.
49
49
  *
50
50
  * @remarks
51
- * Functions are passed by reference, objects are deep cloned using
52
- * structuredClone, and primitives are copied directly.
51
+ * Functions are preserved by reference at any depth, objects and arrays are
52
+ * recursively cloned, and primitives are copied directly.
53
53
  *
54
54
  * @typeParam P - The props type
55
55
  * @param props - Props to clone
@@ -30,6 +30,35 @@ export interface IframeOptions {
30
30
  */
31
31
  style?: IframeStyles;
32
32
  }
33
+ /**
34
+ * Configuration for creating an iframe element before navigation.
35
+ *
36
+ * @internal
37
+ */
38
+ interface IframeElementOptions {
39
+ /**
40
+ * The name attribute for the iframe, used for targeting.
41
+ */
42
+ name: string;
43
+ /**
44
+ * The width and height dimensions for the iframe.
45
+ */
46
+ dimensions: Dimensions;
47
+ /**
48
+ * Optional additional HTML attributes to set on the iframe element.
49
+ */
50
+ attributes?: IframeAttributes;
51
+ /**
52
+ * Optional CSS styles to apply to the iframe element.
53
+ */
54
+ style?: IframeStyles;
55
+ }
56
+ /**
57
+ * Creates a configured iframe element without appending it or setting `src`.
58
+ *
59
+ * @internal
60
+ */
61
+ export declare function createIframeElement(options: IframeElementOptions): HTMLIFrameElement;
33
62
  /**
34
63
  * Creates an iframe element with the specified options and appends it to a container.
35
64
  *
@@ -42,7 +71,7 @@ export interface IframeOptions {
42
71
  * as some browsers require the iframe to be in the DOM before loading content.
43
72
  *
44
73
  * If no sandbox attribute is provided, a default secure sandbox policy is applied:
45
- * `allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox`
74
+ * `allow-scripts allow-same-origin allow-forms allow-popups`
46
75
  *
47
76
  * @param options - Configuration options for the iframe
48
77
  * @returns The created HTMLIFrameElement, already appended to the container
@@ -211,3 +240,4 @@ export declare function focusIframe(iframe: HTMLIFrameElement): void;
211
240
  * @public
212
241
  */
213
242
  export declare function getIframeContentDimensions(iframe: HTMLIFrameElement): Dimensions | null;
243
+ export {};
package/dist/types.d.ts CHANGED
@@ -209,7 +209,7 @@ export interface PropDefinition<T = unknown, P = Record<string, unknown>> {
209
209
  value?: (ctx: PropContext<P>) => T;
210
210
  /** Whether to send this prop to the host window (default: true) */
211
211
  sendToHost?: boolean;
212
- /** Only send if consumer and host are same domain */
212
+ /** Only deliver after the loaded host is verified to be same-origin */
213
213
  sameDomain?: boolean;
214
214
  /** List of trusted domains that can receive this prop */
215
215
  trustedDomains?: DomainMatcher[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forgeframe",
3
- "version": "0.0.6",
3
+ "version": "0.0.10",
4
4
  "description": "Modern cross-domain iframe component framework - a TypeScript alternative to zoid",
5
5
  "type": "module",
6
6
  "module": "./dist/forgeframe.js",