@flamingo-stack/openframe-frontend-core 0.0.406-snapshot.20260711131925 → 0.0.406

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 (135) hide show
  1. package/dist/{chunk-2B6773QM.cjs → chunk-3KEBI6TP.cjs} +1 -1
  2. package/dist/chunk-3KEBI6TP.cjs.map +1 -0
  3. package/dist/{chunk-HJIRG7R6.js → chunk-3KZXOLFK.js} +4 -4
  4. package/dist/{chunk-43H2WOAW.js → chunk-6WMVBCNA.js} +3 -3
  5. package/dist/{chunk-XFP43YKG.js → chunk-7RVSGGO6.js} +6 -6
  6. package/dist/{chunk-KLBEIJVZ.js → chunk-AYFWYOL6.js} +7 -7
  7. package/dist/{chunk-GMZL4T7C.js → chunk-C3NPMZBI.js} +3 -3
  8. package/dist/{chunk-STGWQFYT.cjs → chunk-CCIBZ7TO.cjs} +5 -5
  9. package/dist/chunk-CCIBZ7TO.cjs.map +1 -0
  10. package/dist/{chunk-Q2MC3CBI.cjs → chunk-CF3LBCNI.cjs} +35 -35
  11. package/dist/{chunk-Q2MC3CBI.cjs.map → chunk-CF3LBCNI.cjs.map} +1 -1
  12. package/dist/{chunk-DOBNDDNE.cjs → chunk-COERBDG4.cjs} +75 -75
  13. package/dist/{chunk-DOBNDDNE.cjs.map → chunk-COERBDG4.cjs.map} +1 -1
  14. package/dist/{chunk-7Q52HP45.js → chunk-E6YHDT3D.js} +2 -2
  15. package/dist/chunk-E6YHDT3D.js.map +1 -0
  16. package/dist/{chunk-74FWQI73.cjs → chunk-GNS65HNC.cjs} +18 -18
  17. package/dist/{chunk-74FWQI73.cjs.map → chunk-GNS65HNC.cjs.map} +1 -1
  18. package/dist/{chunk-WCPUJA3Y.cjs → chunk-HJJXNMM7.cjs} +7 -7
  19. package/dist/{chunk-WCPUJA3Y.cjs.map → chunk-HJJXNMM7.cjs.map} +1 -1
  20. package/dist/{chunk-R4MXLJUS.cjs → chunk-ISYVNPRT.cjs} +42 -42
  21. package/dist/{chunk-R4MXLJUS.cjs.map → chunk-ISYVNPRT.cjs.map} +1 -1
  22. package/dist/{chunk-YX7C5JD7.cjs → chunk-JAPP2F4M.cjs} +77 -77
  23. package/dist/{chunk-YX7C5JD7.cjs.map → chunk-JAPP2F4M.cjs.map} +1 -1
  24. package/dist/{chunk-GGDM5J4B.cjs → chunk-LL4QQSAD.cjs} +322 -331
  25. package/dist/chunk-LL4QQSAD.cjs.map +1 -0
  26. package/dist/{chunk-GJSLKATJ.js → chunk-LSPBPUQM.js} +2 -2
  27. package/dist/{chunk-KFQXO7QB.js → chunk-NA7XJRWB.js} +1 -1
  28. package/dist/chunk-NA7XJRWB.js.map +1 -0
  29. package/dist/{chunk-H66L2265.js → chunk-OATWTTCI.js} +6 -6
  30. package/dist/{chunk-LPC3C7MG.cjs → chunk-P43ZHPM6.cjs} +40 -40
  31. package/dist/{chunk-LPC3C7MG.cjs.map → chunk-P43ZHPM6.cjs.map} +1 -1
  32. package/dist/{chunk-NO2KT42M.js → chunk-PNJ5LMVK.js} +10 -9
  33. package/dist/{chunk-NO2KT42M.js.map → chunk-PNJ5LMVK.js.map} +1 -1
  34. package/dist/{chunk-NSF7JUXF.js → chunk-PQN5R5II.js} +7 -7
  35. package/dist/{chunk-CUN4CJUN.cjs → chunk-QAFRLO5N.cjs} +11 -10
  36. package/dist/chunk-QAFRLO5N.cjs.map +1 -0
  37. package/dist/{chunk-LC6RRLFA.cjs → chunk-SF4G7M6U.cjs} +15 -15
  38. package/dist/{chunk-LC6RRLFA.cjs.map → chunk-SF4G7M6U.cjs.map} +1 -1
  39. package/dist/{chunk-CVYSW33D.js → chunk-SOK32D6C.js} +189 -198
  40. package/dist/chunk-SOK32D6C.js.map +1 -0
  41. package/dist/{chunk-4UZH3MT2.js → chunk-TFDNJTBX.js} +4 -4
  42. package/dist/{chunk-5M5W6XDY.cjs → chunk-VANFD4FX.cjs} +7 -7
  43. package/dist/{chunk-5M5W6XDY.cjs.map → chunk-VANFD4FX.cjs.map} +1 -1
  44. package/dist/{chunk-PRKMOF2U.cjs → chunk-VIB4SGCD.cjs} +14 -14
  45. package/dist/{chunk-PRKMOF2U.cjs.map → chunk-VIB4SGCD.cjs.map} +1 -1
  46. package/dist/{chunk-SY3QS2E5.cjs → chunk-VZGU4BV6.cjs} +29 -29
  47. package/dist/{chunk-SY3QS2E5.cjs.map → chunk-VZGU4BV6.cjs.map} +1 -1
  48. package/dist/{chunk-7XVFSGQA.js → chunk-XXG2Z2JT.js} +3 -3
  49. package/dist/{chunk-HB63TQQO.js → chunk-ZVUR3A33.js} +2 -2
  50. package/dist/components/announcement-bar.d.ts.map +1 -1
  51. package/dist/components/case-studies/index.cjs +10 -10
  52. package/dist/components/case-studies/index.js +4 -4
  53. package/dist/components/chat/index.cjs +4 -4
  54. package/dist/components/chat/index.js +3 -3
  55. package/dist/components/contact/index.cjs +5 -5
  56. package/dist/components/contact/index.js +4 -4
  57. package/dist/components/docs/index.cjs +7 -7
  58. package/dist/components/docs/index.js +6 -6
  59. package/dist/components/embeds/index.cjs +5 -5
  60. package/dist/components/embeds/index.js +4 -4
  61. package/dist/components/faq/index.cjs +6 -6
  62. package/dist/components/faq/index.js +5 -5
  63. package/dist/components/features/index.cjs +4 -4
  64. package/dist/components/features/index.js +3 -3
  65. package/dist/components/help-center-pages/index.cjs +23 -23
  66. package/dist/components/help-center-pages/index.js +14 -14
  67. package/dist/components/index.cjs +179 -185
  68. package/dist/components/index.cjs.map +1 -1
  69. package/dist/components/index.js +32 -38
  70. package/dist/components/index.js.map +1 -1
  71. package/dist/components/navigation/index.cjs +4 -4
  72. package/dist/components/navigation/index.js +3 -3
  73. package/dist/components/onboarding-guides/index.cjs +8 -8
  74. package/dist/components/onboarding-guides/index.js +7 -7
  75. package/dist/components/related-content/index.cjs +6 -6
  76. package/dist/components/related-content/index.js +5 -5
  77. package/dist/components/tickets/index.cjs +7 -7
  78. package/dist/components/tickets/index.js +6 -6
  79. package/dist/components/ui/index.cjs +4 -4
  80. package/dist/components/ui/index.js +3 -3
  81. package/dist/contexts/endpoints-runtime-context.d.ts +1 -1
  82. package/dist/contexts/endpoints-runtime-context.d.ts.map +1 -1
  83. package/dist/contexts/index.cjs +2 -2
  84. package/dist/contexts/index.js +1 -1
  85. package/dist/hooks/index.cjs +3 -3
  86. package/dist/hooks/index.js +2 -2
  87. package/dist/hooks/use-self-fetch.d.ts.map +1 -1
  88. package/dist/index.cjs +4 -4
  89. package/dist/index.cjs.map +1 -1
  90. package/dist/index.js +5 -5
  91. package/dist/types/announcement.cjs.map +1 -1
  92. package/dist/types/announcement.d.ts +6 -0
  93. package/dist/types/announcement.d.ts.map +1 -1
  94. package/dist/types/announcement.js.map +1 -1
  95. package/dist/types/index.cjs.map +1 -1
  96. package/dist/types/index.js.map +1 -1
  97. package/dist/utils/announcement-storage.d.ts +0 -3
  98. package/dist/utils/announcement-storage.d.ts.map +1 -1
  99. package/dist/utils/app-config.d.ts.map +1 -1
  100. package/dist/utils/color-analysis.d.ts +4 -0
  101. package/dist/utils/color-analysis.d.ts.map +1 -1
  102. package/dist/utils/index.cjs +177 -186
  103. package/dist/utils/index.cjs.map +1 -1
  104. package/dist/utils/index.js +176 -185
  105. package/dist/utils/index.js.map +1 -1
  106. package/dist/utils/ods-color-utils.d.ts +1 -2
  107. package/dist/utils/ods-color-utils.d.ts.map +1 -1
  108. package/package.json +1 -1
  109. package/src/components/announcement-bar.tsx +21 -38
  110. package/src/contexts/endpoints-runtime-context.tsx +1 -1
  111. package/src/hooks/use-self-fetch.ts +9 -10
  112. package/src/stories/AnnouncementBar.stories.tsx +14 -8
  113. package/src/types/announcement.ts +8 -0
  114. package/src/utils/announcement-storage.ts +0 -17
  115. package/src/utils/app-config.ts +2 -3
  116. package/src/utils/color-analysis.ts +2 -5
  117. package/src/utils/ods-color-utils.ts +7 -4
  118. package/dist/chunk-2B6773QM.cjs.map +0 -1
  119. package/dist/chunk-7Q52HP45.js.map +0 -1
  120. package/dist/chunk-CUN4CJUN.cjs.map +0 -1
  121. package/dist/chunk-CVYSW33D.js.map +0 -1
  122. package/dist/chunk-GGDM5J4B.cjs.map +0 -1
  123. package/dist/chunk-KFQXO7QB.js.map +0 -1
  124. package/dist/chunk-STGWQFYT.cjs.map +0 -1
  125. /package/dist/{chunk-HJIRG7R6.js.map → chunk-3KZXOLFK.js.map} +0 -0
  126. /package/dist/{chunk-43H2WOAW.js.map → chunk-6WMVBCNA.js.map} +0 -0
  127. /package/dist/{chunk-XFP43YKG.js.map → chunk-7RVSGGO6.js.map} +0 -0
  128. /package/dist/{chunk-KLBEIJVZ.js.map → chunk-AYFWYOL6.js.map} +0 -0
  129. /package/dist/{chunk-GMZL4T7C.js.map → chunk-C3NPMZBI.js.map} +0 -0
  130. /package/dist/{chunk-GJSLKATJ.js.map → chunk-LSPBPUQM.js.map} +0 -0
  131. /package/dist/{chunk-H66L2265.js.map → chunk-OATWTTCI.js.map} +0 -0
  132. /package/dist/{chunk-NSF7JUXF.js.map → chunk-PQN5R5II.js.map} +0 -0
  133. /package/dist/{chunk-4UZH3MT2.js.map → chunk-TFDNJTBX.js.map} +0 -0
  134. /package/dist/{chunk-7XVFSGQA.js.map → chunk-XXG2Z2JT.js.map} +0 -0
  135. /package/dist/{chunk-HB63TQQO.js.map → chunk-ZVUR3A33.js.map} +0 -0
@@ -26,7 +26,7 @@ import {
26
26
  useOgPlaceholderUrl,
27
27
  useOnboardingState,
28
28
  useToast
29
- } from "./chunk-7Q52HP45.js";
29
+ } from "./chunk-E6YHDT3D.js";
30
30
  import {
31
31
  AlertCircleIcon,
32
32
  AnthropicLogoGreyIcon,
@@ -150,7 +150,7 @@ import {
150
150
  import {
151
151
  useChatRuntime,
152
152
  useRequiredChatRuntime
153
- } from "./chunk-KFQXO7QB.js";
153
+ } from "./chunk-NA7XJRWB.js";
154
154
  import {
155
155
  dynamic
156
156
  } from "./chunk-EL5YVPD5.js";
@@ -2745,174 +2745,6 @@ function ColorSwatch({ color, className }) {
2745
2745
  // src/components/ui/ticket-status-tag.tsx
2746
2746
  init_cn();
2747
2747
 
2748
- // src/utils/color-analysis.ts
2749
- var DESIGN_PALETTE = [
2750
- { name: "yellow", hex: "#FFC008", rgb: [255, 192, 8] },
2751
- { name: "black", hex: "#161616", rgb: [22, 22, 22] },
2752
- { name: "gray", hex: "#888888", rgb: [136, 136, 136] }
2753
- ];
2754
- function hexToRgb(hex) {
2755
- const normalized = hex.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i, (_, r, g, b) => `${r}${r}${g}${g}${b}${b}`);
2756
- const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(normalized);
2757
- return result ? [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)] : [0, 0, 0];
2758
- }
2759
- function getLuminance(rgb) {
2760
- const [r, g, b] = rgb.map((c) => {
2761
- c = c / 255;
2762
- return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
2763
- });
2764
- return 0.2126 * r + 0.7152 * g + 0.0722 * b;
2765
- }
2766
- function getContrastRatio(color1, color2) {
2767
- const lum1 = getLuminance(color1);
2768
- const lum2 = getLuminance(color2);
2769
- const brightest = Math.max(lum1, lum2);
2770
- const darkest = Math.min(lum1, lum2);
2771
- return (brightest + 0.05) / (darkest + 0.05);
2772
- }
2773
- function pickReadableTextColor(bgHex) {
2774
- const bg = hexToRgb(bgHex);
2775
- const darkContrast = getContrastRatio(bg, [26, 26, 26]);
2776
- const lightContrast = getContrastRatio(bg, [250, 250, 250]);
2777
- return darkContrast >= lightContrast ? "dark" : "light";
2778
- }
2779
- function extractDominantColor(canvas) {
2780
- const ctx = canvas.getContext("2d");
2781
- if (!ctx) return [128, 128, 128];
2782
- const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
2783
- const data = imageData.data;
2784
- const sampleSize = Math.max(1, Math.floor(data.length / (4 * 1e3)));
2785
- const colorCounts = {};
2786
- for (let i = 0; i < data.length; i += 4 * sampleSize) {
2787
- const r = data[i];
2788
- const g = data[i + 1];
2789
- const b = data[i + 2];
2790
- const alpha = data[i + 3];
2791
- if (alpha < 128) continue;
2792
- const bucketR = Math.round(r / 32) * 32;
2793
- const bucketG = Math.round(g / 32) * 32;
2794
- const bucketB = Math.round(b / 32) * 32;
2795
- const key = `${bucketR},${bucketG},${bucketB}`;
2796
- colorCounts[key] = (colorCounts[key] || 0) + 1;
2797
- }
2798
- let maxCount = 0;
2799
- let dominantColor = [128, 128, 128];
2800
- for (const [colorKey, count] of Object.entries(colorCounts)) {
2801
- if (count > maxCount) {
2802
- maxCount = count;
2803
- const [r, g, b] = colorKey.split(",").map(Number);
2804
- dominantColor = [r, g, b];
2805
- }
2806
- }
2807
- return dominantColor;
2808
- }
2809
- function getBestContrastColor(imageColor) {
2810
- let bestColor = DESIGN_PALETTE[0];
2811
- let bestContrast = 0;
2812
- for (const color of DESIGN_PALETTE) {
2813
- const contrast = getContrastRatio(imageColor, color.rgb);
2814
- if (contrast > bestContrast) {
2815
- bestContrast = contrast;
2816
- bestColor = color;
2817
- }
2818
- }
2819
- return bestContrast >= 3 ? bestColor : DESIGN_PALETTE.find((c) => c.name === "black") || bestColor;
2820
- }
2821
- function analyzeImageColor(imageSrc) {
2822
- return new Promise((resolve, reject) => {
2823
- const img = new Image();
2824
- img.crossOrigin = "anonymous";
2825
- img.onload = () => {
2826
- try {
2827
- const canvas = document.createElement("canvas");
2828
- const ctx = canvas.getContext("2d");
2829
- if (!ctx) {
2830
- reject(new Error("Could not get canvas context"));
2831
- return;
2832
- }
2833
- const maxSize = 100;
2834
- const scale = Math.min(maxSize / img.width, maxSize / img.height);
2835
- canvas.width = img.width * scale;
2836
- canvas.height = img.height * scale;
2837
- ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
2838
- const dominantColor = extractDominantColor(canvas);
2839
- const bestContrastColor = getBestContrastColor(dominantColor);
2840
- resolve(bestContrastColor);
2841
- } catch (error) {
2842
- reject(error);
2843
- }
2844
- };
2845
- img.onerror = () => reject(new Error("Failed to load image"));
2846
- img.src = imageSrc;
2847
- });
2848
- }
2849
- async function extractImageEdgeColorAsync(imageUrl) {
2850
- return new Promise((resolve) => {
2851
- if (typeof window === "undefined") {
2852
- resolve("#000000");
2853
- return;
2854
- }
2855
- const img = new Image();
2856
- img.crossOrigin = "anonymous";
2857
- img.onload = () => {
2858
- try {
2859
- const canvas = document.createElement("canvas");
2860
- const ctx = canvas.getContext("2d");
2861
- if (!ctx) {
2862
- resolve("#000000");
2863
- return;
2864
- }
2865
- const maxSize = 50;
2866
- const scale = Math.min(maxSize / img.naturalWidth, maxSize / img.naturalHeight);
2867
- const w = Math.round(img.naturalWidth * scale);
2868
- const h = Math.round(img.naturalHeight * scale);
2869
- canvas.width = w;
2870
- canvas.height = h;
2871
- ctx.drawImage(img, 0, 0, w, h);
2872
- const data = ctx.getImageData(0, 0, w, h).data;
2873
- const edgeW = Math.max(2, Math.round(w * 0.15));
2874
- const edgeH = Math.max(2, Math.round(h * 0.15));
2875
- const bucketSize = 32;
2876
- const buckets = /* @__PURE__ */ new Map();
2877
- for (let y = 0; y < h; y++) {
2878
- for (let x = 0; x < w; x++) {
2879
- if (!(x < edgeW || x >= w - edgeW || y < edgeH || y >= h - edgeH)) continue;
2880
- const i = (y * w + x) * 4;
2881
- if (data[i + 3] < 128) continue;
2882
- const br = Math.floor(data[i] / bucketSize) * bucketSize;
2883
- const bg = Math.floor(data[i + 1] / bucketSize) * bucketSize;
2884
- const bb = Math.floor(data[i + 2] / bucketSize) * bucketSize;
2885
- const key = `${br},${bg},${bb}`;
2886
- const existing = buckets.get(key);
2887
- if (existing) {
2888
- existing.r += data[i];
2889
- existing.g += data[i + 1];
2890
- existing.b += data[i + 2];
2891
- existing.count++;
2892
- } else {
2893
- buckets.set(key, { r: data[i], g: data[i + 1], b: data[i + 2], count: 1 });
2894
- }
2895
- }
2896
- }
2897
- let best = { r: 0, g: 0, b: 0, count: 0 };
2898
- for (const b2 of buckets.values()) {
2899
- if (b2.count > best.count) best = b2;
2900
- }
2901
- if (best.count === 0) {
2902
- resolve("#000000");
2903
- return;
2904
- }
2905
- const r = Math.round(best.r / best.count), g = Math.round(best.g / best.count), b = Math.round(best.b / best.count);
2906
- resolve(`#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`);
2907
- } catch {
2908
- resolve("#000000");
2909
- }
2910
- };
2911
- img.onerror = () => resolve("#000000");
2912
- img.src = imageUrl;
2913
- });
2914
- }
2915
-
2916
2748
  // src/utils/ods-color-utils.ts
2917
2749
  function getPlatformAccentColor(platform) {
2918
2750
  const currentPlatform = platform || getCurrentPlatform();
@@ -2937,13 +2769,18 @@ function getCurrentPlatform() {
2937
2769
  return process.env.NEXT_PUBLIC_APP_TYPE || "openmsp";
2938
2770
  }
2939
2771
  function getReadableTextColor(hex) {
2940
- return pickReadableTextColor(hex) === "dark" ? "#212121" : "#fafafa";
2772
+ const n = parseInt(hex.replace("#", ""), 16);
2773
+ const r = n >> 16 & 255;
2774
+ const g = n >> 8 & 255;
2775
+ const b = n & 255;
2776
+ const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
2777
+ return luminance > 0.5 ? "#212121" : "#fafafa";
2941
2778
  }
2942
2779
  var HEX_PATTERN = /^#[0-9a-fA-F]{6}$/;
2943
2780
  function clamp(n, min, max) {
2944
2781
  return Math.max(min, Math.min(max, n));
2945
2782
  }
2946
- function hexToRgb2(hex) {
2783
+ function hexToRgb(hex) {
2947
2784
  if (!HEX_PATTERN.test(hex)) return null;
2948
2785
  const n = Number.parseInt(hex.slice(1), 16);
2949
2786
  return { r: n >> 16 & 255, g: n >> 8 & 255, b: n & 255 };
@@ -2955,7 +2792,7 @@ function rgbToHex(r, g, b) {
2955
2792
  var HOVER_DARKEN_STEP = 10;
2956
2793
  var ACTIVE_DARKEN_STEP = 20;
2957
2794
  function darkenByStep(hex, step) {
2958
- const rgb = hexToRgb2(hex);
2795
+ const rgb = hexToRgb(hex);
2959
2796
  if (!rgb) return hex;
2960
2797
  return rgbToHex(rgb.r - step, rgb.g - step, rgb.b - step);
2961
2798
  }
@@ -23064,6 +22901,173 @@ function isGenericWebsiteDomain(website) {
23064
22901
  return isGenericDomain(normalizeDomain(website));
23065
22902
  }
23066
22903
 
22904
+ // src/utils/color-analysis.ts
22905
+ var DESIGN_PALETTE = [
22906
+ { name: "yellow", hex: "#FFC008", rgb: [255, 192, 8] },
22907
+ { name: "black", hex: "#161616", rgb: [22, 22, 22] },
22908
+ { name: "gray", hex: "#888888", rgb: [136, 136, 136] }
22909
+ ];
22910
+ function hexToRgb2(hex) {
22911
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
22912
+ return result ? [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)] : [0, 0, 0];
22913
+ }
22914
+ function getLuminance(rgb) {
22915
+ const [r, g, b] = rgb.map((c) => {
22916
+ c = c / 255;
22917
+ return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
22918
+ });
22919
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
22920
+ }
22921
+ function getContrastRatio(color1, color2) {
22922
+ const lum1 = getLuminance(color1);
22923
+ const lum2 = getLuminance(color2);
22924
+ const brightest = Math.max(lum1, lum2);
22925
+ const darkest = Math.min(lum1, lum2);
22926
+ return (brightest + 0.05) / (darkest + 0.05);
22927
+ }
22928
+ function pickReadableTextColor(bgHex) {
22929
+ const bg = hexToRgb2(bgHex);
22930
+ const darkContrast = getContrastRatio(bg, [26, 26, 26]);
22931
+ const lightContrast = getContrastRatio(bg, [250, 250, 250]);
22932
+ return darkContrast >= lightContrast ? "dark" : "light";
22933
+ }
22934
+ function extractDominantColor(canvas) {
22935
+ const ctx = canvas.getContext("2d");
22936
+ if (!ctx) return [128, 128, 128];
22937
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
22938
+ const data = imageData.data;
22939
+ const sampleSize = Math.max(1, Math.floor(data.length / (4 * 1e3)));
22940
+ const colorCounts = {};
22941
+ for (let i = 0; i < data.length; i += 4 * sampleSize) {
22942
+ const r = data[i];
22943
+ const g = data[i + 1];
22944
+ const b = data[i + 2];
22945
+ const alpha = data[i + 3];
22946
+ if (alpha < 128) continue;
22947
+ const bucketR = Math.round(r / 32) * 32;
22948
+ const bucketG = Math.round(g / 32) * 32;
22949
+ const bucketB = Math.round(b / 32) * 32;
22950
+ const key = `${bucketR},${bucketG},${bucketB}`;
22951
+ colorCounts[key] = (colorCounts[key] || 0) + 1;
22952
+ }
22953
+ let maxCount = 0;
22954
+ let dominantColor = [128, 128, 128];
22955
+ for (const [colorKey, count] of Object.entries(colorCounts)) {
22956
+ if (count > maxCount) {
22957
+ maxCount = count;
22958
+ const [r, g, b] = colorKey.split(",").map(Number);
22959
+ dominantColor = [r, g, b];
22960
+ }
22961
+ }
22962
+ return dominantColor;
22963
+ }
22964
+ function getBestContrastColor(imageColor) {
22965
+ let bestColor = DESIGN_PALETTE[0];
22966
+ let bestContrast = 0;
22967
+ for (const color of DESIGN_PALETTE) {
22968
+ const contrast = getContrastRatio(imageColor, color.rgb);
22969
+ if (contrast > bestContrast) {
22970
+ bestContrast = contrast;
22971
+ bestColor = color;
22972
+ }
22973
+ }
22974
+ return bestContrast >= 3 ? bestColor : DESIGN_PALETTE.find((c) => c.name === "black") || bestColor;
22975
+ }
22976
+ function analyzeImageColor(imageSrc) {
22977
+ return new Promise((resolve, reject) => {
22978
+ const img = new Image();
22979
+ img.crossOrigin = "anonymous";
22980
+ img.onload = () => {
22981
+ try {
22982
+ const canvas = document.createElement("canvas");
22983
+ const ctx = canvas.getContext("2d");
22984
+ if (!ctx) {
22985
+ reject(new Error("Could not get canvas context"));
22986
+ return;
22987
+ }
22988
+ const maxSize = 100;
22989
+ const scale = Math.min(maxSize / img.width, maxSize / img.height);
22990
+ canvas.width = img.width * scale;
22991
+ canvas.height = img.height * scale;
22992
+ ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
22993
+ const dominantColor = extractDominantColor(canvas);
22994
+ const bestContrastColor = getBestContrastColor(dominantColor);
22995
+ resolve(bestContrastColor);
22996
+ } catch (error) {
22997
+ reject(error);
22998
+ }
22999
+ };
23000
+ img.onerror = () => reject(new Error("Failed to load image"));
23001
+ img.src = imageSrc;
23002
+ });
23003
+ }
23004
+ async function extractImageEdgeColorAsync(imageUrl) {
23005
+ return new Promise((resolve) => {
23006
+ if (typeof window === "undefined") {
23007
+ resolve("#000000");
23008
+ return;
23009
+ }
23010
+ const img = new Image();
23011
+ img.crossOrigin = "anonymous";
23012
+ img.onload = () => {
23013
+ try {
23014
+ const canvas = document.createElement("canvas");
23015
+ const ctx = canvas.getContext("2d");
23016
+ if (!ctx) {
23017
+ resolve("#000000");
23018
+ return;
23019
+ }
23020
+ const maxSize = 50;
23021
+ const scale = Math.min(maxSize / img.naturalWidth, maxSize / img.naturalHeight);
23022
+ const w = Math.round(img.naturalWidth * scale);
23023
+ const h = Math.round(img.naturalHeight * scale);
23024
+ canvas.width = w;
23025
+ canvas.height = h;
23026
+ ctx.drawImage(img, 0, 0, w, h);
23027
+ const data = ctx.getImageData(0, 0, w, h).data;
23028
+ const edgeW = Math.max(2, Math.round(w * 0.15));
23029
+ const edgeH = Math.max(2, Math.round(h * 0.15));
23030
+ const bucketSize = 32;
23031
+ const buckets = /* @__PURE__ */ new Map();
23032
+ for (let y = 0; y < h; y++) {
23033
+ for (let x = 0; x < w; x++) {
23034
+ if (!(x < edgeW || x >= w - edgeW || y < edgeH || y >= h - edgeH)) continue;
23035
+ const i = (y * w + x) * 4;
23036
+ if (data[i + 3] < 128) continue;
23037
+ const br = Math.floor(data[i] / bucketSize) * bucketSize;
23038
+ const bg = Math.floor(data[i + 1] / bucketSize) * bucketSize;
23039
+ const bb = Math.floor(data[i + 2] / bucketSize) * bucketSize;
23040
+ const key = `${br},${bg},${bb}`;
23041
+ const existing = buckets.get(key);
23042
+ if (existing) {
23043
+ existing.r += data[i];
23044
+ existing.g += data[i + 1];
23045
+ existing.b += data[i + 2];
23046
+ existing.count++;
23047
+ } else {
23048
+ buckets.set(key, { r: data[i], g: data[i + 1], b: data[i + 2], count: 1 });
23049
+ }
23050
+ }
23051
+ }
23052
+ let best = { r: 0, g: 0, b: 0, count: 0 };
23053
+ for (const b2 of buckets.values()) {
23054
+ if (b2.count > best.count) best = b2;
23055
+ }
23056
+ if (best.count === 0) {
23057
+ resolve("#000000");
23058
+ return;
23059
+ }
23060
+ const r = Math.round(best.r / best.count), g = Math.round(best.g / best.count), b = Math.round(best.b / best.count);
23061
+ resolve(`#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`);
23062
+ } catch {
23063
+ resolve("#000000");
23064
+ }
23065
+ };
23066
+ img.onerror = () => resolve("#000000");
23067
+ img.src = imageUrl;
23068
+ });
23069
+ }
23070
+
23067
23071
  // src/utils/announcement-storage.ts
23068
23072
  function announcementDismissCookieName(platform) {
23069
23073
  return `${platform}-announcement-dismissed`;
@@ -23092,19 +23096,6 @@ function isAnnouncementDismissed(platform, id) {
23092
23096
  return false;
23093
23097
  }
23094
23098
  }
23095
- function clearAnnouncementDismissals(platform) {
23096
- if (typeof document === "undefined") return;
23097
- document.cookie = `${announcementDismissCookieName(platform)}=; path=/; max-age=0`;
23098
- try {
23099
- const prefix = `${platform}-announcement-`;
23100
- Object.keys(localStorage).forEach((key) => {
23101
- if (key.startsWith(prefix) && key.endsWith("-dismissed")) {
23102
- localStorage.removeItem(key);
23103
- }
23104
- });
23105
- } catch {
23106
- }
23107
- }
23108
23099
  function clearLegacyAnnouncementCache(platform) {
23109
23100
  if (typeof window === "undefined") return;
23110
23101
  try {
@@ -41867,7 +41858,7 @@ function ChannelInput({
41867
41858
  );
41868
41859
  }
41869
41860
  function RgbInputs({ value, onChange }) {
41870
- const rgb = hexToRgb2(value) ?? { r: 0, g: 0, b: 0 };
41861
+ const rgb = hexToRgb(value) ?? { r: 0, g: 0, b: 0 };
41871
41862
  const update = (next) => {
41872
41863
  const r = next.r ?? rgb.r;
41873
41864
  const g = next.g ?? rgb.g;
@@ -41881,7 +41872,7 @@ function RgbInputs({ value, onChange }) {
41881
41872
  ] });
41882
41873
  }
41883
41874
  function HslInputs({ value, onChange }) {
41884
- const rgb = hexToRgb2(value) ?? { r: 0, g: 0, b: 0 };
41875
+ const rgb = hexToRgb(value) ?? { r: 0, g: 0, b: 0 };
41885
41876
  const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
41886
41877
  const update = (next) => {
41887
41878
  const h = next.h ?? hsl.h;
@@ -52475,18 +52466,11 @@ export {
52475
52466
  ActionsMenu,
52476
52467
  ActionsMenuDropdown,
52477
52468
  ColorSwatch,
52478
- DESIGN_PALETTE,
52479
- getContrastRatio,
52480
- pickReadableTextColor,
52481
- extractDominantColor,
52482
- getBestContrastColor,
52483
- analyzeImageColor,
52484
- extractImageEdgeColorAsync,
52485
52469
  getPlatformAccentColor,
52486
52470
  getCurrentPlatform,
52487
52471
  getReadableTextColor,
52488
52472
  HEX_PATTERN,
52489
- hexToRgb2 as hexToRgb,
52473
+ hexToRgb,
52490
52474
  rgbToHex,
52491
52475
  deriveHoverColor,
52492
52476
  deriveActiveColor,
@@ -53049,11 +53033,18 @@ export {
53049
53033
  isGenericDomain,
53050
53034
  hasGenericEmailDomain,
53051
53035
  isGenericWebsiteDomain,
53036
+ DESIGN_PALETTE,
53037
+ getLuminance,
53038
+ getContrastRatio,
53039
+ pickReadableTextColor,
53040
+ extractDominantColor,
53041
+ getBestContrastColor,
53042
+ analyzeImageColor,
53043
+ extractImageEdgeColorAsync,
53052
53044
  announcementDismissCookieName,
53053
53045
  isDismissedCookieValue,
53054
53046
  dismissAnnouncement,
53055
53047
  isAnnouncementDismissed,
53056
- clearAnnouncementDismissals,
53057
53048
  clearLegacyAnnouncementCache,
53058
53049
  readLeadingDecisionFrame,
53059
53050
  ANNOUNCEMENT_CTA_DEFAULTS,
@@ -53369,4 +53360,4 @@ export {
53369
53360
  LogsList,
53370
53361
  assets
53371
53362
  };
53372
- //# sourceMappingURL=chunk-CVYSW33D.js.map
53363
+ //# sourceMappingURL=chunk-SOK32D6C.js.map