@strands.gg/accui 1.4.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/nuxt/runtime/composables/useStrandsAuth.cjs.js +1 -1
  2. package/dist/nuxt/runtime/composables/useStrandsAuth.d.ts +11 -0
  3. package/dist/nuxt/runtime/composables/useStrandsAuth.d.ts.map +1 -1
  4. package/dist/nuxt/runtime/composables/useStrandsAuth.es.js +1 -1
  5. package/dist/nuxt/runtime/plugin.client.cjs.js +1 -1
  6. package/dist/nuxt/runtime/plugin.client.es.js +1 -1
  7. package/dist/nuxt/runtime/plugin.server.cjs.js +1 -1
  8. package/dist/nuxt/runtime/plugin.server.es.js +1 -1
  9. package/dist/nuxt-v4/runtime/composables/useStrandsAuth.cjs.js +1 -1
  10. package/dist/nuxt-v4/runtime/composables/useStrandsAuth.es.js +1 -1
  11. package/dist/nuxt-v4/runtime/plugin.client.cjs.js +1 -1
  12. package/dist/nuxt-v4/runtime/plugin.client.es.js +1 -1
  13. package/dist/nuxt-v4/runtime/plugin.server.cjs.js +1 -1
  14. package/dist/nuxt-v4/runtime/plugin.server.es.js +1 -1
  15. package/dist/strands-auth-ui.cjs.js +341 -104
  16. package/dist/strands-auth-ui.cjs.js.map +1 -1
  17. package/dist/strands-auth-ui.es.js +342 -105
  18. package/dist/strands-auth-ui.es.js.map +1 -1
  19. package/dist/types/index.d.ts +5 -0
  20. package/dist/types/index.d.ts.map +1 -1
  21. package/dist/{useStrandsAuth-zR8fRWme.cjs → useStrandsAuth-CVR23cd8.cjs} +77 -2
  22. package/dist/useStrandsAuth-CVR23cd8.cjs.map +1 -0
  23. package/dist/{useStrandsAuth-SdmBCyFS.js → useStrandsAuth-if4J5WT8.js} +77 -2
  24. package/dist/useStrandsAuth-if4J5WT8.js.map +1 -0
  25. package/dist/{useStrandsConfig-COEj6nFc.js → useStrandsConfig-Bdk-g0jS.js} +9 -1
  26. package/dist/useStrandsConfig-Bdk-g0jS.js.map +1 -0
  27. package/dist/{useStrandsConfig-DW4ez8t4.cjs → useStrandsConfig-CtmQtE7Y.cjs} +9 -1
  28. package/dist/useStrandsConfig-CtmQtE7Y.cjs.map +1 -0
  29. package/dist/vue/components/SignedIn.vue.d.ts +2 -0
  30. package/dist/vue/components/SignedIn.vue.d.ts.map +1 -1
  31. package/dist/vue/components/SignedOut.vue.d.ts +2 -0
  32. package/dist/vue/components/SignedOut.vue.d.ts.map +1 -1
  33. package/dist/vue/components/StrandsUserProfile.vue.d.ts.map +1 -1
  34. package/dist/vue/composables/useStrandsAuth.d.ts +11 -0
  35. package/dist/vue/composables/useStrandsAuth.d.ts.map +1 -1
  36. package/dist/vue/composables/useStrandsConfig.d.ts.map +1 -1
  37. package/dist/vue/ui/UiAvatarEditorSimple.vue.d.ts.map +1 -1
  38. package/package.json +1 -1
  39. package/dist/useStrandsAuth-SdmBCyFS.js.map +0 -1
  40. package/dist/useStrandsAuth-zR8fRWme.cjs.map +0 -1
  41. package/dist/useStrandsConfig-COEj6nFc.js.map +0 -1
  42. package/dist/useStrandsConfig-DW4ez8t4.cjs.map +0 -1
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const vue = require("vue");
4
- const useStrandsConfig = require("./useStrandsConfig-DW4ez8t4.cjs");
5
- const useStrandsAuth = require("./useStrandsAuth-zR8fRWme.cjs");
4
+ const useStrandsConfig = require("./useStrandsConfig-CtmQtE7Y.cjs");
5
+ const useStrandsAuth = require("./useStrandsAuth-CVR23cd8.cjs");
6
6
  const _sfc_main$w = /* @__PURE__ */ vue.defineComponent({
7
7
  __name: "UiAlert",
8
8
  props: {
@@ -1884,17 +1884,18 @@ const _sfc_main$n = /* @__PURE__ */ vue.defineComponent({
1884
1884
  img.onload = () => {
1885
1885
  originalImage.value = img;
1886
1886
  isResetting.value = true;
1887
- const scale = Math.min(
1887
+ const scale = Math.max(
1888
1888
  cropRadius.value * 2 / img.width,
1889
1889
  cropRadius.value * 2 / img.height
1890
1890
  );
1891
- const initialZoom = scale;
1891
+ const initialZoom = scale * 1.2;
1892
1892
  minZoom.value = scale;
1893
1893
  const scaledWidth = img.width * initialZoom;
1894
1894
  const scaledHeight = img.height * initialZoom;
1895
1895
  imagePos.x = (canvasSize.value - scaledWidth) / 2;
1896
1896
  imagePos.y = (canvasSize.value - scaledHeight) / 2;
1897
1897
  zoom.value = initialZoom;
1898
+ constrainImagePosition();
1898
1899
  vue.nextTick(() => {
1899
1900
  isResetting.value = false;
1900
1901
  });
@@ -1911,6 +1912,7 @@ const _sfc_main$n = /* @__PURE__ */ vue.defineComponent({
1911
1912
  const scaledHeight = img.height * zoom.value;
1912
1913
  imagePos.x = (canvasSize.value - scaledWidth) / 2;
1913
1914
  imagePos.y = (canvasSize.value - scaledHeight) / 2;
1915
+ constrainImagePosition();
1914
1916
  };
1915
1917
  const updateCanvas = () => {
1916
1918
  if (!originalImage.value || !canvas2.value) return;
@@ -1960,12 +1962,29 @@ const _sfc_main$n = /* @__PURE__ */ vue.defineComponent({
1960
1962
  document.addEventListener("mousemove", handleDrag);
1961
1963
  document.addEventListener("mouseup", stopDrag);
1962
1964
  };
1965
+ const constrainImagePosition = () => {
1966
+ if (!originalImage.value) return;
1967
+ const img = originalImage.value;
1968
+ const scaledWidth = img.width * zoom.value;
1969
+ const scaledHeight = img.height * zoom.value;
1970
+ const circleLeft = canvasSize.value / 2 - cropRadius.value;
1971
+ const circleTop = canvasSize.value / 2 - cropRadius.value;
1972
+ const circleRight = canvasSize.value / 2 + cropRadius.value;
1973
+ const circleBottom = canvasSize.value / 2 + cropRadius.value;
1974
+ const maxX = circleRight - scaledWidth;
1975
+ const minX = circleLeft;
1976
+ const maxY = circleBottom - scaledHeight;
1977
+ const minY = circleTop;
1978
+ imagePos.x = Math.min(minX, Math.max(maxX, imagePos.x));
1979
+ imagePos.y = Math.min(minY, Math.max(maxY, imagePos.y));
1980
+ };
1963
1981
  const handleDrag = (event) => {
1964
1982
  if (!isDragging.value) return;
1965
1983
  const deltaX = event.clientX - dragStart.x;
1966
1984
  const deltaY = event.clientY - dragStart.y;
1967
1985
  imagePos.x = dragStart.imageX + deltaX;
1968
1986
  imagePos.y = dragStart.imageY + deltaY;
1987
+ constrainImagePosition();
1969
1988
  updateCanvas();
1970
1989
  };
1971
1990
  const stopDrag = () => {
@@ -1988,6 +2007,7 @@ const _sfc_main$n = /* @__PURE__ */ vue.defineComponent({
1988
2007
  imagePos.x = imageCenterX - newWidth / 2;
1989
2008
  imagePos.y = imageCenterY - newHeight / 2;
1990
2009
  zoom.value = newZoom;
2010
+ constrainImagePosition();
1991
2011
  updateCanvas();
1992
2012
  }
1993
2013
  };
@@ -1995,16 +2015,17 @@ const _sfc_main$n = /* @__PURE__ */ vue.defineComponent({
1995
2015
  if (!originalImage.value) return;
1996
2016
  const img = originalImage.value;
1997
2017
  isResetting.value = true;
1998
- const scale = Math.min(
2018
+ const scale = Math.max(
1999
2019
  cropRadius.value * 2 / img.width,
2000
2020
  cropRadius.value * 2 / img.height
2001
2021
  );
2002
- const targetZoom = scale;
2022
+ const targetZoom = scale * 1.2;
2003
2023
  const scaledWidth = img.width * targetZoom;
2004
2024
  const scaledHeight = img.height * targetZoom;
2005
2025
  imagePos.x = (canvasSize.value - scaledWidth) / 2;
2006
2026
  imagePos.y = (canvasSize.value - scaledHeight) / 2;
2007
2027
  zoom.value = targetZoom;
2028
+ constrainImagePosition();
2008
2029
  vue.nextTick(() => {
2009
2030
  isResetting.value = false;
2010
2031
  });
@@ -2078,7 +2099,7 @@ const _sfc_main$n = /* @__PURE__ */ vue.defineComponent({
2078
2099
  processFile(file);
2079
2100
  }
2080
2101
  }, { immediate: true });
2081
- const __returned__ = { props, emit, fileInput, canvas: canvas2, previewCanvas, imageData, originalImage, canvasSize, previewSize, cropRadius, imagePos, zoom, minZoom, maxZoom, isDragging, isResetting, dragStart, triggerFileUpload, handleFileSelect, handleDrop, processFile, loadImage, centerImage, updateCanvas, updatePreview, startDrag, handleDrag, stopDrag, handleWheel, resetImage, cropAndUpload, clearImage };
2102
+ const __returned__ = { props, emit, fileInput, canvas: canvas2, previewCanvas, imageData, originalImage, canvasSize, previewSize, cropRadius, imagePos, zoom, minZoom, maxZoom, isDragging, isResetting, dragStart, triggerFileUpload, handleFileSelect, handleDrop, processFile, loadImage, centerImage, updateCanvas, updatePreview, startDrag, constrainImagePosition, handleDrag, stopDrag, handleWheel, resetImage, cropAndUpload, clearImage };
2082
2103
  Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2083
2104
  return __returned__;
2084
2105
  }
@@ -2119,7 +2140,7 @@ function _sfc_render$n(_ctx, _cache, $props, $setup, $data, $options) {
2119
2140
  }, ["prevent"]))
2120
2141
  },
2121
2142
  [
2122
- _cache[5] || (_cache[5] = vue.createStaticVNode('<div class="upload-content"><svg class="w-12 h-12 text-gray-400 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg><h3 class="text-lg font-semibold text-gray-900 mb-1">Upload your photo</h3><p class="text-sm text-gray-500 mb-4">Drag and drop or click to browse</p><div class="flex gap-2 justify-center text-xs text-gray-400"><span class="px-2 py-1 bg-gray-100 rounded">JPG</span><span class="px-2 py-1 bg-gray-100 rounded">PNG</span><span class="px-2 py-1 bg-gray-100 rounded">GIF</span></div></div>', 1)),
2143
+ _cache[6] || (_cache[6] = vue.createStaticVNode('<div class="upload-content"><svg class="w-12 h-12 text-gray-400 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg><h3 class="text-lg font-semibold text-gray-900 mb-1">Upload your photo</h3><p class="text-sm text-gray-500 mb-4">Drag and drop or click to browse</p><div class="flex gap-2 justify-center text-xs text-gray-400"><span class="px-2 py-1 bg-gray-100 rounded">JPG</span><span class="px-2 py-1 bg-gray-100 rounded">PNG</span><span class="px-2 py-1 bg-gray-100 rounded">GIF</span></div></div>', 1)),
2123
2144
  vue.createElementVNode(
2124
2145
  "input",
2125
2146
  {
@@ -2201,10 +2222,11 @@ function _sfc_render$n(_ctx, _cache, $props, $setup, $data, $options) {
2201
2222
  vue.createElementVNode("button", {
2202
2223
  onClick: _cache[2] || (_cache[2] = ($event) => {
2203
2224
  $setup.zoom = Math.max($setup.minZoom, $setup.zoom - 0.1);
2225
+ $setup.constrainImagePosition();
2204
2226
  $setup.updateCanvas();
2205
2227
  }),
2206
2228
  class: "zoom-button"
2207
- }, _cache[6] || (_cache[6] = [
2229
+ }, _cache[7] || (_cache[7] = [
2208
2230
  vue.createElementVNode(
2209
2231
  "svg",
2210
2232
  {
@@ -2232,7 +2254,10 @@ function _sfc_render$n(_ctx, _cache, $props, $setup, $data, $options) {
2232
2254
  max: $setup.maxZoom,
2233
2255
  step: 0.01,
2234
2256
  class: "zoom-slider",
2235
- onInput: $setup.updateCanvas
2257
+ onInput: _cache[4] || (_cache[4] = ($event) => {
2258
+ $setup.constrainImagePosition();
2259
+ $setup.updateCanvas();
2260
+ })
2236
2261
  }, null, 40, _hoisted_15$a), [
2237
2262
  [
2238
2263
  vue.vModelText,
@@ -2242,12 +2267,13 @@ function _sfc_render$n(_ctx, _cache, $props, $setup, $data, $options) {
2242
2267
  ]
2243
2268
  ]),
2244
2269
  vue.createElementVNode("button", {
2245
- onClick: _cache[4] || (_cache[4] = ($event) => {
2270
+ onClick: _cache[5] || (_cache[5] = ($event) => {
2246
2271
  $setup.zoom = Math.min($setup.maxZoom, $setup.zoom + 0.1);
2272
+ $setup.constrainImagePosition();
2247
2273
  $setup.updateCanvas();
2248
2274
  }),
2249
2275
  class: "zoom-button"
2250
- }, _cache[7] || (_cache[7] = [
2276
+ }, _cache[8] || (_cache[8] = [
2251
2277
  vue.createElementVNode(
2252
2278
  "svg",
2253
2279
  {
@@ -2289,7 +2315,7 @@ function _sfc_render$n(_ctx, _cache, $props, $setup, $data, $options) {
2289
2315
  ]),
2290
2316
  vue.createCommentVNode(" Preview "),
2291
2317
  vue.createElementVNode("div", _hoisted_18$7, [
2292
- _cache[8] || (_cache[8] = vue.createElementVNode(
2318
+ _cache[9] || (_cache[9] = vue.createElementVNode(
2293
2319
  "h3",
2294
2320
  { class: "text-sm font-medium text-gray-700 mb-3" },
2295
2321
  "Preview",
@@ -2304,7 +2330,7 @@ function _sfc_render$n(_ctx, _cache, $props, $setup, $data, $options) {
2304
2330
  class: "preview-canvas"
2305
2331
  }, null, 8, _hoisted_20$6)
2306
2332
  ]),
2307
- _cache[9] || (_cache[9] = vue.createElementVNode(
2333
+ _cache[10] || (_cache[10] = vue.createElementVNode(
2308
2334
  "p",
2309
2335
  { class: "text-xs text-gray-500 mt-3 text-center" },
2310
2336
  [
@@ -12441,7 +12467,7 @@ const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
12441
12467
  const props = __props;
12442
12468
  const emit = __emit;
12443
12469
  const { getSupportEmail, getUrl } = useStrandsConfig.useStrandsConfig(props.config);
12444
- const { fetchProfile, updateProfile, changeEmail, currentUser: authUser, currentSession, isAuthenticated, refreshToken, signOut } = useStrandsAuth.useStrandsAuth();
12470
+ const { fetchProfile, updateProfile, changeEmail, changeUsername, getUsernameCooldown, checkUsernameAvailability, currentUser: authUser, currentSession, isAuthenticated, refreshToken, signOut } = useStrandsAuth.useStrandsAuth();
12445
12471
  const { activeMfaDevices, fetchMfaDevices } = useStrandsMfa();
12446
12472
  const internalUser = vue.ref(null);
12447
12473
  const fetchingProfile = vue.ref(false);
@@ -12462,6 +12488,8 @@ const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
12462
12488
  const showPasswordChange = vue.ref(false);
12463
12489
  const showEmailChange = vue.ref(false);
12464
12490
  const emailChangeLoading = vue.ref(false);
12491
+ const showUsernameChange = vue.ref(false);
12492
+ const usernameChangeLoading = vue.ref(false);
12465
12493
  const showMfaModal = vue.ref(false);
12466
12494
  const showSettingsModal = vue.ref(false);
12467
12495
  const showAvatarEditor = vue.ref(false);
@@ -12469,6 +12497,16 @@ const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
12469
12497
  const successMessage = vue.ref("");
12470
12498
  const errorMessage = vue.ref("");
12471
12499
  const activeSessions = vue.ref([]);
12500
+ const usernameChangeData = vue.reactive({
12501
+ canChange: true,
12502
+ cooldownEnd: null,
12503
+ daysRemaining: 0
12504
+ });
12505
+ const usernameAvailability = vue.reactive({
12506
+ available: false,
12507
+ message: "",
12508
+ checking: false
12509
+ });
12472
12510
  const avatarFileInput = vue.ref();
12473
12511
  const form = vue.reactive({
12474
12512
  firstName: "",
@@ -12488,6 +12526,12 @@ const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
12488
12526
  new: "",
12489
12527
  confirm: ""
12490
12528
  });
12529
+ const usernameForm = vue.reactive({
12530
+ username: "",
12531
+ errors: {
12532
+ username: ""
12533
+ }
12534
+ });
12491
12535
  const errors = vue.reactive({
12492
12536
  firstName: "",
12493
12537
  lastName: "",
@@ -12504,6 +12548,10 @@ const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
12504
12548
  const isEmailChangeFormValid = vue.computed(() => {
12505
12549
  return emailChangeForm.newEmail && emailChangeForm.password && emailChangeForm.newEmail !== currentUser.value?.email && emailChangeForm.newEmail.includes("@");
12506
12550
  });
12551
+ const isUsernameChangeFormValid = vue.computed(() => {
12552
+ const usernameRegex = /^[a-zA-Z0-9_-]{3,30}$/;
12553
+ return usernameForm.username && usernameRegex.test(usernameForm.username) && usernameForm.username !== currentUser.value?.username && !usernameAvailability.checking;
12554
+ });
12507
12555
  const passwordLastUpdated = vue.computed(() => {
12508
12556
  const user = currentUser.value;
12509
12557
  if (!user) return "Never";
@@ -12724,6 +12772,86 @@ const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
12724
12772
  emailChangeLoading.value = false;
12725
12773
  }
12726
12774
  };
12775
+ const handleToggleUsernameChange = async () => {
12776
+ if (!showUsernameChange.value) {
12777
+ usernameChangeLoading.value = true;
12778
+ try {
12779
+ const cooldownData = await getUsernameCooldown();
12780
+ usernameChangeData.canChange = cooldownData.can_change;
12781
+ usernameChangeData.cooldownEnd = cooldownData.cooldown_end ? new Date(cooldownData.cooldown_end) : null;
12782
+ usernameChangeData.daysRemaining = cooldownData.days_remaining || 0;
12783
+ if (usernameChangeData.canChange) {
12784
+ showUsernameChange.value = true;
12785
+ usernameForm.username = currentUser.value?.username || "";
12786
+ } else {
12787
+ errorMessage.value = `You can change your username again in ${usernameChangeData.daysRemaining} days`;
12788
+ }
12789
+ } catch (err) {
12790
+ errorMessage.value = "Failed to check username cooldown";
12791
+ showUsernameChange.value = true;
12792
+ } finally {
12793
+ usernameChangeLoading.value = false;
12794
+ }
12795
+ } else {
12796
+ showUsernameChange.value = false;
12797
+ usernameForm.username = "";
12798
+ usernameForm.errors.username = "";
12799
+ usernameAvailability.available = false;
12800
+ usernameAvailability.message = "";
12801
+ }
12802
+ };
12803
+ const handleUsernameChange = async () => {
12804
+ if (!isUsernameChangeFormValid.value) {
12805
+ const usernameRegex = /^[a-zA-Z0-9_-]{3,30}$/;
12806
+ if (!usernameRegex.test(usernameForm.username)) {
12807
+ usernameForm.errors.username = "Username must be 3-30 characters and contain only letters, numbers, hyphens, and underscores";
12808
+ return;
12809
+ }
12810
+ usernameAvailability.checking = true;
12811
+ usernameAvailability.message = "Checking availability...";
12812
+ try {
12813
+ const result = await checkUsernameAvailability(usernameForm.username);
12814
+ usernameAvailability.available = result.available;
12815
+ usernameAvailability.message = result.message;
12816
+ if (!result.available) {
12817
+ usernameForm.errors.username = "Username is not available";
12818
+ return;
12819
+ }
12820
+ } catch (err) {
12821
+ usernameForm.errors.username = "Failed to check username availability";
12822
+ return;
12823
+ } finally {
12824
+ usernameAvailability.checking = false;
12825
+ }
12826
+ }
12827
+ clearMessages();
12828
+ usernameChangeLoading.value = true;
12829
+ try {
12830
+ const result = await changeUsername(usernameForm.username);
12831
+ successMessage.value = result.message || "Username updated successfully";
12832
+ showUsernameChange.value = false;
12833
+ usernameForm.username = "";
12834
+ usernameForm.errors.username = "";
12835
+ usernameAvailability.available = false;
12836
+ usernameAvailability.message = "";
12837
+ if (currentUser.value) {
12838
+ emit("profile-updated", currentUser.value);
12839
+ }
12840
+ } catch (err) {
12841
+ const error = err instanceof Error ? err.message : "Failed to update username";
12842
+ if (error.includes("taken")) {
12843
+ usernameForm.errors.username = "Username is already taken";
12844
+ } else if (error.includes("cooldown") || error.includes("30 days")) {
12845
+ errorMessage.value = error;
12846
+ showUsernameChange.value = false;
12847
+ } else {
12848
+ usernameForm.errors.username = error;
12849
+ }
12850
+ emit("error", error);
12851
+ } finally {
12852
+ usernameChangeLoading.value = false;
12853
+ }
12854
+ };
12727
12855
  const triggerAvatarUpload = () => {
12728
12856
  if (uploading.value) return;
12729
12857
  avatarFileInput.value?.click();
@@ -12901,7 +13029,19 @@ const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
12901
13029
  signingOut.value = false;
12902
13030
  }
12903
13031
  };
12904
- const __returned__ = { props, emit, getSupportEmail, getUrl, fetchProfile, updateProfile, changeEmail, authUser, currentSession, isAuthenticated, refreshToken, signOut, activeMfaDevices, fetchMfaDevices, internalUser, fetchingProfile, currentUser, loading: loading2, uploading, signingOut, showPasswordChange, showEmailChange, emailChangeLoading, showMfaModal, showSettingsModal, showAvatarEditor, selectedImageFile, successMessage, errorMessage, activeSessions, avatarFileInput, form, emailChangeForm, passwordForm, errors, hasChanges, isPasswordFormValid, isEmailChangeFormValid, passwordLastUpdated, deviceTypeCounts, mfaDeviceChips, getXpForLevel, getLevelFromXp, userLevel, currentExp, expToNextLevel, progressPercentage, totalCircumference, progressLength, progressGapLength, getInitials: getInitials2, fetchUserProfile, clearMessages, handleUpdateProfile, handlePasswordChange, handleEmailChange, triggerAvatarUpload, handleAvatarFileSelect, handleAvatarUpload, handleAvatarError, handleAvatarEditorClose, uploadAvatar, handleMfaUpdated, handleSettingsUpdated, handleCancel, handleSignOut, get StrandsUiButton() {
13032
+ vue.onMounted(async () => {
13033
+ if (currentUser.value && isAuthenticated.value) {
13034
+ try {
13035
+ const cooldownData = await getUsernameCooldown();
13036
+ usernameChangeData.canChange = cooldownData.can_change;
13037
+ usernameChangeData.cooldownEnd = cooldownData.cooldown_end ? new Date(cooldownData.cooldown_end) : null;
13038
+ usernameChangeData.daysRemaining = cooldownData.days_remaining || 0;
13039
+ } catch (err) {
13040
+ console.error("Failed to fetch username cooldown:", err);
13041
+ }
13042
+ }
13043
+ });
13044
+ const __returned__ = { props, emit, getSupportEmail, getUrl, fetchProfile, updateProfile, changeEmail, changeUsername, getUsernameCooldown, checkUsernameAvailability, authUser, currentSession, isAuthenticated, refreshToken, signOut, activeMfaDevices, fetchMfaDevices, internalUser, fetchingProfile, currentUser, loading: loading2, uploading, signingOut, showPasswordChange, showEmailChange, emailChangeLoading, showUsernameChange, usernameChangeLoading, showMfaModal, showSettingsModal, showAvatarEditor, selectedImageFile, successMessage, errorMessage, activeSessions, usernameChangeData, usernameAvailability, avatarFileInput, form, emailChangeForm, passwordForm, usernameForm, errors, hasChanges, isPasswordFormValid, isEmailChangeFormValid, isUsernameChangeFormValid, passwordLastUpdated, deviceTypeCounts, mfaDeviceChips, getXpForLevel, getLevelFromXp, userLevel, currentExp, expToNextLevel, progressPercentage, totalCircumference, progressLength, progressGapLength, getInitials: getInitials2, fetchUserProfile, clearMessages, handleUpdateProfile, handlePasswordChange, handleEmailChange, handleToggleUsernameChange, handleUsernameChange, triggerAvatarUpload, handleAvatarFileSelect, handleAvatarUpload, handleAvatarError, handleAvatarEditorClose, uploadAvatar, handleMfaUpdated, handleSettingsUpdated, handleCancel, handleSignOut, get StrandsUiButton() {
12905
13045
  return StrandsUiButton;
12906
13046
  }, get StrandsUiInput() {
12907
13047
  return StrandsUiInput;
@@ -12949,58 +13089,69 @@ const _hoisted_16$1 = {
12949
13089
  key: 0,
12950
13090
  class: "space-y-3 overflow-hidden"
12951
13091
  };
12952
- const _hoisted_17$1 = { class: "space-y-3 md:space-y-4" };
12953
- const _hoisted_18$1 = { class: "space-y-4 p-4 bg-gray-50 rounded-xl" };
12954
- const _hoisted_19$1 = { class: "flex items-center justify-between gap-2" };
12955
- const _hoisted_20$1 = { class: "text-sm text-gray-600" };
13092
+ const _hoisted_17$1 = { class: "space-y-4 p-4 bg-gray-50 rounded-xl" };
13093
+ const _hoisted_18$1 = { class: "flex items-center justify-between gap-2" };
13094
+ const _hoisted_19$1 = { class: "text-sm text-gray-600" };
13095
+ const _hoisted_20$1 = {
13096
+ key: 0,
13097
+ class: "text-red-600 ml-2"
13098
+ };
12956
13099
  const _hoisted_21 = {
12957
13100
  key: 0,
12958
13101
  class: "space-y-3 overflow-hidden"
12959
13102
  };
12960
- const _hoisted_22 = { class: "p-4 bg-gray-50 rounded-xl" };
12961
- const _hoisted_23 = { class: "flex items-start justify-between gap-4" };
12962
- const _hoisted_24 = { class: "flex-1" };
12963
- const _hoisted_25 = { class: "text-sm text-gray-600 mt-1" };
13103
+ const _hoisted_22 = { class: "space-y-3 md:space-y-4" };
13104
+ const _hoisted_23 = { class: "space-y-4 p-4 bg-gray-50 rounded-xl" };
13105
+ const _hoisted_24 = { class: "flex items-center justify-between gap-2" };
13106
+ const _hoisted_25 = { class: "text-sm text-gray-600" };
12964
13107
  const _hoisted_26 = {
12965
13108
  key: 0,
12966
- class: "flex flex-wrap gap-2 mt-3"
13109
+ class: "space-y-3 overflow-hidden"
12967
13110
  };
12968
- const _hoisted_27 = { class: "ml-1" };
12969
- const _hoisted_28 = { class: "p-4 bg-gray-50 rounded-xl" };
12970
- const _hoisted_29 = { class: "flex items-center justify-between gap-2" };
12971
- const _hoisted_30 = { class: "text-sm text-gray-600" };
13111
+ const _hoisted_27 = { class: "p-4 bg-gray-50 rounded-xl" };
13112
+ const _hoisted_28 = { class: "flex items-start justify-between gap-4" };
13113
+ const _hoisted_29 = { class: "flex-1" };
13114
+ const _hoisted_30 = { class: "text-sm text-gray-600 mt-1" };
12972
13115
  const _hoisted_31 = {
13116
+ key: 0,
13117
+ class: "flex flex-wrap gap-2 mt-3"
13118
+ };
13119
+ const _hoisted_32 = { class: "ml-1" };
13120
+ const _hoisted_33 = { class: "p-4 bg-gray-50 rounded-xl" };
13121
+ const _hoisted_34 = { class: "flex items-center justify-between gap-2" };
13122
+ const _hoisted_35 = { class: "text-sm text-gray-600" };
13123
+ const _hoisted_36 = {
12973
13124
  key: 0,
12974
13125
  class: "flex flex-col sm:flex-row gap-3 pt-6 border-t border-gray-200 animate-slide-up"
12975
13126
  };
12976
- const _hoisted_32 = {
13127
+ const _hoisted_37 = {
12977
13128
  key: 0,
12978
13129
  class: "mt-6 animate-fade-in"
12979
13130
  };
12980
- const _hoisted_33 = { class: "alert-success" };
12981
- const _hoisted_34 = { class: "flex items-start gap-3" };
12982
- const _hoisted_35 = { class: "font-medium" };
12983
- const _hoisted_36 = {
13131
+ const _hoisted_38 = { class: "alert-success" };
13132
+ const _hoisted_39 = { class: "flex items-start gap-3" };
13133
+ const _hoisted_40 = { class: "font-medium" };
13134
+ const _hoisted_41 = {
12984
13135
  key: 1,
12985
13136
  class: "mt-6 animate-fade-in"
12986
13137
  };
12987
- const _hoisted_37 = { class: "alert-error" };
12988
- const _hoisted_38 = { class: "flex items-start gap-3" };
12989
- const _hoisted_39 = { class: "font-medium" };
12990
- const _hoisted_40 = { class: "flex gap-4 items-stretch" };
12991
- const _hoisted_41 = { key: 0 };
12992
- const _hoisted_42 = { class: "text-gray-400 text-sm" };
12993
- const _hoisted_43 = {
13138
+ const _hoisted_42 = { class: "alert-error" };
13139
+ const _hoisted_43 = { class: "flex items-start gap-3" };
13140
+ const _hoisted_44 = { class: "font-medium" };
13141
+ const _hoisted_45 = { class: "flex gap-4 items-stretch" };
13142
+ const _hoisted_46 = { key: 0 };
13143
+ const _hoisted_47 = { class: "text-gray-400 text-sm" };
13144
+ const _hoisted_48 = {
12994
13145
  key: 1,
12995
13146
  class: "fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4"
12996
13147
  };
12997
- const _hoisted_44 = { class: "bg-white rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-y-auto" };
12998
- const _hoisted_45 = { class: "p-6" };
13148
+ const _hoisted_49 = { class: "bg-white rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-y-auto" };
13149
+ const _hoisted_50 = { class: "p-6" };
12999
13150
  function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13000
13151
  return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$5, [
13001
13152
  vue.createElementVNode("div", _hoisted_2$4, [
13002
13153
  vue.createCommentVNode(" Header "),
13003
- _cache[29] || (_cache[29] = vue.createElementVNode(
13154
+ _cache[31] || (_cache[31] = vue.createElementVNode(
13004
13155
  "div",
13005
13156
  { class: "text-center mb-6" },
13006
13157
  [
@@ -13049,7 +13200,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13049
13200
  key: 0,
13050
13201
  size: 24,
13051
13202
  variant: "dark"
13052
- })) : (vue.openBlock(), vue.createElementBlock("svg", _hoisted_10$1, _cache[14] || (_cache[14] = [
13203
+ })) : (vue.openBlock(), vue.createElementBlock("svg", _hoisted_10$1, _cache[15] || (_cache[15] = [
13053
13204
  vue.createElementVNode(
13054
13205
  "path",
13055
13206
  {
@@ -13104,7 +13255,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13104
13255
  vue.createElementVNode("div", _hoisted_11$1, [
13105
13256
  vue.createCommentVNode(" Personal Information "),
13106
13257
  vue.createElementVNode("div", _hoisted_12$1, [
13107
- _cache[16] || (_cache[16] = vue.createElementVNode(
13258
+ _cache[18] || (_cache[18] = vue.createElementVNode(
13108
13259
  "h3",
13109
13260
  { class: "text-lg font-semibold text-gray-900 mb-3 md:mb-4" },
13110
13261
  "Personal Information",
@@ -13137,7 +13288,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13137
13288
  vue.createElementVNode("div", _hoisted_13$1, [
13138
13289
  vue.createElementVNode("div", _hoisted_14$1, [
13139
13290
  vue.createElementVNode("div", null, [
13140
- _cache[15] || (_cache[15] = vue.createElementVNode(
13291
+ _cache[16] || (_cache[16] = vue.createElementVNode(
13141
13292
  "h4",
13142
13293
  { class: "font-medium text-gray-900" },
13143
13294
  "Email Address",
@@ -13208,11 +13359,97 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13208
13359
  _: 1
13209
13360
  /* STABLE */
13210
13361
  })
13362
+ ]),
13363
+ vue.createCommentVNode(" Username Change Section "),
13364
+ vue.createElementVNode("div", _hoisted_17$1, [
13365
+ vue.createElementVNode("div", _hoisted_18$1, [
13366
+ vue.createElementVNode("div", null, [
13367
+ _cache[17] || (_cache[17] = vue.createElementVNode(
13368
+ "h4",
13369
+ { class: "font-medium text-gray-900" },
13370
+ "Username",
13371
+ -1
13372
+ /* CACHED */
13373
+ )),
13374
+ vue.createElementVNode("p", _hoisted_19$1, [
13375
+ vue.createTextVNode(
13376
+ vue.toDisplayString($setup.currentUser?.username || "No username set") + " ",
13377
+ 1
13378
+ /* TEXT */
13379
+ ),
13380
+ $setup.usernameChangeData.cooldownEnd ? (vue.openBlock(), vue.createElementBlock(
13381
+ "span",
13382
+ _hoisted_20$1,
13383
+ " (Can change in " + vue.toDisplayString($setup.usernameChangeData.daysRemaining) + " days) ",
13384
+ 1
13385
+ /* TEXT */
13386
+ )) : vue.createCommentVNode("v-if", true)
13387
+ ])
13388
+ ]),
13389
+ vue.createVNode($setup["StrandsUiButton"], {
13390
+ variant: "secondary",
13391
+ size: "sm",
13392
+ disabled: !$setup.usernameChangeData.canChange || $setup.usernameChangeLoading,
13393
+ onClick: $setup.handleToggleUsernameChange
13394
+ }, {
13395
+ default: vue.withCtx(() => [
13396
+ vue.createTextVNode(
13397
+ vue.toDisplayString($setup.showUsernameChange ? "Cancel" : $setup.currentUser?.username ? "Change" : "Set Username"),
13398
+ 1
13399
+ /* TEXT */
13400
+ )
13401
+ ]),
13402
+ _: 1
13403
+ /* STABLE */
13404
+ }, 8, ["disabled"])
13405
+ ]),
13406
+ vue.createVNode(vue.Transition, { name: "expand" }, {
13407
+ default: vue.withCtx(() => [
13408
+ $setup.showUsernameChange ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_21, [
13409
+ vue.createVNode($setup["StrandsUiInput"], {
13410
+ modelValue: $setup.usernameForm.username,
13411
+ "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => $setup.usernameForm.username = $event),
13412
+ type: "text",
13413
+ placeholder: "Enter username (3-30 characters)",
13414
+ autocomplete: "username",
13415
+ error: $setup.usernameForm.errors.username
13416
+ }, null, 8, ["modelValue", "error"]),
13417
+ $setup.usernameAvailability.message ? (vue.openBlock(), vue.createElementBlock(
13418
+ "div",
13419
+ {
13420
+ key: 0,
13421
+ class: vue.normalizeClass(["text-xs", $setup.usernameAvailability.available ? "text-green-600" : "text-red-600"])
13422
+ },
13423
+ vue.toDisplayString($setup.usernameAvailability.message),
13424
+ 3
13425
+ /* TEXT, CLASS */
13426
+ )) : vue.createCommentVNode("v-if", true),
13427
+ vue.createVNode($setup["StrandsUiButton"], {
13428
+ variant: "primary",
13429
+ size: "sm",
13430
+ onClick: $setup.handleUsernameChange,
13431
+ disabled: !$setup.isUsernameChangeFormValid || $setup.usernameChangeLoading
13432
+ }, {
13433
+ default: vue.withCtx(() => [
13434
+ vue.createTextVNode(
13435
+ vue.toDisplayString($setup.usernameChangeLoading ? "Updating..." : "Update Username"),
13436
+ 1
13437
+ /* TEXT */
13438
+ )
13439
+ ]),
13440
+ _: 1
13441
+ /* STABLE */
13442
+ }, 8, ["disabled"])
13443
+ ])) : vue.createCommentVNode("v-if", true)
13444
+ ]),
13445
+ _: 1
13446
+ /* STABLE */
13447
+ })
13211
13448
  ])
13212
13449
  ]),
13213
13450
  vue.createCommentVNode(" Security Settings "),
13214
- vue.createElementVNode("div", _hoisted_17$1, [
13215
- _cache[22] || (_cache[22] = vue.createElementVNode(
13451
+ vue.createElementVNode("div", _hoisted_22, [
13452
+ _cache[24] || (_cache[24] = vue.createElementVNode(
13216
13453
  "h3",
13217
13454
  { class: "text-lg font-semibold text-gray-900 mb-3 md:mb-4" },
13218
13455
  "Security Settings",
@@ -13220,10 +13457,10 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13220
13457
  /* CACHED */
13221
13458
  )),
13222
13459
  vue.createCommentVNode(" Password Change "),
13223
- vue.createElementVNode("div", _hoisted_18$1, [
13224
- vue.createElementVNode("div", _hoisted_19$1, [
13460
+ vue.createElementVNode("div", _hoisted_23, [
13461
+ vue.createElementVNode("div", _hoisted_24, [
13225
13462
  vue.createElementVNode("div", null, [
13226
- _cache[17] || (_cache[17] = vue.createElementVNode(
13463
+ _cache[19] || (_cache[19] = vue.createElementVNode(
13227
13464
  "h4",
13228
13465
  { class: "font-medium text-gray-900" },
13229
13466
  "Password",
@@ -13232,7 +13469,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13232
13469
  )),
13233
13470
  vue.createElementVNode(
13234
13471
  "p",
13235
- _hoisted_20$1,
13472
+ _hoisted_25,
13236
13473
  "Last updated " + vue.toDisplayString($setup.passwordLastUpdated),
13237
13474
  1
13238
13475
  /* TEXT */
@@ -13241,7 +13478,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13241
13478
  vue.createVNode($setup["StrandsUiButton"], {
13242
13479
  variant: "secondary",
13243
13480
  size: "sm",
13244
- onClick: _cache[5] || (_cache[5] = ($event) => $setup.showPasswordChange = !$setup.showPasswordChange)
13481
+ onClick: _cache[6] || (_cache[6] = ($event) => $setup.showPasswordChange = !$setup.showPasswordChange)
13245
13482
  }, {
13246
13483
  default: vue.withCtx(() => [
13247
13484
  vue.createTextVNode(
@@ -13256,24 +13493,24 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13256
13493
  ]),
13257
13494
  vue.createVNode(vue.Transition, { name: "expand" }, {
13258
13495
  default: vue.withCtx(() => [
13259
- $setup.showPasswordChange ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_21, [
13496
+ $setup.showPasswordChange ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_26, [
13260
13497
  vue.createVNode($setup["StrandsUiInput"], {
13261
13498
  modelValue: $setup.passwordForm.current,
13262
- "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => $setup.passwordForm.current = $event),
13499
+ "onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => $setup.passwordForm.current = $event),
13263
13500
  type: "password",
13264
13501
  placeholder: "Current password",
13265
13502
  autocomplete: "current-password"
13266
13503
  }, null, 8, ["modelValue"]),
13267
13504
  vue.createVNode($setup["StrandsUiInput"], {
13268
13505
  modelValue: $setup.passwordForm.new,
13269
- "onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => $setup.passwordForm.new = $event),
13506
+ "onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => $setup.passwordForm.new = $event),
13270
13507
  type: "password",
13271
13508
  placeholder: "New password",
13272
13509
  autocomplete: "new-password"
13273
13510
  }, null, 8, ["modelValue"]),
13274
13511
  vue.createVNode($setup["StrandsUiInput"], {
13275
13512
  modelValue: $setup.passwordForm.confirm,
13276
- "onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => $setup.passwordForm.confirm = $event),
13513
+ "onUpdate:modelValue": _cache[9] || (_cache[9] = ($event) => $setup.passwordForm.confirm = $event),
13277
13514
  type: "password",
13278
13515
  placeholder: "Confirm new password",
13279
13516
  autocomplete: "new-password"
@@ -13284,7 +13521,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13284
13521
  onClick: $setup.handlePasswordChange,
13285
13522
  disabled: !$setup.isPasswordFormValid
13286
13523
  }, {
13287
- default: vue.withCtx(() => _cache[18] || (_cache[18] = [
13524
+ default: vue.withCtx(() => _cache[20] || (_cache[20] = [
13288
13525
  vue.createTextVNode(
13289
13526
  " Update Password ",
13290
13527
  -1
@@ -13292,7 +13529,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13292
13529
  )
13293
13530
  ])),
13294
13531
  _: 1,
13295
- __: [18]
13532
+ __: [20]
13296
13533
  }, 8, ["disabled"])
13297
13534
  ])) : vue.createCommentVNode("v-if", true)
13298
13535
  ]),
@@ -13301,10 +13538,10 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13301
13538
  })
13302
13539
  ]),
13303
13540
  vue.createCommentVNode(" Two-Factor Authentication "),
13304
- vue.createElementVNode("div", _hoisted_22, [
13305
- vue.createElementVNode("div", _hoisted_23, [
13306
- vue.createElementVNode("div", _hoisted_24, [
13307
- _cache[19] || (_cache[19] = vue.createElementVNode(
13541
+ vue.createElementVNode("div", _hoisted_27, [
13542
+ vue.createElementVNode("div", _hoisted_28, [
13543
+ vue.createElementVNode("div", _hoisted_29, [
13544
+ _cache[21] || (_cache[21] = vue.createElementVNode(
13308
13545
  "h4",
13309
13546
  { class: "font-medium text-gray-900" },
13310
13547
  "Two-Factor Authentication",
@@ -13313,13 +13550,13 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13313
13550
  )),
13314
13551
  vue.createElementVNode(
13315
13552
  "p",
13316
- _hoisted_25,
13553
+ _hoisted_30,
13317
13554
  vue.toDisplayString($setup.currentUser?.mfaEnabled ? "Enabled" : "Add extra security to your account"),
13318
13555
  1
13319
13556
  /* TEXT */
13320
13557
  ),
13321
13558
  vue.createCommentVNode(" Device Type Chips "),
13322
- $setup.mfaDeviceChips.length > 0 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_26, [
13559
+ $setup.mfaDeviceChips.length > 0 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_31, [
13323
13560
  (vue.openBlock(true), vue.createElementBlock(
13324
13561
  vue.Fragment,
13325
13562
  null,
@@ -13347,7 +13584,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13347
13584
  ),
13348
13585
  vue.createElementVNode(
13349
13586
  "span",
13350
- _hoisted_27,
13587
+ _hoisted_32,
13351
13588
  vue.toDisplayString(chip.label),
13352
13589
  1
13353
13590
  /* TEXT */
@@ -13365,7 +13602,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13365
13602
  vue.createVNode($setup["StrandsUiButton"], {
13366
13603
  variant: $setup.currentUser?.mfaEnabled ? "secondary" : "primary",
13367
13604
  size: "sm",
13368
- onClick: _cache[9] || (_cache[9] = ($event) => $setup.showMfaModal = true),
13605
+ onClick: _cache[10] || (_cache[10] = ($event) => $setup.showMfaModal = true),
13369
13606
  class: "flex-shrink-0"
13370
13607
  }, {
13371
13608
  default: vue.withCtx(() => [
@@ -13381,10 +13618,10 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13381
13618
  ])
13382
13619
  ]),
13383
13620
  vue.createCommentVNode(" Active Sessions "),
13384
- vue.createElementVNode("div", _hoisted_28, [
13385
- vue.createElementVNode("div", _hoisted_29, [
13621
+ vue.createElementVNode("div", _hoisted_33, [
13622
+ vue.createElementVNode("div", _hoisted_34, [
13386
13623
  vue.createElementVNode("div", null, [
13387
- _cache[20] || (_cache[20] = vue.createElementVNode(
13624
+ _cache[22] || (_cache[22] = vue.createElementVNode(
13388
13625
  "h4",
13389
13626
  { class: "font-medium text-gray-900" },
13390
13627
  "Active Sessions",
@@ -13393,7 +13630,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13393
13630
  )),
13394
13631
  vue.createElementVNode(
13395
13632
  "p",
13396
- _hoisted_30,
13633
+ _hoisted_35,
13397
13634
  vue.toDisplayString($setup.activeSessions.length) + " active device(s)",
13398
13635
  1
13399
13636
  /* TEXT */
@@ -13402,10 +13639,10 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13402
13639
  vue.createVNode($setup["StrandsUiButton"], {
13403
13640
  variant: "secondary",
13404
13641
  size: "sm",
13405
- onClick: _cache[10] || (_cache[10] = ($event) => _ctx.$emit("manage-sessions")),
13642
+ onClick: _cache[11] || (_cache[11] = ($event) => _ctx.$emit("manage-sessions")),
13406
13643
  disabled: ""
13407
13644
  }, {
13408
- default: vue.withCtx(() => _cache[21] || (_cache[21] = [
13645
+ default: vue.withCtx(() => _cache[23] || (_cache[23] = [
13409
13646
  vue.createTextVNode(
13410
13647
  " Coming Soon ",
13411
13648
  -1
@@ -13413,14 +13650,14 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13413
13650
  )
13414
13651
  ])),
13415
13652
  _: 1,
13416
- __: [21]
13653
+ __: [23]
13417
13654
  })
13418
13655
  ])
13419
13656
  ])
13420
13657
  ])
13421
13658
  ]),
13422
13659
  vue.createCommentVNode(" Action Buttons - Only show when changes are made "),
13423
- $setup.hasChanges ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_31, [
13660
+ $setup.hasChanges ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_36, [
13424
13661
  vue.createVNode($setup["StrandsUiButton"], {
13425
13662
  type: "submit",
13426
13663
  variant: "primary",
@@ -13442,7 +13679,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13442
13679
  onClick: $setup.handleCancel,
13443
13680
  disabled: $setup.loading
13444
13681
  }, {
13445
- default: vue.withCtx(() => _cache[23] || (_cache[23] = [
13682
+ default: vue.withCtx(() => _cache[25] || (_cache[25] = [
13446
13683
  vue.createTextVNode(
13447
13684
  " Cancel ",
13448
13685
  -1
@@ -13450,7 +13687,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13450
13687
  )
13451
13688
  ])),
13452
13689
  _: 1,
13453
- __: [23]
13690
+ __: [25]
13454
13691
  }, 8, ["disabled"])
13455
13692
  ])) : vue.createCommentVNode("v-if", true)
13456
13693
  ],
@@ -13458,10 +13695,10 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13458
13695
  /* NEED_HYDRATION */
13459
13696
  ),
13460
13697
  vue.createCommentVNode(" Success/Error Messages "),
13461
- $setup.successMessage ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_32, [
13462
- vue.createElementVNode("div", _hoisted_33, [
13463
- vue.createElementVNode("div", _hoisted_34, [
13464
- _cache[24] || (_cache[24] = vue.createElementVNode(
13698
+ $setup.successMessage ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_37, [
13699
+ vue.createElementVNode("div", _hoisted_38, [
13700
+ vue.createElementVNode("div", _hoisted_39, [
13701
+ _cache[26] || (_cache[26] = vue.createElementVNode(
13465
13702
  "svg",
13466
13703
  {
13467
13704
  class: "w-4 h-4 mt-0.5 flex-shrink-0",
@@ -13480,7 +13717,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13480
13717
  )),
13481
13718
  vue.createElementVNode(
13482
13719
  "p",
13483
- _hoisted_35,
13720
+ _hoisted_40,
13484
13721
  vue.toDisplayString($setup.successMessage),
13485
13722
  1
13486
13723
  /* TEXT */
@@ -13488,10 +13725,10 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13488
13725
  ])
13489
13726
  ])
13490
13727
  ])) : vue.createCommentVNode("v-if", true),
13491
- $setup.errorMessage ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_36, [
13492
- vue.createElementVNode("div", _hoisted_37, [
13493
- vue.createElementVNode("div", _hoisted_38, [
13494
- _cache[25] || (_cache[25] = vue.createElementVNode(
13728
+ $setup.errorMessage ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_41, [
13729
+ vue.createElementVNode("div", _hoisted_42, [
13730
+ vue.createElementVNode("div", _hoisted_43, [
13731
+ _cache[27] || (_cache[27] = vue.createElementVNode(
13495
13732
  "svg",
13496
13733
  {
13497
13734
  class: "w-4 h-4 mt-0.5 flex-shrink-0",
@@ -13510,7 +13747,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13510
13747
  )),
13511
13748
  vue.createElementVNode(
13512
13749
  "p",
13513
- _hoisted_39,
13750
+ _hoisted_44,
13514
13751
  vue.toDisplayString($setup.errorMessage),
13515
13752
  1
13516
13753
  /* TEXT */
@@ -13523,7 +13760,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13523
13760
  config: $setup.props.config
13524
13761
  }, {
13525
13762
  default: vue.withCtx(() => [
13526
- vue.createElementVNode("div", _hoisted_40, [
13763
+ vue.createElementVNode("div", _hoisted_45, [
13527
13764
  vue.createCommentVNode(" Sign Out button "),
13528
13765
  vue.createVNode($setup["StrandsUiButton"], {
13529
13766
  variant: "secondary",
@@ -13545,10 +13782,10 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13545
13782
  vue.createCommentVNode(" Settings button "),
13546
13783
  vue.createVNode($setup["StrandsUiButton"], {
13547
13784
  variant: "secondary",
13548
- onClick: _cache[11] || (_cache[11] = ($event) => $setup.showSettingsModal = true),
13785
+ onClick: _cache[12] || (_cache[12] = ($event) => $setup.showSettingsModal = true),
13549
13786
  class: "w-full sm:w-auto"
13550
13787
  }, {
13551
- default: vue.withCtx(() => _cache[26] || (_cache[26] = [
13788
+ default: vue.withCtx(() => _cache[28] || (_cache[28] = [
13552
13789
  vue.createElementVNode(
13553
13790
  "svg",
13554
13791
  {
@@ -13576,13 +13813,13 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13576
13813
  )
13577
13814
  ])),
13578
13815
  _: 1,
13579
- __: [26]
13816
+ __: [28]
13580
13817
  })
13581
13818
  ]),
13582
13819
  vue.createCommentVNode(" Need help "),
13583
- $setup.getSupportEmail() ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_41, [
13584
- vue.createElementVNode("p", _hoisted_42, [
13585
- _cache[28] || (_cache[28] = vue.createTextVNode(
13820
+ $setup.getSupportEmail() ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_46, [
13821
+ vue.createElementVNode("p", _hoisted_47, [
13822
+ _cache[30] || (_cache[30] = vue.createTextVNode(
13586
13823
  " Need help? ",
13587
13824
  -1
13588
13825
  /* CACHED */
@@ -13591,7 +13828,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13591
13828
  variant: "primary",
13592
13829
  href: `mailto:${$setup.getSupportEmail()}`
13593
13830
  }, {
13594
- default: vue.withCtx(() => _cache[27] || (_cache[27] = [
13831
+ default: vue.withCtx(() => _cache[29] || (_cache[29] = [
13595
13832
  vue.createTextVNode(
13596
13833
  " Contact Support ",
13597
13834
  -1
@@ -13599,7 +13836,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13599
13836
  )
13600
13837
  ])),
13601
13838
  _: 1,
13602
- __: [27]
13839
+ __: [29]
13603
13840
  }, 8, ["href"])
13604
13841
  ])
13605
13842
  ])) : vue.createCommentVNode("v-if", true)
@@ -13611,21 +13848,21 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13611
13848
  vue.createCommentVNode(" MFA Management Modal "),
13612
13849
  vue.createVNode($setup["StrandsMfaModal"], {
13613
13850
  show: $setup.showMfaModal,
13614
- onClose: _cache[12] || (_cache[12] = ($event) => $setup.showMfaModal = false),
13851
+ onClose: _cache[13] || (_cache[13] = ($event) => $setup.showMfaModal = false),
13615
13852
  onMfaUpdated: $setup.handleMfaUpdated
13616
13853
  }, null, 8, ["show"]),
13617
13854
  vue.createCommentVNode(" Settings Modal "),
13618
13855
  $setup.showSettingsModal ? (vue.openBlock(), vue.createBlock($setup["StrandsSettingsModal"], {
13619
13856
  key: 0,
13620
- onClose: _cache[13] || (_cache[13] = ($event) => $setup.showSettingsModal = false),
13857
+ onClose: _cache[14] || (_cache[14] = ($event) => $setup.showSettingsModal = false),
13621
13858
  onSettingsUpdated: $setup.handleSettingsUpdated
13622
13859
  })) : vue.createCommentVNode("v-if", true),
13623
13860
  vue.createCommentVNode(" Avatar Editor Modal "),
13624
- $setup.showAvatarEditor ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_43, [
13625
- vue.createElementVNode("div", _hoisted_44, [
13626
- vue.createElementVNode("div", _hoisted_45, [
13861
+ $setup.showAvatarEditor ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_48, [
13862
+ vue.createElementVNode("div", _hoisted_49, [
13863
+ vue.createElementVNode("div", _hoisted_50, [
13627
13864
  vue.createElementVNode("div", { class: "flex items-center justify-between mb-6" }, [
13628
- _cache[31] || (_cache[31] = vue.createElementVNode(
13865
+ _cache[33] || (_cache[33] = vue.createElementVNode(
13629
13866
  "h2",
13630
13867
  { class: "text-xl font-bold text-gray-900" },
13631
13868
  "Edit Avatar",
@@ -13635,7 +13872,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
13635
13872
  vue.createElementVNode("button", {
13636
13873
  onClick: $setup.handleAvatarEditorClose,
13637
13874
  class: "text-gray-400 hover:text-gray-600 transition-colors"
13638
- }, _cache[30] || (_cache[30] = [
13875
+ }, _cache[32] || (_cache[32] = [
13639
13876
  vue.createElementVNode(
13640
13877
  "svg",
13641
13878
  {