From 2ae9878738a37ac2c826569585a3d8e0c43f7807 Mon Sep 17 00:00:00 2001 From: Abhi <19635345+ph33nx@users.noreply.github.com> Date: Wed, 5 Aug 2026 21:48:11 +0530 Subject: [PATCH 1/2] fix(i18n): the chosen language never reached the service on the readings that matter `lang` is declared `in: query` on every operation that accepts it, POST included, but the client only built a query string for GET and left `lang` in the JSON body on POST. The service ignores it there SILENTLY: a 200 comes back in English, so nothing surfaced the failure in a log, an error, or the admin. That made the Branding reading-language setting and the site-locale fallback no-ops on 120 of 175 operations, including 13 of the 17 featured readings: natal chart, kundli, panchang, mangal dosha, KP chart, synastry, Guna Milan, compatibility, numerology, life path, tarot, biorhythm. The four GET heroes (horoscope, moon phase, angel number, crystals by zodiac) translated correctly and masked it. Reported by a customer on a Spanish site. Verified both directions against production before and after: the same request returns English with `lang` in the body and Spanish with `?lang=` on the URL. Tests assert on the URL and body the client actually builds, because that is the seam the bug lived in. A test checking only "was lang injected into the payload" passed throughout. Also vendors @roxyapi/ui 0.22.0, and corrects the readme, which promised a `lang` attribute on every shortcode. Only some of the long tail accept one; the featured readings drop it silently, so the site language and the Branding setting are the documented path. --- assets/js/roxy-ui.js | 74 ++++++------ bin/component-map.json | 4 +- readme.txt | 12 +- roxyapi.php | 2 +- src/Api/Client.php | 19 +++ tests/phpunit/test-post-language-query.php | 130 +++++++++++++++++++++ 6 files changed, 199 insertions(+), 42 deletions(-) create mode 100644 tests/phpunit/test-post-language-query.php diff --git a/assets/js/roxy-ui.js b/assets/js/roxy-ui.js index a75910d..3a6a75a 100644 --- a/assets/js/roxy-ui.js +++ b/assets/js/roxy-ui.js @@ -1,21 +1,21 @@ -"use strict";var RoxyUI=(()=>{var oa=Object.defineProperty;var Nt=Object.getOwnPropertyDescriptor;var Qs=Object.getOwnPropertyNames;var eo=Object.prototype.hasOwnProperty;var ro=(n,r)=>{for(var e in r)oa(n,e,{get:r[e],enumerable:!0})},ao=(n,r,e,a)=>{if(r&&typeof r=="object"||typeof r=="function")for(let t of Qs(r))!eo.call(n,t)&&t!==e&&oa(n,t,{get:()=>r[t],enumerable:!(a=Nt(r,t))||a.enumerable});return n};var to=n=>ao(oa({},"__esModule",{value:!0}),n),g=(n,r,e,a)=>{for(var t=a>1?void 0:a?Nt(r,e):r,o=n.length-1,l;o>=0;o--)(l=n[o])&&(t=(a?l(r,e,t):l(t))||t);return a&&t&&oa(r,e,t),t};var wi={};ro(wi,{ROXY_COMPONENTS:()=>ja,ROXY_UI_COMPONENTS:()=>$i,ROXY_UI_TOKENS_STYLE_ID:()=>Ka,ROXY_UI_VERSION:()=>Oa,RoxyAngelNumberCard:()=>Ye,RoxyAngelNumberLookup:()=>Ve,RoxyArudhaPadas:()=>Ze,RoxyAshtakavargaGrid:()=>Le,RoxyAspectsTable:()=>We,RoxyAstrocartographyMap:()=>Xe,RoxyBhavChalitTable:()=>Qe,RoxyBhavaBalaTable:()=>er,RoxyBiorhythmChart:()=>$e,RoxyBodygraph:()=>ke,RoxyCharaKarakas:()=>ar,RoxyChoghadiyaGrid:()=>tr,RoxyCompatibilityCard:()=>Se,RoxyCrystalCard:()=>sr,RoxyCrystalGrid:()=>Re,RoxyDashaTimeline:()=>he,RoxyData:()=>Ae,RoxyDivisionalChart:()=>Ce,RoxyDoshaCard:()=>De,RoxyDreamCard:()=>lr,RoxyDreamSearch:()=>dr,RoxyEndpointForm:()=>F,RoxyFixedStars:()=>cr,RoxyForecastDigest:()=>pr,RoxyForecastTimeline:()=>mr,RoxyGocharaTable:()=>gr,RoxyGunaMilan:()=>hr,RoxyHdConnection:()=>yr,RoxyHdPenta:()=>ur,RoxyHdTypeCard:()=>xr,RoxyHdVariables:()=>fr,RoxyHeliacalTable:()=>br,RoxyHexagram:()=>Ee,RoxyHoraTable:()=>vr,RoxyHoroscopeCard:()=>Te,RoxyKpChart:()=>Pe,RoxyKpPlanetsTable:()=>Lr,RoxyKpRulingPlanets:()=>$r,RoxyLocalSpaceCompass:()=>wr,RoxyLocationSearch:()=>V,RoxyMoonPhase:()=>Me,RoxyNakshatraCard:()=>kr,RoxyNatalChart:()=>le,RoxyNumerologyCard:()=>ze,RoxyPanchangTable:()=>Ne,RoxyPositionsTable:()=>_e,RoxyProfectionCard:()=>Sr,RoxyReferenceCard:()=>Rr,RoxyRelocationWheel:()=>Ar,RoxyShadbalaTable:()=>Cr,RoxySynastryChart:()=>Dr,RoxyTarotCard:()=>Oe,RoxyTarotCatalog:()=>Ge,RoxyTarotSpread:()=>He,RoxyTransitsTable:()=>Be,RoxyUpagrahaTable:()=>Er,RoxyVedicAspects:()=>Tr,RoxyVedicKundli:()=>de,RoxyVedicPlanetsTable:()=>Pr,RoxyWesternPlanetsTable:()=>Mr,RoxyYogaList:()=>Ie,injectRoxyTokens:()=>Fa,roxyDataScript:()=>rs,serializeRoxyData:()=>tt});var na=globalThis,ia=na.ShadowRoot&&(na.ShadyCSS===void 0||na.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,qa=Symbol(),_t=new WeakMap,Kr=class{constructor(r,e,a){if(this._$cssResult$=!0,a!==qa)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=r,this.t=e}get styleSheet(){let r=this.o,e=this.t;if(ia&&r===void 0){let a=e!==void 0&&e.length===1;a&&(r=_t.get(e)),r===void 0&&((this.o=r=new CSSStyleSheet).replaceSync(this.cssText),a&&_t.set(e,r))}return r}toString(){return this.cssText}},Ot=n=>new Kr(typeof n=="string"?n:n+"",void 0,qa),y=(n,...r)=>{let e=n.length===1?n[0]:r.reduce((a,t,o)=>a+(l=>{if(l._$cssResult$===!0)return l.cssText;if(typeof l=="number")return l;throw Error("Value passed to 'css' function must be a 'css' function result: "+l+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(t)+n[o+1],n[0]);return new Kr(e,n,qa)},Gt=(n,r)=>{if(ia)n.adoptedStyleSheets=r.map(e=>e instanceof CSSStyleSheet?e:e.styleSheet);else for(let e of r){let a=document.createElement("style"),t=na.litNonce;t!==void 0&&a.setAttribute("nonce",t),a.textContent=e.cssText,n.appendChild(a)}},Ya=ia?n=>n:n=>n instanceof CSSStyleSheet?(r=>{let e="";for(let a of r.cssRules)e+=a.cssText;return Ot(e)})(n):n;var{is:so,defineProperty:oo,getOwnPropertyDescriptor:no,getOwnPropertyNames:io,getOwnPropertySymbols:lo,getPrototypeOf:co}=Object,la=globalThis,Ht=la.trustedTypes,po=Ht?Ht.emptyScript:"",mo=la.reactiveElementPolyfillSupport,Fr=(n,r)=>n,qr={toAttribute(n,r){switch(r){case Boolean:n=n?po:null;break;case Object:case Array:n=n==null?n:JSON.stringify(n)}return n},fromAttribute(n,r){let e=n;switch(r){case Boolean:e=n!==null;break;case Number:e=n===null?null:Number(n);break;case Object:case Array:try{e=JSON.parse(n)}catch{e=null}}return e}},da=(n,r)=>!so(n,r),Bt={attribute:!0,type:String,converter:qr,reflect:!1,useDefault:!1,hasChanged:da};Symbol.metadata??=Symbol("metadata"),la.litPropertyMetadata??=new WeakMap;var pe=class extends HTMLElement{static addInitializer(r){this._$Ei(),(this.l??=[]).push(r)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(r,e=Bt){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(r)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(r,e),!e.noAccessor){let a=Symbol(),t=this.getPropertyDescriptor(r,a,e);t!==void 0&&oo(this.prototype,r,t)}}static getPropertyDescriptor(r,e,a){let{get:t,set:o}=no(this.prototype,r)??{get(){return this[e]},set(l){this[e]=l}};return{get:t,set(l){let d=t?.call(this);o?.call(this,l),this.requestUpdate(r,d,a)},configurable:!0,enumerable:!0}}static getPropertyOptions(r){return this.elementProperties.get(r)??Bt}static _$Ei(){if(this.hasOwnProperty(Fr("elementProperties")))return;let r=co(this);r.finalize(),r.l!==void 0&&(this.l=[...r.l]),this.elementProperties=new Map(r.elementProperties)}static finalize(){if(this.hasOwnProperty(Fr("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(Fr("properties"))){let e=this.properties,a=[...io(e),...lo(e)];for(let t of a)this.createProperty(t,e[t])}let r=this[Symbol.metadata];if(r!==null){let e=litPropertyMetadata.get(r);if(e!==void 0)for(let[a,t]of e)this.elementProperties.set(a,t)}this._$Eh=new Map;for(let[e,a]of this.elementProperties){let t=this._$Eu(e,a);t!==void 0&&this._$Eh.set(t,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(r){let e=[];if(Array.isArray(r)){let a=new Set(r.flat(1/0).reverse());for(let t of a)e.unshift(Ya(t))}else r!==void 0&&e.push(Ya(r));return e}static _$Eu(r,e){let a=e.attribute;return a===!1?void 0:typeof a=="string"?a:typeof r=="string"?r.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(r=>this.enableUpdating=r),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(r=>r(this))}addController(r){(this._$EO??=new Set).add(r),this.renderRoot!==void 0&&this.isConnected&&r.hostConnected?.()}removeController(r){this._$EO?.delete(r)}_$E_(){let r=new Map,e=this.constructor.elementProperties;for(let a of e.keys())this.hasOwnProperty(a)&&(r.set(a,this[a]),delete this[a]);r.size>0&&(this._$Ep=r)}createRenderRoot(){let r=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return Gt(r,this.constructor.elementStyles),r}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(r=>r.hostConnected?.())}enableUpdating(r){}disconnectedCallback(){this._$EO?.forEach(r=>r.hostDisconnected?.())}attributeChangedCallback(r,e,a){this._$AK(r,a)}_$ET(r,e){let a=this.constructor.elementProperties.get(r),t=this.constructor._$Eu(r,a);if(t!==void 0&&a.reflect===!0){let o=(a.converter?.toAttribute!==void 0?a.converter:qr).toAttribute(e,a.type);this._$Em=r,o==null?this.removeAttribute(t):this.setAttribute(t,o),this._$Em=null}}_$AK(r,e){let a=this.constructor,t=a._$Eh.get(r);if(t!==void 0&&this._$Em!==t){let o=a.getPropertyOptions(t),l=typeof o.converter=="function"?{fromAttribute:o.converter}:o.converter?.fromAttribute!==void 0?o.converter:qr;this._$Em=t;let d=l.fromAttribute(e,o.type);this[t]=d??this._$Ej?.get(t)??d,this._$Em=null}}requestUpdate(r,e,a,t=!1,o){if(r!==void 0){let l=this.constructor;if(t===!1&&(o=this[r]),a??=l.getPropertyOptions(r),!((a.hasChanged??da)(o,e)||a.useDefault&&a.reflect&&o===this._$Ej?.get(r)&&!this.hasAttribute(l._$Eu(r,a))))return;this.C(r,e,a)}this.isUpdatePending===!1&&(this._$ES=this._$EP())}C(r,e,{useDefault:a,reflect:t,wrapped:o},l){a&&!(this._$Ej??=new Map).has(r)&&(this._$Ej.set(r,l??e??this[r]),o!==!0||l!==void 0)||(this._$AL.has(r)||(this.hasUpdated||a||(e=void 0),this._$AL.set(r,e)),t===!0&&this._$Em!==r&&(this._$Eq??=new Set).add(r))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}let r=this.scheduleUpdate();return r!=null&&await r,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(let[t,o]of this._$Ep)this[t]=o;this._$Ep=void 0}let a=this.constructor.elementProperties;if(a.size>0)for(let[t,o]of a){let{wrapped:l}=o,d=this[t];l!==!0||this._$AL.has(t)||d===void 0||this.C(t,void 0,o,d)}}let r=!1,e=this._$AL;try{r=this.shouldUpdate(e),r?(this.willUpdate(e),this._$EO?.forEach(a=>a.hostUpdate?.()),this.update(e)):this._$EM()}catch(a){throw r=!1,this._$EM(),a}r&&this._$AE(e)}willUpdate(r){}_$AE(r){this._$EO?.forEach(e=>e.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(r)),this.updated(r)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(r){return!0}update(r){this._$Eq&&=this._$Eq.forEach(e=>this._$ET(e,this[e])),this._$EM()}updated(r){}firstUpdated(r){}};pe.elementStyles=[],pe.shadowRootOptions={mode:"open"},pe[Fr("elementProperties")]=new Map,pe[Fr("finalized")]=new Map,mo?.({ReactiveElement:pe}),(la.reactiveElementVersions??=[]).push("2.1.2");var Qa=globalThis,It=n=>n,ca=Qa.trustedTypes,jt=ca?ca.createPolicy("lit-html",{createHTML:n=>n}):void 0,Ut="$lit$",fe=`lit$${Math.random().toFixed(9).slice(2)}$`,Zt="?"+fe,go=`<${Zt}>`,Fe=document,Vr=()=>Fe.createComment(""),Ur=n=>n===null||typeof n!="object"&&typeof n!="function",et=Array.isArray,ho=n=>et(n)||typeof n?.[Symbol.iterator]=="function",Va=`[ -\f\r]`,Yr=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,Kt=/-->/g,Ft=/>/g,je=RegExp(`>|${Va}(?:([^\\s"'>=/]+)(${Va}*=${Va}*(?:[^ -\f\r"'\`<>=]|("|')|))|$)`,"g"),qt=/'/g,Yt=/"/g,Wt=/^(?:script|style|textarea|title)$/i,rt=n=>(r,...e)=>({_$litType$:n,strings:r,values:e}),s=rt(1),$=rt(2),Di=rt(3),qe=Symbol.for("lit-noChange"),i=Symbol.for("lit-nothing"),Vt=new WeakMap,Ke=Fe.createTreeWalker(Fe,129);function Jt(n,r){if(!et(n)||!n.hasOwnProperty("raw"))throw Error("invalid template strings array");return jt!==void 0?jt.createHTML(r):r}var yo=(n,r)=>{let e=n.length-1,a=[],t,o=r===2?"":r===3?"":"",l=Yr;for(let d=0;d"?(l=t??Yr,h=-1):p[1]===void 0?h=-2:(h=l.lastIndex-p[2].length,m=p[1],l=p[3]===void 0?je:p[3]==='"'?Yt:qt):l===Yt||l===qt?l=je:l===Kt||l===Ft?l=Yr:(l=je,t=void 0);let k=l===je&&n[d+1].startsWith("/>")?" ":"";o+=l===Yr?c+go:h>=0?(a.push(m),c.slice(0,h)+Ut+c.slice(h)+fe+k):c+fe+(h===-2?d:k)}return[Jt(n,o+(n[e]||"")+(r===2?"":r===3?"":"")),a]},Zr=class n{constructor({strings:r,_$litType$:e},a){let t;this.parts=[];let o=0,l=0,d=r.length-1,c=this.parts,[m,p]=yo(r,e);if(this.el=n.createElement(m,a),Ke.currentNode=this.el.content,e===2||e===3){let h=this.el.content.firstChild;h.replaceWith(...h.childNodes)}for(;(t=Ke.nextNode())!==null&&c.length0){t.textContent=ca?ca.emptyScript:"";for(let k=0;k2||a[0]!==""||a[1]!==""?(this._$AH=Array(a.length-1).fill(new String),this.strings=a):this._$AH=i}_$AI(r,e=this,a,t){let o=this.strings,l=!1;if(o===void 0)r=zr(this,r,e,0),l=!Ur(r)||r!==this._$AH&&r!==qe,l&&(this._$AH=r);else{let d=r,c,m;for(r=o[0],c=0;c{let a=e?.renderBefore??r,t=a._$litPart$;if(t===void 0){let o=e?.renderBefore??null;a._$litPart$=t=new Wr(r.insertBefore(Vr(),o),o,void 0,e??{})}return t._$AI(n),t};var at=globalThis,ae=class extends pe{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){let r=super.createRenderRoot();return this.renderOptions.renderBefore??=r.firstChild,r}update(r){let e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(r),this._$Do=Xt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return qe}};ae._$litElement$=!0,ae.finalized=!0,at.litElementHydrateSupport?.({LitElement:ae});var xo=at.litElementPolyfillSupport;xo?.({LitElement:ae});(at.litElementVersions??=[]).push("4.2.2");var f=n=>(r,e)=>{e!==void 0?e.addInitializer(()=>{customElements.define(n,r)}):customElements.define(n,r)};var fo={attribute:!0,type:String,converter:qr,reflect:!1,hasChanged:da},bo=(n=fo,r,e)=>{let{kind:a,metadata:t}=e,o=globalThis.litPropertyMetadata.get(t);if(o===void 0&&globalThis.litPropertyMetadata.set(t,o=new Map),a==="setter"&&((n=Object.create(n)).wrapped=!0),o.set(e.name,n),a==="accessor"){let{name:l}=e;return{set(d){let c=r.get.call(this);r.set.call(this,d),this.requestUpdate(l,c,n,!0,d)},init(d){return d!==void 0&&this.C(l,void 0,n,d),d}}}if(a==="setter"){let{name:l}=e;return function(d){let c=this[l];r.call(this,d),this.requestUpdate(l,c,n,!0,d)}}throw Error("Unsupported decorator location: "+a)};function w(n){return(r,e)=>typeof e=="object"?bo(n,r,e):((a,t,o)=>{let l=t.hasOwnProperty(o);return t.constructor.createProperty(o,a),l?Object.getOwnPropertyDescriptor(t,o):void 0})(n,r,e)}function P(n){return w({...n,state:!0,attribute:!1})}var vo=[{key:"spiritual",label:"Spiritual"},{key:"love",label:"Love"},{key:"career",label:"Career"},{key:"money",label:"Money"},{key:"twinFlame",label:"Twin flame"}];function ma(n,r,e){let a=[];if(n)for(let t of vo){let o=n[t.key];o&&a.push({label:t.label,body:o})}return r&&a.push({label:"Biblical",body:r}),e&&a.push({label:"Shadow",body:e}),a}var me=n=>n??i;var x=y`:host{font-family:var(--roxy-font-sans,system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);color:var(--roxy-fg,#0a0a0a);font-size:var(--roxy-text-base,1rem);line-height:var(--roxy-leading-normal,1.5);animation:roxy-fade-in var(--roxy-motion-duration,.2s) var(--roxy-motion-easing,cubic-bezier(.4, 0, .2, 1)) both;background:0 0;display:block;container-type:inline-size}:host([bare]){--roxy-surface:transparent;--roxy-shadow-sm:none;--roxy-shadow-md:none}*,:before,:after{box-sizing:border-box}h1,h2,h3,h4{font-family:var(--roxy-font-display,var(--roxy-font-sans,system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif))}@keyframes roxy-fade-in{0%{opacity:0;transform:translateY(2px)}to{opacity:1;transform:translateY(0)}}@media (prefers-reduced-motion:reduce){:host{animation:none}}.roxy-skeleton{background:linear-gradient(90deg, var(--roxy-border,#e4e4e7) 0%, color-mix(in srgb, var(--roxy-border,#e4e4e7) 60%, transparent) 50%, var(--roxy-border,#e4e4e7) 100%);border-radius:var(--roxy-radius-md,8px);background-size:200% 100%;animation:1.4s ease-in-out infinite roxy-shimmer}@keyframes roxy-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}@media (prefers-reduced-motion:reduce){.roxy-skeleton{animation:none}}.roxy-sr-only{clip-path:inset(50%);white-space:nowrap;border:0;width:1px;height:1px;margin:0;padding:0;position:absolute;overflow:hidden}.roxy-empty{padding:var(--roxy-space-lg,1.5rem);color:var(--roxy-muted,#71717a);text-align:center;font-size:var(--roxy-text-sm,.875rem)}.roxy-error{gap:var(--roxy-space-sm,.5rem);padding:var(--roxy-space-lg,1.5rem);background:var(--roxy-surface,#fff);border:1px solid var(--roxy-danger,#dc2626);border-radius:var(--roxy-radius-md,8px);color:var(--roxy-danger-fg,#991b1b);font-size:var(--roxy-text-sm,.875rem);justify-items:start;display:grid}.roxy-surface{background:var(--roxy-surface,#fff);color:var(--roxy-fg,#0a0a0a)}:host(:focus-within) .roxy-card{outline:2px solid var(--roxy-ring,#f59e0b66);outline-offset:2px}.roxy-attribution{margin-top:var(--roxy-space-sm,.5rem);font-size:var(--roxy-text-xs,.75rem);color:var(--roxy-muted,#71717a);text-align:right}.roxy-attribution a{color:inherit;text-decoration:none}.roxy-attribution a:hover{color:var(--roxy-accent-ink,#b45309);text-decoration:underline}.roxy-attribution a:focus-visible{outline:2px solid var(--roxy-ring,#f59e0b66);outline-offset:2px}.roxy-edit-bar{margin-bottom:var(--roxy-space-sm,.5rem);justify-content:flex-end;display:flex}.roxy-edit{padding:var(--roxy-space-xs,.25rem) var(--roxy-space-md,1rem);border:1px solid var(--roxy-border,#e4e4e7);border-radius:var(--roxy-radius-md,8px);color:var(--roxy-fg,#0a0a0a);font-family:inherit;font-size:var(--roxy-text-sm,.875rem);cursor:pointer;background:0 0}.roxy-edit:hover{border-color:var(--roxy-accent,#f59e0b);color:var(--roxy-accent-ink,#b45309)}.roxy-edit:focus-visible{outline:2px solid var(--roxy-ring,#f59e0b66);outline-offset:2px}:host{font-variant-emoji:text}`;var _r="Client-side components accept a pk_ publishable key only. Use a publishable key with an origin allowlist, or render server-side.";function ga(n){return!!n&&!n.startsWith("pk_")}function ha(n,r={}){r.warn&&console.warn(_r),n.dispatchEvent(new CustomEvent("roxy-validation-error",{detail:{reason:"possible-secret-key",message:_r},bubbles:!0,composed:!0}))}var Lo="https://roxyapi.com/api/v2",ya=class{constructor(r){this.baseUrl=Lo;this.host=r,r.addController(this)}hostDisconnected(){this.abort?.abort(),this.abort=void 0}async run(r){if(!this.submitUrl&&this.secretKeyRefused())return;this.abort?.abort();let e=new AbortController;this.abort=e,this.host.loading=!0,this.host.error=null;try{let a=this.submitUrl?await fetch(this.submitUrl,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(r),signal:e.signal}):await this.callApi(r,e.signal);if(!a.ok)throw new Error(await this.readError(a));let t=await a.json();if(e.signal.aborted)return;this.host.data=t}catch(a){if(a?.name==="AbortError")return;this.host.error=a instanceof Error?a.message:String(a)}finally{this.abort===e&&(this.abort=void 0),e.signal.aborted||(this.host.loading=!1)}}callApi(r,e){let a=new URL(`${this.baseUrl}${r.path}`);for(let[o,l]of Object.entries(r.query??{}))l!=null&&a.searchParams.set(o,String(l));let t={Accept:"application/json"};return this.publishableKey&&(t["X-API-Key"]=this.publishableKey),r.body!=null&&(t["Content-Type"]="application/json"),fetch(a,{method:r.method??"GET",headers:t,body:r.body!=null?JSON.stringify(r.body):void 0,signal:e})}secretKeyRefused(){return ga(this.publishableKey)?(this.host.error=_r,ha(this.host),!0):!1}async readError(r){try{let e=await r.json();if(e?.error)return e.error}catch{}return`Request failed (${r.status})`}};function Qt(n,r,e,a=[]){let t={...e},o=`/${n.replace(/^\//,"")}`.replace(/\{([^}]+)\}/g,(m,p)=>{let h=t[p];return delete t[p],encodeURIComponent(String(h??""))}),l=new Set(a),d={},c={};for(let[m,p]of Object.entries(t))p===void 0||p===""||(r==="GET"||l.has(m)?d[m]=p:c[m]=p);return{path:o,method:r,query:d,body:r==="POST"?c:void 0}}var es="roxy-data";function tt(n){return JSON.stringify(n).replace(//g,"\\u003e").replace(/&/g,"\\u0026").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")}function rs(n){return`