@returningai/widget-sdk 1.8.0 → 1.8.2

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.
@@ -12689,12 +12689,31 @@ function waitWithTimeout(promise, timeoutMs, timeoutMessage) {
12689
12689
  );
12690
12690
  });
12691
12691
  }
12692
- async function waitForBundleMountReadiness(mountResult, firstPaint, timeoutMs = BUNDLE_READY_TIMEOUT_MS) {
12693
- const resolvedMountResult = isPromiseLike(mountResult) ? await waitWithTimeout(
12692
+ function resolveBundleMountResult(mountResult, timeoutMs = BUNDLE_READY_TIMEOUT_MS) {
12693
+ return isPromiseLike(mountResult) ? waitWithTimeout(
12694
12694
  mountResult,
12695
12695
  timeoutMs,
12696
12696
  `Widget bundle mount did not resolve within ${timeoutMs}ms`
12697
- ) : mountResult;
12697
+ ) : Promise.resolve(mountResult);
12698
+ }
12699
+ function createBundleMountCleanup(mountResult) {
12700
+ if (typeof mountResult !== "object" || mountResult === null || !("unmount" in mountResult)) {
12701
+ return void 0;
12702
+ }
12703
+ const unmount = mountResult.unmount;
12704
+ if (typeof unmount !== "function") return void 0;
12705
+ let unmounted = false;
12706
+ return () => {
12707
+ if (unmounted) return;
12708
+ unmounted = true;
12709
+ unmount.call(mountResult);
12710
+ };
12711
+ }
12712
+ async function waitForBundleMountReadiness(mountResult, firstPaint, timeoutMs = BUNDLE_READY_TIMEOUT_MS) {
12713
+ const resolvedMountResult = await resolveBundleMountResult(
12714
+ mountResult,
12715
+ timeoutMs
12716
+ );
12698
12717
  if (!isReadyHandle(resolvedMountResult)) {
12699
12718
  await firstPaint;
12700
12719
  return "first-paint";
@@ -12706,11 +12725,51 @@ async function waitForBundleMountReadiness(mountResult, firstPaint, timeoutMs =
12706
12725
  );
12707
12726
  return "deep-ready";
12708
12727
  }
12728
+ const MAX_PRELOAD_ASSETS = 24;
12729
+ function resolveBundlePreloadAssets(bundleUrl, manifest) {
12730
+ if (manifest.version !== 1) return [];
12731
+ const normalizedBundleUrl = new URL(bundleUrl);
12732
+ const bundleDirectory = new URL("./", normalizedBundleUrl);
12733
+ const candidates = [
12734
+ ...(Array.isArray(manifest.scripts) ? manifest.scripts : []).map((value) => ({
12735
+ value,
12736
+ rel: "modulepreload",
12737
+ as: "script",
12738
+ extension: ".js"
12739
+ })),
12740
+ ...(Array.isArray(manifest.styles) ? manifest.styles : []).map((value) => ({
12741
+ value,
12742
+ rel: "preload",
12743
+ as: "style",
12744
+ extension: ".css"
12745
+ }))
12746
+ ];
12747
+ const seen = /* @__PURE__ */ new Set();
12748
+ const assets = [];
12749
+ for (const candidate of candidates) {
12750
+ if (assets.length >= MAX_PRELOAD_ASSETS) break;
12751
+ if (typeof candidate.value !== "string") continue;
12752
+ let resolved;
12753
+ try {
12754
+ resolved = new URL(candidate.value, bundleDirectory);
12755
+ } catch {
12756
+ continue;
12757
+ }
12758
+ if (resolved.origin !== bundleDirectory.origin || !resolved.pathname.startsWith(bundleDirectory.pathname) || !resolved.pathname.endsWith(candidate.extension) || seen.has(resolved.href)) {
12759
+ continue;
12760
+ }
12761
+ seen.add(resolved.href);
12762
+ assets.push({ url: resolved.href, rel: candidate.rel, as: candidate.as });
12763
+ }
12764
+ return assets;
12765
+ }
12709
12766
  function createBundleRuntimeWarmer({
12710
12767
  preloadScript: preloadScript2,
12768
+ preloadBundleAssets: preloadBundleAssets2,
12711
12769
  baseUrl
12712
12770
  }) {
12713
12771
  const preloadPromises = /* @__PURE__ */ new Map();
12772
+ const deepPreloadPromises = /* @__PURE__ */ new Map();
12714
12773
  return function warmBundleRuntime2(globalName, bundleUrl) {
12715
12774
  const normalizedUrl = normalizeBundleUrl(bundleUrl, baseUrl());
12716
12775
  if (preloadPromises.has(normalizedUrl)) return;
@@ -12718,6 +12777,12 @@ function createBundleRuntimeWarmer({
12718
12777
  preloadPromises.delete(normalizedUrl);
12719
12778
  });
12720
12779
  preloadPromises.set(normalizedUrl, preloadPromise);
12780
+ if (preloadBundleAssets2 && !deepPreloadPromises.has(normalizedUrl)) {
12781
+ const deepPreloadPromise = preloadBundleAssets2(normalizedUrl).catch(() => {
12782
+ deepPreloadPromises.delete(normalizedUrl);
12783
+ });
12784
+ deepPreloadPromises.set(normalizedUrl, deepPreloadPromise);
12785
+ }
12721
12786
  };
12722
12787
  }
12723
12788
  function isWidgetBundleRuntime(value) {
@@ -12797,6 +12862,35 @@ function preloadScript(url) {
12797
12862
  document.head.appendChild(link);
12798
12863
  });
12799
12864
  }
12865
+ const preloadedBundleAssets = /* @__PURE__ */ new Set();
12866
+ function appendBundleAssetPreload(asset) {
12867
+ const cacheKey = `${asset.rel}:${asset.url}`;
12868
+ if (preloadedBundleAssets.has(cacheKey)) return;
12869
+ const link = document.createElement("link");
12870
+ link.rel = asset.rel;
12871
+ link.as = asset.as;
12872
+ link.href = asset.url;
12873
+ link.crossOrigin = "anonymous";
12874
+ link.onload = () => void 0;
12875
+ link.onerror = () => {
12876
+ preloadedBundleAssets.delete(cacheKey);
12877
+ link.remove();
12878
+ };
12879
+ preloadedBundleAssets.add(cacheKey);
12880
+ document.head.appendChild(link);
12881
+ }
12882
+ async function preloadBundleAssets(bundleUrl) {
12883
+ const manifestUrl = new URL("./preload-manifest.json", bundleUrl);
12884
+ const response = await fetch(manifestUrl, {
12885
+ credentials: "omit",
12886
+ headers: { Accept: "application/json" }
12887
+ });
12888
+ if (!response.ok) throw new Error(`Bundle preload manifest returned ${response.status}`);
12889
+ const manifest = await response.json();
12890
+ for (const asset of resolveBundlePreloadAssets(bundleUrl, manifest)) {
12891
+ appendBundleAssetPreload(asset);
12892
+ }
12893
+ }
12800
12894
  const loadBrowserBundleRuntime = createBundleRuntimeLoader({
12801
12895
  loadScript: appendScript,
12802
12896
  readGlobal: (globalName) => window[globalName],
@@ -12804,6 +12898,7 @@ const loadBrowserBundleRuntime = createBundleRuntimeLoader({
12804
12898
  });
12805
12899
  const warmBrowserBundleRuntime = createBundleRuntimeWarmer({
12806
12900
  preloadScript,
12901
+ preloadBundleAssets,
12807
12902
  baseUrl: () => document.baseURI
12808
12903
  });
12809
12904
  function warmBundleRuntime(globalName, bundleUrl) {
@@ -12812,6 +12907,20 @@ function warmBundleRuntime(globalName, bundleUrl) {
12812
12907
  function getOrLoadBundleRuntime(globalName, bundleUrl) {
12813
12908
  return loadBrowserBundleRuntime(globalName, bundleUrl);
12814
12909
  }
12910
+ const BUNDLE_AUTH_TOKEN_CHANGE_EVENT = "authtoken-change";
12911
+ function syncBundleAccessToken(config, state, runtime = window) {
12912
+ if (!config.bundleUrl || !state.accessToken) return false;
12913
+ runtime.guest_token = state.accessToken;
12914
+ runtime.dispatchEvent(
12915
+ new CustomEvent(BUNDLE_AUTH_TOKEN_CHANGE_EVENT, {
12916
+ detail: {
12917
+ token: state.accessToken,
12918
+ widgetId: config.widgetId
12919
+ }
12920
+ })
12921
+ );
12922
+ return true;
12923
+ }
12815
12924
  function assertCallbackName(callbackName) {
12816
12925
  if (!callbackName || typeof callbackName !== "string") {
12817
12926
  throw new TypeError("ReturningAI callback name must be a non-empty string");
@@ -13045,6 +13154,100 @@ function dispatchHostCallback(input) {
13045
13154
  }
13046
13155
  );
13047
13156
  }
13157
+ const SUPPORTED_WIDGET_LANGUAGES = [
13158
+ "en",
13159
+ "de",
13160
+ "es",
13161
+ "fr",
13162
+ "it",
13163
+ "pt",
13164
+ "pl",
13165
+ "da",
13166
+ "nl",
13167
+ "ru",
13168
+ "chs",
13169
+ "el",
13170
+ "ko",
13171
+ "cht",
13172
+ "th",
13173
+ "ja",
13174
+ "id",
13175
+ "vt",
13176
+ "ms",
13177
+ "hi",
13178
+ "fil",
13179
+ "ta",
13180
+ "tr",
13181
+ "ar",
13182
+ "mn",
13183
+ "sw"
13184
+ ];
13185
+ const supportedWidgetLanguages = new Set(SUPPORTED_WIDGET_LANGUAGES);
13186
+ const warnedUnsupportedLanguages = /* @__PURE__ */ new Set();
13187
+ const LANGUAGE_TAG_PATTERN = /^[a-z]{2,8}(?:-[a-z0-9]{1,8})*$/;
13188
+ function resolveWidgetLanguage(language) {
13189
+ const normalized = language == null ? void 0 : language.trim().toLowerCase().replace(/_/g, "-");
13190
+ if (!normalized || !LANGUAGE_TAG_PATTERN.test(normalized)) return void 0;
13191
+ const segments = normalized.split("-");
13192
+ const primaryLanguage = segments[0];
13193
+ if (primaryLanguage === "zh") {
13194
+ if (segments.includes("hant")) {
13195
+ return "cht";
13196
+ }
13197
+ if (segments.includes("hans")) {
13198
+ return "chs";
13199
+ }
13200
+ if (segments.includes("tw") || segments.includes("hk") || segments.includes("mo")) {
13201
+ return "cht";
13202
+ }
13203
+ if (segments.includes("cn") || segments.includes("sg")) {
13204
+ return "chs";
13205
+ }
13206
+ return void 0;
13207
+ }
13208
+ if (primaryLanguage === "vi" || primaryLanguage === "vt") {
13209
+ return "vt";
13210
+ }
13211
+ return supportedWidgetLanguages.has(primaryLanguage) ? primaryLanguage : void 0;
13212
+ }
13213
+ function warnUnsupportedWidgetLanguage(language) {
13214
+ const value = language.trim();
13215
+ if (!value) return;
13216
+ const warningKey = value.toLowerCase();
13217
+ if (warnedUnsupportedLanguages.has(warningKey)) return;
13218
+ warnedUnsupportedLanguages.add(warningKey);
13219
+ console.warn(
13220
+ `[rai-widget] Unsupported language "${value.slice(
13221
+ 0,
13222
+ 80
13223
+ )}". Falling back to the browser language. Supported language codes: ${SUPPORTED_WIDGET_LANGUAGES.join(
13224
+ ", "
13225
+ )}.`
13226
+ );
13227
+ }
13228
+ const PERCENTAGE_HEIGHT = /^(\d+(?:\.\d+)?)%$/;
13229
+ function parsePercentageHeight(value) {
13230
+ const match = value.trim().match(PERCENTAGE_HEIGHT);
13231
+ if (!match) return null;
13232
+ const percentage = Number(match[1]);
13233
+ return Number.isFinite(percentage) && percentage > 0 ? percentage : null;
13234
+ }
13235
+ function resolvePercentageViewportHeight(value, viewportHeight) {
13236
+ const percentage = parsePercentageHeight(value);
13237
+ return percentage === null ? 0 : viewportHeight * percentage / 100;
13238
+ }
13239
+ function resolveCollapsedRestoredHeight({
13240
+ originalHeight,
13241
+ restoredHeight,
13242
+ resolvedHeight,
13243
+ isRendered
13244
+ }) {
13245
+ if (!isRendered || Number.isFinite(restoredHeight) && restoredHeight > 0) {
13246
+ return null;
13247
+ }
13248
+ const percentage = parsePercentageHeight(originalHeight);
13249
+ return percentage === null ? `${resolvedHeight}px` : `${percentage}vh`;
13250
+ }
13048
13251
  function debounce(fn, wait) {
13049
13252
  let timer = null;
13050
13253
  return {
@@ -13199,6 +13402,54 @@ function setupMessageListener(config, state, _shadow, iframe, onRefreshScheduled
13199
13402
  heightSetter.cancel();
13200
13403
  };
13201
13404
  }
13405
+ async function resolveStartupAuthentication(authentication, loadErrorSettings) {
13406
+ const authenticated = await authentication;
13407
+ if (authenticated) {
13408
+ void loadErrorSettings({ skipCache: true }).catch(() => {
13409
+ });
13410
+ return true;
13411
+ }
13412
+ try {
13413
+ await loadErrorSettings();
13414
+ } catch {
13415
+ }
13416
+ return false;
13417
+ }
13418
+ function resolveWidgetPreconnectOrigins(config, baseUrl) {
13419
+ const values = [
13420
+ config.apiUrl,
13421
+ config.v2ApiUrl,
13422
+ config.authUrl,
13423
+ config.bundleUrl,
13424
+ config.widgetUrl,
13425
+ config.widgetDomain
13426
+ ];
13427
+ const origins = [];
13428
+ for (const value of values) {
13429
+ if (!value) continue;
13430
+ try {
13431
+ const url = new URL(value, baseUrl);
13432
+ if ((url.protocol === "http:" || url.protocol === "https:") && !origins.includes(url.origin)) {
13433
+ origins.push(url.origin);
13434
+ }
13435
+ } catch {
13436
+ }
13437
+ }
13438
+ return origins;
13439
+ }
13440
+ function ensureWidgetPreconnects(origins, targetDocument) {
13441
+ const documentTarget = document;
13442
+ for (const origin of origins) {
13443
+ const id = `rai-widget-preconnect-${origin.replace(/[^a-z0-9]+/gi, "-")}`;
13444
+ if (documentTarget.getElementById(id)) continue;
13445
+ const link = documentTarget.createElement("link");
13446
+ link.id = id;
13447
+ link.rel = "preconnect";
13448
+ link.href = origin;
13449
+ link.crossOrigin = "anonymous";
13450
+ documentTarget.head.appendChild(link);
13451
+ }
13452
+ }
13202
13453
  const widgetCSS = ':host{display:block;position:relative;width:100%;height:100%}.rai-loader{position:absolute;top:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.75rem;width:100%;height:100%;background:var(--rai-loading-background, var(--background-5, var(--rai-loader-bg, #ffffff)));border-radius:8px;z-index:10;transition:opacity .3s ease-out;font-family:var(--rai-loader-font, "Roboto", system-ui, -apple-system, sans-serif)}.rai-loader.fade-out{opacity:0;pointer-events:none}.rai-loader-pending-settings{visibility:hidden}.rai-loader-text{margin:.5rem 0 0;font-family:var(--rai-loading-text-font, var(--rai-loader-font, "Roboto", system-ui, -apple-system, sans-serif));font-size:var(--rai-loading-text-size, 1.125rem);line-height:1.75rem;font-weight:var(--rai-loading-text-weight, 400);font-style:var(--rai-loading-text-style, normal);text-decoration:var(--rai-loading-text-decoration, none);letter-spacing:normal;color:var(--rai-loading-text-color, var(--accent-1, var(--rai-accent, #000000)));text-align:center}@media (min-width: 768px){.rai-loader-text{font-size:var(--rai-loading-text-size, 1.5rem);line-height:2rem}}.rai-error{display:none;position:absolute;top:0;left:0;width:100%;height:100%;align-items:center;justify-content:center;flex-direction:column;gap:12px;background:var(--rai-error-bg, #1a1a1a);border-radius:8px;padding:24px;box-sizing:border-box;text-align:center;color:var(--rai-error-text, #9ca3af);font-family:system-ui,-apple-system,sans-serif;z-index:10}.rai-error.visible{display:flex}iframe{display:block;border:none;opacity:0;transition:opacity .3s ease-in}iframe.loaded{opacity:1}.rai-lottie-loader{width:100px;height:100px}.rai-lottie-loader svg{width:100%!important;height:100%!important}.rai-lottie-spinner{width:32px;height:32px;margin:34px auto;border:3px solid var(--rai-text4, #6b7280);border-top-color:var(--rai-accent, #000000);border-radius:50%;animation:rai-spin .7s linear infinite}@keyframes rai-spin{to{transform:rotate(360deg)}}.rai-sdk-loader{position:relative;width:75px;height:100px}.rai-sdk-loader__bar{position:absolute;bottom:0;width:10px;height:50%;background:var(--rai-accent, #000000);transform-origin:center bottom;box-shadow:1px 1px #0003}.rai-sdk-loader__bar:nth-child(1){left:0;transform:scaleY(.2);animation:rai-sdk-barUp1 4s infinite}.rai-sdk-loader__bar:nth-child(2){left:15px;transform:scaleY(.4);animation:rai-sdk-barUp2 4s infinite}.rai-sdk-loader__bar:nth-child(3){left:30px;transform:scaleY(.6);animation:rai-sdk-barUp3 4s infinite}.rai-sdk-loader__bar:nth-child(4){left:45px;transform:scaleY(.8);animation:rai-sdk-barUp4 4s infinite}.rai-sdk-loader__bar:nth-child(5){left:60px;transform:scale(1);animation:rai-sdk-barUp5 4s infinite}.rai-sdk-loader__ball{position:absolute;bottom:10px;left:0;width:10px;height:10px;background:var(--rai-accent, #000000);border-radius:50%;animation:rai-sdk-ball 4s infinite}@keyframes rai-sdk-ball{0%{transform:translate(0)}5%{transform:translate(8px,-14px)}10%{transform:translate(15px,-10px)}17%{transform:translate(23px,-24px)}20%{transform:translate(30px,-20px)}27%{transform:translate(38px,-34px)}30%{transform:translate(45px,-30px)}37%{transform:translate(53px,-44px)}40%{transform:translate(60px,-40px)}50%{transform:translate(60px)}57%{transform:translate(53px,-14px)}60%{transform:translate(45px,-10px)}67%{transform:translate(37px,-24px)}70%{transform:translate(30px,-20px)}77%{transform:translate(22px,-34px)}80%{transform:translate(15px,-30px)}87%{transform:translate(7px,-44px)}90%{transform:translateY(-40px)}to{transform:translate(0)}}@keyframes rai-sdk-barUp1{0%{transform:scaleY(.2)}40%{transform:scaleY(.2)}50%{transform:scale(1)}90%{transform:scale(1)}to{transform:scaleY(.2)}}@keyframes rai-sdk-barUp2{0%{transform:scaleY(.4)}40%{transform:scaleY(.4)}50%{transform:scaleY(.8)}90%{transform:scaleY(.8)}to{transform:scaleY(.4)}}@keyframes rai-sdk-barUp3{0%{transform:scaleY(.6)}to{transform:scaleY(.6)}}@keyframes rai-sdk-barUp4{0%{transform:scaleY(.8)}40%{transform:scaleY(.8)}50%{transform:scaleY(.4)}90%{transform:scaleY(.4)}to{transform:scaleY(.8)}}@keyframes rai-sdk-barUp5{0%{transform:scale(1)}40%{transform:scale(1)}50%{transform:scaleY(.2)}90%{transform:scaleY(.2)}to{transform:scale(1)}}#loading-square{width:75px;aspect-ratio:1;display:flex;color:var(--rai-accent, #000000);background:linear-gradient(currentColor 0 0) right / 51% 100%,linear-gradient(currentColor 0 0) bottom / 100% 51%;background-repeat:no-repeat;animation:l16-0 2s infinite linear .25s}#loading-square>div{width:50%;height:50%;background:currentColor;animation:l16-1 .5s infinite linear}@keyframes l16-0{0%,12.49%{transform:rotate(0)}12.5%,37.49%{transform:rotate(90deg)}37.5%,62.49%{transform:rotate(180deg)}62.5%,87.49%{transform:rotate(270deg)}87.5%,to{transform:rotate(360deg)}}@keyframes l16-1{0%{transform:perspective(80px) rotate3d(-1,-1,0,0)}80%,to{transform:perspective(80px) rotate3d(-1,-1,0,-180deg)}}#loading-circle{width:75px;aspect-ratio:1;display:grid;grid:50%/50%;color:var(--rai-accent, #000000);border-radius:50%;--_g: no-repeat linear-gradient(currentColor 0 0);background:var(--_g),var(--_g),var(--_g);background-size:50.1% 50.1%;animation:l9-0 1.5s infinite steps(1) alternate,l9-0-0 3s infinite steps(1) alternate}#loading-circle>div{background:var(--rai-text4, #6b7280);border-top-left-radius:100px;transform:perspective(150px) rotateY(0) rotateX(0);transform-origin:bottom right;animation:l9-1 1.5s infinite linear alternate}@keyframes l9-0{0%{background-position:0 100%,100% 100%,100% 0}33%{background-position:100% 100%,100% 100%,100% 0}66%{background-position:100% 0,100% 0,100% 0}}@keyframes l9-0-0{0%{transform:scaleX(1) rotate(0)}50%{transform:scaleX(-1) rotate(-90deg)}}@keyframes l9-1{16.5%{transform:perspective(150px) rotateX(-90deg) rotateY(0) rotateX(0);filter:grayscale(.8)}33%{transform:perspective(150px) rotateX(-180deg) rotateY(0) rotateX(0)}66%{transform:perspective(150px) rotateX(-180deg) rotateY(-180deg) rotateX(0)}to{transform:perspective(150px) rotateX(-180deg) rotateY(-180deg) rotateX(-180deg);filter:grayscale(.8)}}.rai-custom-error{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10}.tiptap strong.tw-font-bold,.tiptap b.tw-font-bold{font-weight:700}.tiptap em.tw-font-italic,.tiptap i.tw-font-italic{font-style:italic}.tiptap a.tiptap-rich-text-link{color:#3b82f6;text-decoration:underline;position:relative;display:inline-block;width:fit-content}.tiptap a.tiptap-rich-text-link:hover{color:#3b82f6cc;text-decoration:none}.tiptap a.tiptap-rich-text-link:not([title=""]):before{content:attr(title);position:absolute;top:-2rem;left:50%;transform:translate(-50%);white-space:nowrap;border-radius:.25rem;background-color:#000;padding:.25rem .5rem;color:#fff;opacity:0;transition:opacity .2s;pointer-events:none}.tiptap a.tiptap-rich-text-link:not([title=""]):hover:before{opacity:1}.tiptap p[style*="text-align: left"]{text-align:left}.tiptap p[style*="text-align: center"]{text-align:center}.tiptap p[style*="text-align: right"]{text-align:right}.tiptap p[style*="text-align: justify"]{text-align:justify}.tiptap u{text-decoration:underline}.tiptap.ProseMirror{background-color:transparent;height:fit-content!important;word-wrap:break-word;white-space:pre-wrap;white-space:break-spaces;-webkit-font-variant-ligatures:none;font-variant-ligatures:none;font-feature-settings:"liga" 0;padding:0;width:100%;overflow-y:auto}.tiptap{line-height:1.6;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif}.tiptap p{margin:.5em 0}.tiptap p:first-child{margin-top:0}.tiptap p:last-child{margin-bottom:0}.tiptap img{max-width:100%;height:auto;display:block}.tiptap p[style*="text-align: left"] img{margin-left:0;margin-right:auto}.tiptap p[style*="text-align: center"] img{margin-left:auto;margin-right:auto}.tiptap p[style*="text-align: right"] img{margin-left:auto;margin-right:0}.rai-retry-btn{padding:8px 20px;border:none;border-radius:6px;background:var(--rai-accent, #000000);color:var(--rai-error-bg, #ffffff);font-size:14px;font-family:system-ui,-apple-system,sans-serif;cursor:pointer}.rai-retry-btn:hover{opacity:.85}';
13203
13454
  const DEFINED_ATTRS = /* @__PURE__ */ new Set([
13204
13455
  "community-id",
@@ -13219,6 +13470,7 @@ const DEFINED_ATTRS = /* @__PURE__ */ new Set([
13219
13470
  "max-retries",
13220
13471
  "retry-delay",
13221
13472
  "height-debounce",
13473
+ "language",
13222
13474
  "locale",
13223
13475
  "custom-data",
13224
13476
  "retry-label",
@@ -13479,6 +13731,13 @@ function readConfig(el2, existingId) {
13479
13731
  return void 0;
13480
13732
  }
13481
13733
  })();
13734
+ const explicitLanguage = get("language").trim();
13735
+ const legacyLocale = get("locale").trim();
13736
+ const requestedLanguage = explicitLanguage || legacyLocale || void 0;
13737
+ const language = resolveWidgetLanguage(requestedLanguage);
13738
+ if (requestedLanguage && !language) {
13739
+ warnUnsupportedWidgetLanguage(requestedLanguage);
13740
+ }
13482
13741
  return {
13483
13742
  communityId,
13484
13743
  channelId,
@@ -13504,7 +13763,12 @@ function readConfig(el2, existingId) {
13504
13763
  // #2
13505
13764
  heightDebounce: num("height-debounce", 100),
13506
13765
  // #4
13507
- locale: get("locale") || void 0,
13766
+ // `language` is the canonical forced widget locale. Keep `locale` as a
13767
+ // backwards-compatible alias only when it supplied the selected value.
13768
+ // Unsupported explicit values are omitted so the widget uses its existing
13769
+ // browser-language fallback.
13770
+ language,
13771
+ locale: !explicitLanguage && legacyLocale ? language : void 0,
13508
13772
  // #5
13509
13773
  customData,
13510
13774
  // #8
@@ -13566,6 +13830,8 @@ class BaseWidget extends HTMLElement {
13566
13830
  __publicField(this, "config");
13567
13831
  __publicField(this, "state", createInitialState());
13568
13832
  __publicField(this, "loaderEl", null);
13833
+ __publicField(this, "loaderHeightRestore", null);
13834
+ __publicField(this, "loaderHeightObserver", null);
13569
13835
  __publicField(this, "errorEl", null);
13570
13836
  __publicField(this, "msgEl", null);
13571
13837
  __publicField(this, "cleanupListener");
@@ -13577,14 +13843,21 @@ class BaseWidget extends HTMLElement {
13577
13843
  __publicField(this, "hasAttemptedInit", false);
13578
13844
  __publicField(this, "initGeneration", 0);
13579
13845
  __publicField(this, "lottieInstances", []);
13580
- __publicField(this, "renderedLoaderAnimationKey", null);
13581
13846
  __publicField(this, "callbackRegistry", new WidgetCallbackRegistry());
13582
13847
  __publicField(this, "bannerNode", null);
13583
13848
  __publicField(this, "releaseAutoThemeDisableLease");
13849
+ __publicField(this, "bundleUnmount");
13584
13850
  this.shadow = this.attachShadow({ mode: "closed" });
13585
13851
  }
13586
13852
  static get observedAttributes() {
13587
- return ["embed-token", "data-embed-token"];
13853
+ return [
13854
+ "embed-token",
13855
+ "data-embed-token",
13856
+ "language",
13857
+ "data-language",
13858
+ "locale",
13859
+ "data-locale"
13860
+ ];
13588
13861
  }
13589
13862
  registerCallback(callbackName, callback) {
13590
13863
  this.callbackRegistry.registerCallback(callbackName, callback);
@@ -13596,6 +13869,9 @@ class BaseWidget extends HTMLElement {
13596
13869
  this.config = readConfig(this, void 0);
13597
13870
  this.identitySignature = identitySignatureForConfig(this.config);
13598
13871
  this.setupIdentityAttributeObserver();
13872
+ ensureWidgetPreconnects(
13873
+ resolveWidgetPreconnectOrigins(this.config, document.baseURI)
13874
+ );
13599
13875
  const style = document.createElement("style");
13600
13876
  style.textContent = widgetCSS;
13601
13877
  this.shadow.appendChild(style);
@@ -13631,13 +13907,23 @@ class BaseWidget extends HTMLElement {
13631
13907
  (_c = this.identityAttributeObserver) == null ? void 0 : _c.disconnect();
13632
13908
  this.teardownMountedWidget();
13633
13909
  this.clearLottieInstances();
13910
+ this.restoreLoaderHeight();
13634
13911
  this.removeBanner();
13635
13912
  clearState(this.state);
13636
13913
  }
13637
13914
  attributeChangedCallback(name, oldValue, newValue) {
13638
13915
  if (oldValue === newValue) return;
13639
- if (name !== "embed-token" && name !== "data-embed-token") return;
13640
- this.handleIdentityConfigChange();
13916
+ if (name === "embed-token" || name === "data-embed-token") {
13917
+ this.handleIdentityConfigChange();
13918
+ return;
13919
+ }
13920
+ if (this.isConnected && this.config) {
13921
+ if (this.hasAttemptedInit) {
13922
+ void this.reload();
13923
+ } else {
13924
+ this.config = readConfig(this, this.config.communityId);
13925
+ }
13926
+ }
13641
13927
  }
13642
13928
  setupIdentityAttributeObserver() {
13643
13929
  var _a;
@@ -13793,22 +14079,6 @@ class BaseWidget extends HTMLElement {
13793
14079
  textEl.hidden = !loadingText.enabled;
13794
14080
  }
13795
14081
  }
13796
- getLoadingAnimationRenderKey() {
13797
- var _a, _b, _c;
13798
- const animation = this.state.loadingAnimation;
13799
- const theme = this.config.theme === "dark" ? "dark" : "light";
13800
- const custom = (animation == null ? void 0 : animation.type) === "custom" ? ((_a = animation.custom) == null ? void 0 : _a[theme]) || ((_b = animation.custom) == null ? void 0 : _b.light) || ((_c = animation.custom) == null ? void 0 : _c.dark) : void 0;
13801
- return JSON.stringify({
13802
- theme,
13803
- type: (animation == null ? void 0 : animation.type) ?? null,
13804
- preset: (animation == null ? void 0 : animation.preset) ?? null,
13805
- custom: custom ? {
13806
- type: custom.type ?? null,
13807
- html: custom.html ?? null,
13808
- lottie: custom.lottie ?? null
13809
- } : null
13810
- });
13811
- }
13812
14082
  renderShell() {
13813
14083
  this.loaderEl = document.createElement("div");
13814
14084
  this.loaderEl.className = "rai-loader";
@@ -13820,6 +14090,7 @@ class BaseWidget extends HTMLElement {
13820
14090
  textEl.textContent = this.config.loadingText;
13821
14091
  this.loaderEl.appendChild(textEl);
13822
14092
  this.shadow.appendChild(this.loaderEl);
14093
+ this.freezeIframeLoaderHeight();
13823
14094
  this.applyLoadingSettings();
13824
14095
  this.fetchAndRenderLoader();
13825
14096
  this.errorEl = document.createElement("div");
@@ -13840,11 +14111,9 @@ class BaseWidget extends HTMLElement {
13840
14111
  * Loads the community loading animation + theme palette from cache or API
13841
14112
  * and renders the configured animation above the loading text.
13842
14113
  *
13843
- * Stale-while-revalidate:
13844
- * - Cache hit → apply palette & render animation synchronously, fire
13845
- * background refresh.
13846
- * - Cache miss → retain the initial shell; await network; apply palette +
13847
- * render the resolved animation or fallback.
14114
+ * Cached settings are applied synchronously. On a first visit, settings load
14115
+ * alongside authentication so the generic loader stays hidden until the
14116
+ * configured animation is known. This request never blocks widget launch.
13848
14117
  */
13849
14118
  async fetchAndRenderLoader() {
13850
14119
  var _a;
@@ -13853,26 +14122,14 @@ class BaseWidget extends HTMLElement {
13853
14122
  applyErrorSettingsToState(this.state, cached);
13854
14123
  this.applyLoadingSettings();
13855
14124
  this.renderLoaderAnimation();
13856
- void fetchErrorSettings(this.config, this.state, { skipCache: true }).then(() => {
13857
- var _a2;
13858
- if (!this.loaderEl) return;
13859
- const theme2 = this.config.theme === "dark" ? "dark" : "light";
13860
- const palette2 = (_a2 = this.state.themePalette) == null ? void 0 : _a2[theme2];
13861
- if (palette2) this.applyPalette(palette2);
13862
- if (this.state.font) this.applyFont(this.state.font);
13863
- this.applyLoadingSettings();
13864
- if (this.renderedLoaderAnimationKey !== this.getLoadingAnimationRenderKey()) {
13865
- this.renderLoaderAnimation();
13866
- }
13867
- }).catch(() => {
13868
- });
13869
14125
  return;
13870
14126
  }
13871
14127
  try {
13872
14128
  await fetchErrorSettings(this.config, this.state);
13873
14129
  } catch {
13874
14130
  }
13875
- if (!this.loaderEl) return;
14131
+ const loaderEl = this.loaderEl;
14132
+ if (!loaderEl) return;
13876
14133
  if (!this.config.themeExplicit && (this.state.defaultColorSchema === "light" || this.state.defaultColorSchema === "dark") && this.state.defaultColorSchema !== this.config.theme) {
13877
14134
  this.config.theme = this.state.defaultColorSchema;
13878
14135
  }
@@ -13882,7 +14139,7 @@ class BaseWidget extends HTMLElement {
13882
14139
  if (this.state.font) this.applyFont(this.state.font);
13883
14140
  this.applyLoadingSettings();
13884
14141
  this.renderLoaderAnimation();
13885
- this.loaderEl.classList.remove("rai-loader-pending-settings");
14142
+ loaderEl.classList.remove("rai-loader-pending-settings");
13886
14143
  }
13887
14144
  /**
13888
14145
  * Append the loading animation above the text. Removes any previous
@@ -13891,7 +14148,6 @@ class BaseWidget extends HTMLElement {
13891
14148
  */
13892
14149
  renderLoaderAnimation() {
13893
14150
  if (!this.loaderEl) return;
13894
- this.renderedLoaderAnimationKey = this.getLoadingAnimationRenderKey();
13895
14151
  this.clearLottieInstances();
13896
14152
  const existing = this.loaderEl.querySelector(".rai-loader-anim");
13897
14153
  if (existing) existing.remove();
@@ -13978,9 +14234,82 @@ class BaseWidget extends HTMLElement {
13978
14234
  setTimeout(() => {
13979
14235
  loader.remove();
13980
14236
  lottieInstances.forEach((instance) => instance.destroy());
14237
+ this.restoreLoaderHeight();
13981
14238
  }, 300);
13982
14239
  this.loaderEl = null;
13983
14240
  }
14241
+ /**
14242
+ * Keep percentage-based iframe embeds at their resolved startup height while
14243
+ * the SDK loader is visible. The child iframe may resize during auth/data
14244
+ * loading; without this pin the loader's 100% centering moves with the host.
14245
+ */
14246
+ freezeIframeLoaderHeight() {
14247
+ var _a;
14248
+ if (this.config.bundleUrl || this.loaderHeightRestore) return;
14249
+ const measuredHeight = this.getBoundingClientRect().height;
14250
+ const isRendered = this.getClientRects().length > 0;
14251
+ const hasPercentageHeight = parsePercentageHeight(this.style.height) !== null;
14252
+ const percentageHeight = resolvePercentageViewportHeight(
14253
+ this.style.height,
14254
+ window.innerHeight
14255
+ );
14256
+ if (measuredHeight <= 0 && hasPercentageHeight && !isRendered) {
14257
+ this.deferIframeLoaderHeightFreeze();
14258
+ return;
14259
+ }
14260
+ const resolvedHeight = measuredHeight > 0 ? measuredHeight : percentageHeight;
14261
+ if (!Number.isFinite(resolvedHeight) || resolvedHeight <= 0) return;
14262
+ (_a = this.loaderHeightObserver) == null ? void 0 : _a.disconnect();
14263
+ this.loaderHeightObserver = null;
14264
+ this.loaderHeightRestore = {
14265
+ value: this.style.getPropertyValue("height"),
14266
+ priority: this.style.getPropertyPriority("height"),
14267
+ resolvedHeight
14268
+ };
14269
+ this.style.setProperty("height", `${resolvedHeight}px`);
14270
+ }
14271
+ deferIframeLoaderHeightFreeze() {
14272
+ if (this.loaderHeightObserver || typeof ResizeObserver === "undefined") {
14273
+ return;
14274
+ }
14275
+ this.loaderHeightObserver = new ResizeObserver(() => {
14276
+ var _a, _b;
14277
+ if (!this.isConnected || !this.loaderEl || this.config.bundleUrl) {
14278
+ (_a = this.loaderHeightObserver) == null ? void 0 : _a.disconnect();
14279
+ this.loaderHeightObserver = null;
14280
+ return;
14281
+ }
14282
+ if (this.getClientRects().length === 0) return;
14283
+ (_b = this.loaderHeightObserver) == null ? void 0 : _b.disconnect();
14284
+ this.loaderHeightObserver = null;
14285
+ this.freezeIframeLoaderHeight();
14286
+ });
14287
+ this.loaderHeightObserver.observe(this);
14288
+ }
14289
+ restoreLoaderHeight() {
14290
+ var _a;
14291
+ (_a = this.loaderHeightObserver) == null ? void 0 : _a.disconnect();
14292
+ this.loaderHeightObserver = null;
14293
+ if (!this.loaderHeightRestore) return;
14294
+ const { value, priority, resolvedHeight } = this.loaderHeightRestore;
14295
+ this.loaderHeightRestore = null;
14296
+ if (value) {
14297
+ this.style.setProperty("height", value, priority);
14298
+ } else {
14299
+ this.style.removeProperty("height");
14300
+ }
14301
+ const restoredHeight = this.getBoundingClientRect().height;
14302
+ const isRendered = this.isConnected && this.getClientRects().length > 0;
14303
+ const collapsedFallback = resolveCollapsedRestoredHeight({
14304
+ originalHeight: value,
14305
+ restoredHeight,
14306
+ resolvedHeight,
14307
+ isRendered
14308
+ });
14309
+ if (collapsedFallback) {
14310
+ this.style.setProperty("height", collapsedFallback, priority);
14311
+ }
14312
+ }
13984
14313
  /**
13985
14314
  * Resolve after a legacy bundle's first rendered child has reached a paint.
13986
14315
  * This remains the fallback for bundles that do not expose a deep-ready
@@ -14193,14 +14522,10 @@ class BaseWidget extends HTMLElement {
14193
14522
  this.config.bundleUrl
14194
14523
  );
14195
14524
  }
14196
- const errorSettingsPromise = fetchErrorSettings(this.config, this.state);
14197
- const finishStartup = async (authentication) => {
14198
- const [authenticated] = await Promise.all([
14199
- authentication,
14200
- errorSettingsPromise
14201
- ]);
14202
- return authenticated;
14203
- };
14525
+ const finishStartup = (authentication) => resolveStartupAuthentication(
14526
+ authentication,
14527
+ (options) => fetchErrorSettings(this.config, this.state, options)
14528
+ );
14204
14529
  const launchWidget = () => {
14205
14530
  var _a;
14206
14531
  if (!this.isCurrentInit(initId)) return;
@@ -14300,6 +14625,13 @@ class BaseWidget extends HTMLElement {
14300
14625
  }
14301
14626
  teardownMountedWidget() {
14302
14627
  var _a;
14628
+ const bundleUnmount = this.bundleUnmount;
14629
+ this.bundleUnmount = void 0;
14630
+ try {
14631
+ bundleUnmount == null ? void 0 : bundleUnmount();
14632
+ } catch (error) {
14633
+ console.error("[rai-widget] Bundle unmount failed:", error);
14634
+ }
14303
14635
  (_a = this.releaseAutoThemeDisableLease) == null ? void 0 : _a.call(this);
14304
14636
  this.releaseAutoThemeDisableLease = void 0;
14305
14637
  if (this.cleanupListener) {
@@ -14375,6 +14707,7 @@ class BaseWidget extends HTMLElement {
14375
14707
  async mountWidget(initId) {
14376
14708
  var _a;
14377
14709
  let container = null;
14710
+ let cleanupBundleMount;
14378
14711
  try {
14379
14712
  this.teardownMountedWidget();
14380
14713
  const autoHeight = this.config.height.trim().toLowerCase() === "auto";
@@ -14382,7 +14715,7 @@ class BaseWidget extends HTMLElement {
14382
14715
  this.releaseAutoThemeDisableLease = acquireAutoThemeDisableLease();
14383
14716
  }
14384
14717
  const { bundleApiUrl, colorMode } = this.prepareBundleRuntimeEnvironment();
14385
- window.guest_token = this.state.accessToken;
14718
+ syncBundleAccessToken(this.config, this.state);
14386
14719
  const globalName = WIDGET_GLOBALS[this.config.widgetType];
14387
14720
  const widgetGlobal = await getOrLoadBundleRuntime(
14388
14721
  globalName,
@@ -14437,6 +14770,7 @@ class BaseWidget extends HTMLElement {
14437
14770
  // injected by SSR for the explicit `/open-widget` route.
14438
14771
  isOpenWidget: !this.state.accessToken,
14439
14772
  defaultColorSchema: this.config.widgetType === "custom" && !this.config.themeExplicit ? null : colorMode,
14773
+ language: this.config.language,
14440
14774
  // Bundle loading screens are rendered beneath an instance-scoped
14441
14775
  // provider. Do not put these values on window: pages can mount several
14442
14776
  // widget types at once.
@@ -14459,8 +14793,20 @@ class BaseWidget extends HTMLElement {
14459
14793
  transport: "bundle"
14460
14794
  })
14461
14795
  });
14462
- await waitForBundleMountReadiness(mountResult, firstPaint);
14796
+ const resolvedMountResult = await resolveBundleMountResult(mountResult);
14797
+ cleanupBundleMount = createBundleMountCleanup(resolvedMountResult);
14463
14798
  if (!this.isCurrentInit(initId) || !container.isConnected) {
14799
+ cleanupBundleMount == null ? void 0 : cleanupBundleMount();
14800
+ container.remove();
14801
+ return;
14802
+ }
14803
+ this.bundleUnmount = cleanupBundleMount;
14804
+ await waitForBundleMountReadiness(resolvedMountResult, firstPaint);
14805
+ if (!this.isCurrentInit(initId) || !container.isConnected) {
14806
+ cleanupBundleMount == null ? void 0 : cleanupBundleMount();
14807
+ if (this.bundleUnmount === cleanupBundleMount) {
14808
+ this.bundleUnmount = void 0;
14809
+ }
14464
14810
  container.remove();
14465
14811
  return;
14466
14812
  }
@@ -14468,11 +14814,16 @@ class BaseWidget extends HTMLElement {
14468
14814
  this.hideLoader();
14469
14815
  this.emit("rai-mounted");
14470
14816
  } catch (err) {
14817
+ cleanupBundleMount == null ? void 0 : cleanupBundleMount();
14818
+ if (this.bundleUnmount === cleanupBundleMount) {
14819
+ this.bundleUnmount = void 0;
14820
+ }
14471
14821
  if (!this.isCurrentInit(initId)) {
14472
14822
  container == null ? void 0 : container.remove();
14473
14823
  return;
14474
14824
  }
14475
14825
  console.error("[rai-widget] Bundle mount failed:", err);
14826
+ container == null ? void 0 : container.remove();
14476
14827
  (_a = this.releaseAutoThemeDisableLease) == null ? void 0 : _a.call(this);
14477
14828
  this.releaseAutoThemeDisableLease = void 0;
14478
14829
  this.showError();
@@ -14486,9 +14837,7 @@ class BaseWidget extends HTMLElement {
14486
14837
  const pushToken = () => {
14487
14838
  if (this.state.iframe)
14488
14839
  sendTokenToWidget(this.config, this.state, this.state.iframe);
14489
- if (this.config.bundleUrl && this.state.accessToken) {
14490
- window.guest_token = this.state.accessToken;
14491
- }
14840
+ syncBundleAccessToken(this.config, this.state);
14492
14841
  };
14493
14842
  const doRefresh = async () => {
14494
14843
  if (this.config.authUrl) {
@@ -14566,6 +14915,7 @@ class StoreWidget extends BaseWidget {
14566
14915
  url.searchParams.set("containerId", config.container);
14567
14916
  url.searchParams.set("connectType", "simple");
14568
14917
  url.searchParams.set("mode", "private");
14918
+ if (config.language) url.searchParams.set("language", config.language);
14569
14919
  if (config.locale) url.searchParams.set("locale", config.locale);
14570
14920
  return url.toString();
14571
14921
  }
@@ -14576,10 +14926,12 @@ class ChannelWidget extends BaseWidget {
14576
14926
  try {
14577
14927
  const u = new URL(base);
14578
14928
  u.searchParams.set("color", config.theme);
14929
+ if (config.language) u.searchParams.set("language", config.language);
14579
14930
  if (config.locale) u.searchParams.set("locale", config.locale);
14580
14931
  return u.toString();
14581
14932
  } catch {
14582
14933
  const params = [`color=${config.theme}`];
14934
+ if (config.language) params.push(`language=${encodeURIComponent(config.language)}`);
14583
14935
  if (config.locale) params.push(`locale=${encodeURIComponent(config.locale)}`);
14584
14936
  return `${base}?${params.join("&")}`;
14585
14937
  }
@@ -14591,10 +14943,12 @@ class MilestoneWidget extends BaseWidget {
14591
14943
  try {
14592
14944
  const u = new URL(base);
14593
14945
  u.searchParams.set("color", config.theme);
14946
+ if (config.language) u.searchParams.set("language", config.language);
14594
14947
  if (config.locale) u.searchParams.set("locale", config.locale);
14595
14948
  return u.toString();
14596
14949
  } catch {
14597
14950
  const params = [`color=${config.theme}`];
14951
+ if (config.language) params.push(`language=${encodeURIComponent(config.language)}`);
14598
14952
  if (config.locale) params.push(`locale=${encodeURIComponent(config.locale)}`);
14599
14953
  return `${base}?${params.join("&")}`;
14600
14954
  }
@@ -14606,10 +14960,12 @@ class SocialWidget extends BaseWidget {
14606
14960
  try {
14607
14961
  const u = new URL(base);
14608
14962
  u.searchParams.set("color", config.theme);
14963
+ if (config.language) u.searchParams.set("language", config.language);
14609
14964
  if (config.locale) u.searchParams.set("locale", config.locale);
14610
14965
  return u.toString();
14611
14966
  } catch {
14612
14967
  const params = [`color=${config.theme}`];
14968
+ if (config.language) params.push(`language=${encodeURIComponent(config.language)}`);
14613
14969
  if (config.locale) params.push(`locale=${encodeURIComponent(config.locale)}`);
14614
14970
  return `${base}?${params.join("&")}`;
14615
14971
  }
@@ -14621,10 +14977,12 @@ class CurrencyWidget extends BaseWidget {
14621
14977
  try {
14622
14978
  const u = new URL(base);
14623
14979
  u.searchParams.set("color", config.theme);
14980
+ if (config.language) u.searchParams.set("language", config.language);
14624
14981
  if (config.locale) u.searchParams.set("locale", config.locale);
14625
14982
  return u.toString();
14626
14983
  } catch {
14627
14984
  const params = [`color=${config.theme}`];
14985
+ if (config.language) params.push(`language=${encodeURIComponent(config.language)}`);
14628
14986
  if (config.locale) params.push(`locale=${encodeURIComponent(config.locale)}`);
14629
14987
  return `${base}?${params.join("&")}`;
14630
14988
  }
@@ -14636,10 +14994,12 @@ class ReferralWidget extends BaseWidget {
14636
14994
  try {
14637
14995
  const u = new URL(base);
14638
14996
  u.searchParams.set("color", config.theme);
14997
+ if (config.language) u.searchParams.set("language", config.language);
14639
14998
  if (config.locale) u.searchParams.set("locale", config.locale);
14640
14999
  return u.toString();
14641
15000
  } catch {
14642
15001
  const params = [`color=${config.theme}`];
15002
+ if (config.language) params.push(`language=${encodeURIComponent(config.language)}`);
14643
15003
  if (config.locale) params.push(`locale=${encodeURIComponent(config.locale)}`);
14644
15004
  return `${base}?${params.join("&")}`;
14645
15005
  }
@@ -14652,17 +15012,19 @@ class CustomWidget extends BaseWidget {
14652
15012
  const u = new URL(base);
14653
15013
  u.searchParams.set("auth", "postmessage");
14654
15014
  if (config.themeExplicit) u.searchParams.set("color", config.theme);
15015
+ if (config.language) u.searchParams.set("language", config.language);
14655
15016
  if (config.locale) u.searchParams.set("locale", config.locale);
14656
15017
  return u.toString();
14657
15018
  } catch {
14658
15019
  const params = ["auth=postmessage"];
14659
15020
  if (config.themeExplicit) params.push(`color=${config.theme}`);
15021
+ if (config.language) params.push(`language=${encodeURIComponent(config.language)}`);
14660
15022
  if (config.locale) params.push(`locale=${encodeURIComponent(config.locale)}`);
14661
15023
  return params.length > 0 ? `${base}?${params.join("&")}` : base;
14662
15024
  }
14663
15025
  }
14664
15026
  }
14665
- console.log(`[rai-widget] v${"1.8.0"}`);
15027
+ console.log(`[rai-widget] v${"1.8.2"}`);
14666
15028
  class StoreWidgetCompat extends StoreWidget {
14667
15029
  }
14668
15030
  const WIDGET_REGISTRY = [
@@ -14726,7 +15088,7 @@ function exposePublicApi() {
14726
15088
  })();
14727
15089
  const widget = container == null ? void 0 : container.querySelector(ALL_WIDGET_SELECTOR);
14728
15090
  window.ReturningAIWidget = {
14729
- version: "1.8.0",
15091
+ version: "1.8.2",
14730
15092
  reload: () => (widget == null ? void 0 : widget.reload()) ?? Promise.resolve(),
14731
15093
  logout: () => (widget == null ? void 0 : widget.logoutPublic()) ?? Promise.resolve(),
14732
15094
  isAuthenticated: () => (widget == null ? void 0 : widget.isAuthenticated()) ?? false,