|
|
@@ -0,0 +1,1128 @@
|
|
|
+(function () {
|
|
|
+ const res_path = "resources";
|
|
|
+
|
|
|
+ // 默认主题配置(绿色主题)
|
|
|
+ const defaultTheme = {
|
|
|
+ // 主色调
|
|
|
+ primaryColor: "#24EE89",
|
|
|
+ secondaryColor: "#2CD97D",
|
|
|
+ thirdColor: "#00AF78",
|
|
|
+ fourthColor: "#046E55",
|
|
|
+ fiveColor: "#10b981",
|
|
|
+ highlightColor: "#23FD93", // 高亮绿色
|
|
|
+ accentColor: "#08c974", // 强调色
|
|
|
+
|
|
|
+ // 渐变背景
|
|
|
+ backgroundColor: "linear-gradient(to right, #0BAA47, #057B52)",
|
|
|
+ backgroundColor1: "linear-gradient(to right, #10B981, #059669)",
|
|
|
+ backgroundColor2: "linear-gradient(180deg, rgba(12, 89, 70, 0.8), rgba(12, 89, 70, 0) 100%)",
|
|
|
+ activityBgColor: "linear-gradient(180deg, rgb(14, 110, 67),rgb(5, 73, 45) 99.237%)",
|
|
|
+
|
|
|
+ // 按钮颜色
|
|
|
+ buttonColor: "#24EE89",
|
|
|
+ buttonText: "#13171F",
|
|
|
+ buttonGradient: "linear-gradient(90deg, #1FEB85 0%, #7FFE5A 100%)",
|
|
|
+ buttonGray: "#464F50",
|
|
|
+ warningButtonColor: "linear-gradient(to bottom, #f7c61d, #ef9a05)",
|
|
|
+ disabledButtonColor: "linear-gradient(to bottom, #b3b3b3, #939393)",
|
|
|
+ errorButtonColor: "linear-gradient(to bottom, #ff5a6d, #ce1126)",
|
|
|
+ orangeButtonColor: "linear-gradient(179deg, #FEC412 20.1%, #FE871C 46.83%, #FFFB23 78.17%)",
|
|
|
+
|
|
|
+ // 文字颜色
|
|
|
+ textColor: "#E8ECF0",
|
|
|
+ textGrayColor: "#849194",
|
|
|
+ textGrayColor1: "#B3BEC1",
|
|
|
+ textLightColor: "#f9f5ef", // 米白文字
|
|
|
+
|
|
|
+ // 背景颜色
|
|
|
+ mainBgColor: "#232626",
|
|
|
+ darkColor: "#323738",
|
|
|
+ darkColor1: "#3A4142",
|
|
|
+ darkColor2: "#464F50",
|
|
|
+ darkColor3: "#464F50",
|
|
|
+ bodyBgColor: "#232626", // 最深背景
|
|
|
+ pageTitleBg: "#292D2E",
|
|
|
+
|
|
|
+ // 面板/卡片颜色
|
|
|
+ popupBgColor: "#323738",
|
|
|
+ popupGradientColor: "linear-gradient(150deg, rgba(36, 238, 137, 0.20) 0.05%, rgba(0, 0, 0, 0.00) 32.53%), #232626",
|
|
|
+ inputBgColor: "#292D2E", // 输入框背景
|
|
|
+
|
|
|
+ // 边框颜色
|
|
|
+ selectBorderColor: "#24EE89",
|
|
|
+
|
|
|
+ // 状态颜色
|
|
|
+ positiveColor: "#7ED321",
|
|
|
+ negativeColor: "#FF1B44",
|
|
|
+ successColor: "#36EE85", // 成功色
|
|
|
+
|
|
|
+ // 金币/警告颜色
|
|
|
+ warningColor: "#F5D111",
|
|
|
+ moneyColor: "#24EE89",
|
|
|
+ goldColor: "#FFAD4D", // 金色
|
|
|
+ coinColor: "#edc349", // 金币黄
|
|
|
+
|
|
|
+ // 其他
|
|
|
+ linkColor: "#c2ec9d", // 链接色
|
|
|
+ scrollbarColor: "#c4c4c4", // 滚动条色
|
|
|
+
|
|
|
+ moneyGradient: "linear-gradient(180deg, #30FDB8 17.92%, #00A369 91.51%)", //首冲礼包
|
|
|
+
|
|
|
+ // 弹窗专用(新增)
|
|
|
+ titleGradient: "linear-gradient(180deg, #FEC412 0%, #FFFB23 100%)", // WELCOME 标题渐变
|
|
|
+ bonusGradient: "linear-gradient(179deg, #FEC412 20.1%, #FE871C 46.83%, #FFFB23 78.17%)", // Free $10 渐变
|
|
|
+ popupBgFilter: "none", // 弹窗背景图滤镜
|
|
|
+ tabIconFilter: "none", // Tab图标滤镜(默认绿色主题保持红色图标)
|
|
|
+ gameMenuBg: "#232626", // 游戏菜单背景
|
|
|
+ iconAccentColor: "#FF2400", // 图标强调色(双色图标的第二色)
|
|
|
+ };
|
|
|
+
|
|
|
+ // 蓝色主题
|
|
|
+ const blueTheme = {
|
|
|
+ ...defaultTheme,
|
|
|
+ thirdColor: "#0078D4",
|
|
|
+ fourthColor: "#004578",
|
|
|
+ primaryColor: "#00A9FF",
|
|
|
+ secondaryColor: "#0078D4",
|
|
|
+ fiveColor: "#3B82F6",
|
|
|
+ highlightColor: "#60A5FA",
|
|
|
+ accentColor: "#3B82F6",
|
|
|
+ negativeColor: "#2563EB", // 蓝色按钮
|
|
|
+ moneyColor: "#60A5FA", // 蓝色金币文字
|
|
|
+ linkColor: "#93C5FD", // 蓝色链接
|
|
|
+ titleGradient: "linear-gradient(180deg, #60A5FA 0%, #2563EB 100%)",
|
|
|
+ bonusGradient: "linear-gradient(179deg, #60A5FA 20.1%, #3B82F6 46.83%, #93C5FD 78.17%)",
|
|
|
+ tabIconFilter: "hue-rotate(200deg) saturate(1.2)", // 红色转蓝色
|
|
|
+ backgroundColor: "linear-gradient(to right, #1E40AF, #1E3A8A)",
|
|
|
+ backgroundColor1: "linear-gradient(to right, #3B82F6, #2563EB)",
|
|
|
+ buttonColor: "linear-gradient(to bottom, #60A5FA, #2563EB)",
|
|
|
+ buttonGradient: "linear-gradient(90deg, #60A5FA 0%, #2563EB 100%)",
|
|
|
+ activityBgColor: "linear-gradient(180deg, rgb(30, 64, 175),rgb(30, 58, 138) 99.237%)",
|
|
|
+ backgroundColor2: "linear-gradient(180deg, rgba(30, 64, 175, 0.8), rgba(30, 64, 175, 0) 100%)",
|
|
|
+ popupGradientColor: "#0a1929",
|
|
|
+ selectBorderColor: "#60A5FA",
|
|
|
+ gameMenuBg: "linear-gradient(180deg, rgba(30, 64, 175, 0.85) 0%, rgba(15, 32, 90, 0.92) 30%, rgba(0, 0, 0, 0.98) 100%)",
|
|
|
+ iconAccentColor: "#2563EB",
|
|
|
+ };
|
|
|
+
|
|
|
+ // 紫色主题
|
|
|
+ const purpleTheme = {
|
|
|
+ ...defaultTheme,
|
|
|
+ thirdColor: "#7C3AED",
|
|
|
+ fourthColor: "#5B21B6",
|
|
|
+ primaryColor: "#A78BFA",
|
|
|
+ secondaryColor: "#8B5CF6",
|
|
|
+ fiveColor: "#8B5CF6",
|
|
|
+ highlightColor: "#A78BFA",
|
|
|
+ accentColor: "#8B5CF6",
|
|
|
+ negativeColor: "#7C3AED", // 紫色按钮
|
|
|
+ moneyColor: "#A78BFA",
|
|
|
+ linkColor: "#DDD6FE", // 紫色链接
|
|
|
+ titleGradient: "linear-gradient(180deg, #A78BFA 0%, #7C3AED 100%)",
|
|
|
+ bonusGradient: "linear-gradient(179deg, #C4B5FD 20.1%, #8B5CF6 46.83%, #DDD6FE 78.17%)",
|
|
|
+ tabIconFilter: "hue-rotate(270deg) saturate(1.2)", // 红色转紫色
|
|
|
+ backgroundColor: "linear-gradient(to right, #5B21B6, #4C1D95)",
|
|
|
+ backgroundColor1: "linear-gradient(to right, #8B5CF6, #7C3AED)",
|
|
|
+ buttonColor: "linear-gradient(to bottom, #A78BFA, #7C3AED)",
|
|
|
+ buttonGradient: "linear-gradient(90deg, #A78BFA 0%, #7C3AED 100%)",
|
|
|
+ activityBgColor: "linear-gradient(180deg, rgb(91, 33, 182),rgb(76, 29, 149) 99.237%)",
|
|
|
+ backgroundColor2: "linear-gradient(180deg, rgba(91, 33, 182, 0.8), rgba(91, 33, 182, 0) 100%)",
|
|
|
+ popupGradientColor: "#1a0a2e",
|
|
|
+ selectBorderColor: "#A78BFA",
|
|
|
+ gameMenuBg: "linear-gradient(180deg, rgba(91, 33, 182, 0.85) 0%, rgba(45, 16, 91, 0.92) 30%, rgba(0, 0, 0, 0.98) 100%)",
|
|
|
+ iconAccentColor: "#7C3AED",
|
|
|
+ };
|
|
|
+
|
|
|
+ // 金色主题
|
|
|
+ const goldTheme = {
|
|
|
+ ...defaultTheme,
|
|
|
+ thirdColor: "#D97706",
|
|
|
+ fourthColor: "#B45309",
|
|
|
+ primaryColor: "#FBBF24",
|
|
|
+ secondaryColor: "#F59E0B",
|
|
|
+ fiveColor: "#F59E0B",
|
|
|
+ highlightColor: "#FBBF24",
|
|
|
+ accentColor: "#F59E0B",
|
|
|
+ negativeColor: "#D97706", // 金色按钮
|
|
|
+ moneyColor: "#FBBF24",
|
|
|
+ linkColor: "#FEF3C7", // 金色链接
|
|
|
+ titleGradient: "linear-gradient(180deg, #FBBF24 0%, #D97706 100%)",
|
|
|
+ bonusGradient: "linear-gradient(179deg, #FDE68A 20.1%, #F59E0B 46.83%, #FEF3C7 78.17%)",
|
|
|
+ tabIconFilter: "hue-rotate(35deg) saturate(1.3)", // 红色转金色
|
|
|
+ backgroundColor: "linear-gradient(to right, #B45309, #92400E)",
|
|
|
+ backgroundColor1: "linear-gradient(to right, #F59E0B, #D97706)",
|
|
|
+ buttonColor: "linear-gradient(to bottom, #FBBF24, #D97706)",
|
|
|
+ buttonGradient: "linear-gradient(90deg, #FBBF24 0%, #D97706 100%)",
|
|
|
+ activityBgColor: "linear-gradient(180deg, rgb(180, 83, 9),rgb(146, 64, 14) 99.237%)",
|
|
|
+ backgroundColor2: "linear-gradient(180deg, rgba(180, 83, 9, 0.8), rgba(180, 83, 9, 0) 100%)",
|
|
|
+ popupGradientColor: "#291a00",
|
|
|
+ selectBorderColor: "#FBBF24",
|
|
|
+ gameMenuBg: "linear-gradient(180deg, rgba(180, 83, 9, 0.85) 0%, rgba(90, 41, 5, 0.92) 30%, rgba(0, 0, 0, 0.98) 100%)",
|
|
|
+ iconAccentColor: "#D97706",
|
|
|
+ };
|
|
|
+
|
|
|
+ // 红色主题
|
|
|
+ const redTheme = {
|
|
|
+ ...defaultTheme,
|
|
|
+ thirdColor: "#DC2626",
|
|
|
+ fourthColor: "#B91C1C",
|
|
|
+ primaryColor: "#F87171",
|
|
|
+ secondaryColor: "#EF4444",
|
|
|
+ fiveColor: "#EF4444",
|
|
|
+ highlightColor: "#F87171",
|
|
|
+ accentColor: "#EF4444",
|
|
|
+ negativeColor: "#DC2626", // 红色按钮
|
|
|
+ moneyColor: "#F87171",
|
|
|
+ linkColor: "#FECACA", // 红色链接
|
|
|
+ titleGradient: "linear-gradient(180deg, #F87171 0%, #DC2626 100%)",
|
|
|
+ bonusGradient: "linear-gradient(179deg, #FCA5A5 20.1%, #EF4444 46.83%, #FECACA 78.17%)",
|
|
|
+ tabIconFilter: "none", // 红色主题保持原色
|
|
|
+ backgroundColor: "linear-gradient(to right, #B91C1C, #991B1B)",
|
|
|
+ backgroundColor1: "linear-gradient(to right, #EF4444, #DC2626)",
|
|
|
+ buttonColor: "linear-gradient(to bottom, #F87171, #DC2626)",
|
|
|
+ buttonGradient: "linear-gradient(90deg, #F87171 0%, #DC2626 100%)",
|
|
|
+ activityBgColor: "linear-gradient(180deg, rgb(185, 28, 28),rgb(153, 27, 27) 99.237%)",
|
|
|
+ backgroundColor2: "linear-gradient(180deg, rgba(185, 28, 28, 0.8), rgba(185, 28, 28, 0) 100%)",
|
|
|
+ popupGradientColor: "#2a0a0a",
|
|
|
+ selectBorderColor: "#F87171",
|
|
|
+ gameMenuBg: "linear-gradient(180deg, rgba(185, 28, 28, 0.85) 0%, rgba(90, 14, 14, 0.92) 30%, rgba(0, 0, 0, 0.98) 100%)",
|
|
|
+ iconAccentColor: "#DC2626",
|
|
|
+ };
|
|
|
+
|
|
|
+ // 橙色主题 (RapidJackpot)
|
|
|
+ const orangeTheme = {
|
|
|
+ ...defaultTheme,
|
|
|
+ thirdColor: "#EA580C",
|
|
|
+ fourthColor: "#C2410C",
|
|
|
+ primaryColor: "#FB923C",
|
|
|
+ secondaryColor: "#F97316",
|
|
|
+ fiveColor: "#F97316",
|
|
|
+ highlightColor: "#FB923C",
|
|
|
+ accentColor: "#F97316",
|
|
|
+ negativeColor: "#EA580C", // 橙色按钮
|
|
|
+ moneyColor: "#FB923C",
|
|
|
+ linkColor: "#FED7AA", // 橙色链接
|
|
|
+ titleGradient: "linear-gradient(180deg, #FB923C 0%, #EA580C 100%)",
|
|
|
+ bonusGradient: "linear-gradient(179deg, #FDBA74 20.1%, #F97316 46.83%, #FED7AA 78.17%)",
|
|
|
+ tabIconFilter: "hue-rotate(15deg) saturate(1.2)", // 红色转橙色
|
|
|
+ backgroundColor: "linear-gradient(to right, #C2410C, #9A3412)",
|
|
|
+ backgroundColor1: "linear-gradient(to right, #F97316, #EA580C)",
|
|
|
+ buttonColor: "linear-gradient(to bottom, #FB923C, #EA580C)",
|
|
|
+ buttonGradient: "linear-gradient(90deg, #FB923C 0%, #EA580C 100%)",
|
|
|
+ activityBgColor: "linear-gradient(180deg, rgb(194, 65, 12),rgb(154, 52, 18) 99.237%)",
|
|
|
+ backgroundColor2: "linear-gradient(180deg, rgba(194, 65, 12, 0.8), rgba(194, 65, 12, 0) 100%)",
|
|
|
+ popupGradientColor: "#2a1500",
|
|
|
+ selectBorderColor: "#FB923C",
|
|
|
+ gameMenuBg: "linear-gradient(180deg, rgba(194, 65, 12, 0.85) 0%, rgba(97, 32, 6, 0.92) 30%, rgba(0, 0, 0, 0.98) 100%)",
|
|
|
+ iconAccentColor: "#EA580C",
|
|
|
+ };
|
|
|
+
|
|
|
+ // 青色主题 (CashStorm - 龙卷风蓝绿色)
|
|
|
+ const cyanTheme = {
|
|
|
+ ...defaultTheme,
|
|
|
+ thirdColor: "#0891B2",
|
|
|
+ fourthColor: "#0E7490",
|
|
|
+ primaryColor: "#22D3EE",
|
|
|
+ secondaryColor: "#06B6D4",
|
|
|
+ fiveColor: "#06B6D4",
|
|
|
+ highlightColor: "#22D3EE",
|
|
|
+ accentColor: "#06B6D4",
|
|
|
+ negativeColor: "#0891B2", // 青色按钮
|
|
|
+ moneyColor: "#22D3EE",
|
|
|
+ linkColor: "#A5F3FC", // 青色链接
|
|
|
+ titleGradient: "linear-gradient(180deg, #22D3EE 0%, #0891B2 100%)",
|
|
|
+ bonusGradient: "linear-gradient(179deg, #67E8F9 20.1%, #06B6D4 46.83%, #A5F3FC 78.17%)",
|
|
|
+ tabIconFilter: "hue-rotate(175deg) saturate(1.2)", // 红色转青色
|
|
|
+ backgroundColor: "linear-gradient(to right, #0E7490, #155E75)",
|
|
|
+ backgroundColor1: "linear-gradient(to right, #06B6D4, #0891B2)",
|
|
|
+ buttonColor: "linear-gradient(to bottom, #22D3EE, #0891B2)",
|
|
|
+ buttonGradient: "linear-gradient(90deg, #22D3EE 0%, #0891B2 100%)",
|
|
|
+ activityBgColor: "linear-gradient(180deg, rgb(14, 116, 144),rgb(21, 94, 117) 99.237%)",
|
|
|
+ backgroundColor2: "linear-gradient(180deg, rgba(14, 116, 144, 0.8), rgba(14, 116, 144, 0) 100%)",
|
|
|
+ popupGradientColor: "#0a1f29",
|
|
|
+ selectBorderColor: "#22D3EE",
|
|
|
+ gameMenuBg: "linear-gradient(180deg, rgba(14, 116, 144, 0.85) 0%, rgba(7, 58, 72, 0.92) 30%, rgba(0, 0, 0, 0.98) 100%)",
|
|
|
+ iconAccentColor: "#0891B2",
|
|
|
+ };
|
|
|
+
|
|
|
+ // 亮黄色+红色主题 (RapidJackpot - 火箭速度感)
|
|
|
+ const yellowRedTheme = {
|
|
|
+ ...defaultTheme,
|
|
|
+ thirdColor: "#EAB308", // 黄色
|
|
|
+ fourthColor: "#CA8A04",
|
|
|
+ primaryColor: "#FDE047", // 亮黄色
|
|
|
+ secondaryColor: "#FACC15",
|
|
|
+ fiveColor: "#FACC15",
|
|
|
+ highlightColor: "#FDE047",
|
|
|
+ accentColor: "#FACC15",
|
|
|
+ negativeColor: "#DC2626", // 红色按钮(强调色)
|
|
|
+ moneyColor: "#FDE047",
|
|
|
+ linkColor: "#FEF9C3", // 浅黄色链接
|
|
|
+ titleGradient: "linear-gradient(180deg, #FDE047 0%, #DC2626 100%)",
|
|
|
+ bonusGradient: "linear-gradient(179deg, #FEF08A 20.1%, #FACC15 46.83%, #FEF9C3 78.17%)",
|
|
|
+ tabIconFilter: "hue-rotate(45deg) saturate(1.4)", // 红色转黄色
|
|
|
+ backgroundColor: "linear-gradient(to right, #B91C1C, #CA8A04)",
|
|
|
+ backgroundColor1: "linear-gradient(to right, #FACC15, #EAB308)",
|
|
|
+ buttonColor: "linear-gradient(to bottom, #FDE047, #DC2626)",
|
|
|
+ buttonGradient: "linear-gradient(90deg, #FDE047 0%, #DC2626 100%)",
|
|
|
+ activityBgColor: "linear-gradient(180deg, rgb(185, 28, 28),rgb(202, 138, 4) 99.237%)",
|
|
|
+ backgroundColor2: "linear-gradient(180deg, rgba(202, 138, 4, 0.8), rgba(202, 138, 4, 0) 100%)",
|
|
|
+ popupGradientColor: "#2a1a00",
|
|
|
+ selectBorderColor: "#FDE047",
|
|
|
+ gameMenuBg: "linear-gradient(180deg, rgba(185, 28, 28, 0.85) 0%, rgba(101, 67, 2, 0.92) 30%, rgba(0, 0, 0, 0.98) 100%)",
|
|
|
+ iconAccentColor: "#DC2626",
|
|
|
+ };
|
|
|
+
|
|
|
+ // 橙色+橙红色主题 (JackpotFury - 火焰暴怒)
|
|
|
+ const orangeRedTheme = {
|
|
|
+ ...defaultTheme,
|
|
|
+ thirdColor: "#EA580C", // 深橙色
|
|
|
+ fourthColor: "#C2410C",
|
|
|
+ primaryColor: "#FB923C", // 橙色
|
|
|
+ secondaryColor: "#F97316",
|
|
|
+ fiveColor: "#F97316",
|
|
|
+ highlightColor: "#FDBA14",
|
|
|
+ accentColor: "#F97316",
|
|
|
+ negativeColor: "#DC2626", // 橙红色按钮
|
|
|
+ moneyColor: "#FB923C",
|
|
|
+ linkColor: "#FED7AA", // 浅橙色链接
|
|
|
+ titleGradient: "linear-gradient(180deg, #FB923C 0%, #DC2626 100%)",
|
|
|
+ bonusGradient: "linear-gradient(179deg, #FDBA74 20.1%, #F97316 46.83%, #FED7AA 78.17%)",
|
|
|
+ tabIconFilter: "hue-rotate(10deg) saturate(1.3)", // 保持偏红橙
|
|
|
+ backgroundColor: "linear-gradient(to right, #DC2626, #EA580C)",
|
|
|
+ backgroundColor1: "linear-gradient(to right, #F97316, #EF4444)",
|
|
|
+ buttonColor: "linear-gradient(to bottom, #FB923C, #DC2626)",
|
|
|
+ buttonGradient: "linear-gradient(90deg, #FB923C 0%, #DC2626 100%)",
|
|
|
+ activityBgColor: "linear-gradient(180deg, rgb(220, 38, 38),rgb(234, 88, 12) 99.237%)",
|
|
|
+ backgroundColor2: "linear-gradient(180deg, rgba(220, 38, 38, 0.8), rgba(220, 38, 38, 0) 100%)",
|
|
|
+ popupGradientColor: "#2a0f00",
|
|
|
+ selectBorderColor: "#FB923C",
|
|
|
+ gameMenuBg: "linear-gradient(180deg, rgba(220, 38, 38, 0.85) 0%, rgba(117, 44, 6, 0.92) 30%, rgba(0, 0, 0, 0.98) 100%)",
|
|
|
+ iconAccentColor: "#DC2626",
|
|
|
+ };
|
|
|
+
|
|
|
+ // 红+叶绿混合主题 (WinExplosion - 爆炸多彩彩虹)
|
|
|
+ const explosionTheme = {
|
|
|
+ ...defaultTheme,
|
|
|
+ thirdColor: "#DC2626", // 红色
|
|
|
+ fourthColor: "#22C55E", // 叶绿色
|
|
|
+ primaryColor: "#F87171", // 亮红色
|
|
|
+ secondaryColor: "#22C55E", // 叶绿色
|
|
|
+ fiveColor: "#22C55E",
|
|
|
+ highlightColor: "#22C55E", // 叶绿高亮
|
|
|
+ accentColor: "#EF4444", // 红色强调
|
|
|
+ negativeColor: "#DC2626", // 红色按钮
|
|
|
+ moneyColor: "#4ADE80", // 叶绿金币
|
|
|
+ linkColor: "#86EFAC", // 浅叶绿链接
|
|
|
+ titleGradient: "linear-gradient(90deg, #EF4444 0%, #F97316 20%, #EAB308 40%, #22C55E 60%, #3B82F6 80%, #8B5CF6 100%)",
|
|
|
+ bonusGradient: "linear-gradient(90deg, #FCA5A5 0%, #FDBA74 25%, #FDE047 50%, #86EFAC 75%, #C4B5FD 100%)",
|
|
|
+ tabIconFilter: "none", // 保持红色图标
|
|
|
+ backgroundColor: "linear-gradient(to right, #DC2626, #16A34A)",
|
|
|
+ backgroundColor1: "linear-gradient(to right, #22C55E, #EF4444)",
|
|
|
+ buttonColor: "linear-gradient(to bottom, #F87171, #16A34A)",
|
|
|
+ buttonGradient: "linear-gradient(90deg, #F87171 0%, #16A34A 100%)",
|
|
|
+ activityBgColor: "linear-gradient(180deg, rgb(220, 38, 38),rgb(22, 163, 74) 99.237%)",
|
|
|
+ backgroundColor2: "linear-gradient(180deg, rgba(220, 38, 38, 0.8), rgba(22, 163, 74, 0) 100%)",
|
|
|
+ popupGradientColor: "#0a1f12",
|
|
|
+ selectBorderColor: "#4ADE80",
|
|
|
+ gameMenuBg: "linear-gradient(180deg, rgba(220, 38, 38, 0.85) 0%, rgba(22, 101, 52, 0.92) 30%, rgba(0, 0, 0, 0.98) 100%)",
|
|
|
+ iconAccentColor: "#22C55E",
|
|
|
+ };
|
|
|
+
|
|
|
+ // 玫红色+冷蓝绿色主题 (SlotFrenzy - 狂热冷酷)
|
|
|
+ const purpleTealTheme = {
|
|
|
+ ...defaultTheme,
|
|
|
+ thirdColor: "#DB2777", // 玫红色
|
|
|
+ fourthColor: "#0D9488", // 冷蓝绿色
|
|
|
+ primaryColor: "#F472B6", // 亮玫红
|
|
|
+ secondaryColor: "#14B8A6", // 蓝绿色
|
|
|
+ fiveColor: "#14B8A6",
|
|
|
+ highlightColor: "#2DD4BF", // 蓝绿高亮
|
|
|
+ accentColor: "#EC4899", // 玫红强调
|
|
|
+ negativeColor: "#DB2777", // 玫红按钮
|
|
|
+ moneyColor: "#2DD4BF", // 蓝绿金币
|
|
|
+ linkColor: "#FBCFE8", // 浅玫红链接
|
|
|
+ titleGradient: "linear-gradient(180deg, #F472B6 0%, #14B8A6 100%)",
|
|
|
+ bonusGradient: "linear-gradient(179deg, #FBCFE8 20.1%, #14B8A6 46.83%, #99F6E4 78.17%)",
|
|
|
+ tabIconFilter: "hue-rotate(330deg) saturate(1.3)", // 红色转玫红
|
|
|
+ backgroundColor: "linear-gradient(to right, #BE185D, #0F766E)",
|
|
|
+ backgroundColor1: "linear-gradient(to right, #14B8A6, #EC4899)",
|
|
|
+ buttonColor: "linear-gradient(to bottom, #F472B6, #0D9488)",
|
|
|
+ buttonGradient: "linear-gradient(90deg, #F472B6 0%, #0D9488 100%)",
|
|
|
+ activityBgColor: "linear-gradient(180deg, rgb(190, 24, 93),rgb(15, 118, 110) 99.237%)",
|
|
|
+ backgroundColor2: "linear-gradient(180deg, rgba(190, 24, 93, 0.8), rgba(15, 118, 110, 0) 100%)",
|
|
|
+ popupGradientColor: "#1f0a1a",
|
|
|
+ selectBorderColor: "#2DD4BF",
|
|
|
+ gameMenuBg: "linear-gradient(180deg, rgba(190, 24, 93, 0.85) 0%, rgba(7, 59, 55, 0.92) 30%, rgba(0, 0, 0, 0.98) 100%)",
|
|
|
+ iconAccentColor: "#14B8A6",
|
|
|
+ };
|
|
|
+
|
|
|
+ // 叶绿色+金黄色主题 (LuckyHitNow - 幸运四叶草)
|
|
|
+ const emeraldTheme = {
|
|
|
+ ...defaultTheme,
|
|
|
+ thirdColor: "#16A34A", // 叶绿色
|
|
|
+ fourthColor: "#EAB308", // 金黄色
|
|
|
+ primaryColor: "#22C55E", // 亮叶绿
|
|
|
+ secondaryColor: "#F59E0B", // 琥珀金
|
|
|
+ fiveColor: "#22C55E",
|
|
|
+ highlightColor: "#FBBF24", // 金黄高亮
|
|
|
+ accentColor: "#22C55E", // 叶绿强调
|
|
|
+ negativeColor: "#16A34A", // 叶绿按钮
|
|
|
+ moneyColor: "#FBBF24", // 金黄金币
|
|
|
+ linkColor: "#FEF3C7", // 浅金黄链接
|
|
|
+ titleGradient: "linear-gradient(180deg, #22C55E 0%, #EAB308 100%)",
|
|
|
+ bonusGradient: "linear-gradient(179deg, #86EFAC 20.1%, #FBBF24 46.83%, #FDE68A 78.17%)",
|
|
|
+ tabIconFilter: "hue-rotate(100deg) saturate(1.2)", // 红色转叶绿
|
|
|
+ backgroundColor: "linear-gradient(to right, #15803D, #CA8A04)",
|
|
|
+ backgroundColor1: "linear-gradient(to right, #22C55E, #F59E0B)",
|
|
|
+ buttonColor: "linear-gradient(to bottom, #4ADE80, #EAB308)",
|
|
|
+ buttonGradient: "linear-gradient(90deg, #4ADE80 0%, #EAB308 100%)",
|
|
|
+ activityBgColor: "linear-gradient(180deg, rgb(21, 128, 61),rgb(202, 138, 4) 99.237%)",
|
|
|
+ backgroundColor2: "linear-gradient(180deg, rgba(21, 128, 61, 0.8), rgba(202, 138, 4, 0) 100%)",
|
|
|
+ popupGradientColor: "#0f2a12",
|
|
|
+ selectBorderColor: "#FBBF24",
|
|
|
+ gameMenuBg: "linear-gradient(180deg, rgba(21, 128, 61, 0.85) 0%, rgba(101, 67, 2, 0.92) 30%, rgba(0, 0, 0, 0.98) 100%)",
|
|
|
+ iconAccentColor: "#EAB308",
|
|
|
+ };
|
|
|
+ // ═══════════════════════════════════════════════════════
|
|
|
+ // 区域配置(Region Config)
|
|
|
+ // 每个品牌站点通过 "region" 字段引用对应的区域配置
|
|
|
+ // 区域配置包含:可用语言、默认语言、API、电话区号、货币、时区等
|
|
|
+ // ═══════════════════════════════════════════════════════
|
|
|
+ const regions = {
|
|
|
+ // 美国区域(默认区域)
|
|
|
+ // languages / defaultLang 使用完整 BCP47 locale(en-US vs en-GB、pt-BR vs pt-PT 等),消除歧义
|
|
|
+ "us": {
|
|
|
+ "code": "us",
|
|
|
+ "countryCode": "US",
|
|
|
+ "locale": "en-US",
|
|
|
+ "languages": ["en-US", "es-MX"],
|
|
|
+ "defaultLang": "en-US",
|
|
|
+ "api": "https://us2api.uswinslots.com/",
|
|
|
+ "apiHost": "api1.usvip.org",
|
|
|
+ "ws": "wss://us2api.uswinslots.com:10000",
|
|
|
+ "wsPort": 10000,
|
|
|
+ "phoneCode": "+1",
|
|
|
+ "currency": "USD",
|
|
|
+ "currencySymbol": "$",
|
|
|
+ "timezone": "America/New_York",
|
|
|
+ "dateFormat": "MM/DD/YYYY",
|
|
|
+ "numberFormat": "en-US",
|
|
|
+ "supportEmailDomain": "lionhalo.com",
|
|
|
+ "titleSuffix": "Online Slots & Real Money Games"
|
|
|
+ },
|
|
|
+ // ========== 品牌站点配置 ==========
|
|
|
+ // 巴西区域
|
|
|
+ "br": {
|
|
|
+ "code": "br",
|
|
|
+ "countryCode": "BR",
|
|
|
+ "locale": "pt-BR",
|
|
|
+ "languages": ["pt-BR", "en-US"],
|
|
|
+ "defaultLang": "pt-BR",
|
|
|
+ "api": "https://us2api.uswinslots.com/",
|
|
|
+ "apiHost": "brapi.vipsvip.org",
|
|
|
+ "ws": "wss://us2api.uswinslots.com:10000",
|
|
|
+ "wsPort": 10000,
|
|
|
+ "phoneCode": "+55",
|
|
|
+ "currency": "BRL",
|
|
|
+ "currencySymbol": "R$",
|
|
|
+ "timezone": "America/Sao_Paulo",
|
|
|
+ "dateFormat": "DD/MM/YYYY",
|
|
|
+ "numberFormat": "pt-BR",
|
|
|
+ "supportEmailDomain": "lionhalo.com",
|
|
|
+ "titleSuffix": "Slots Online & Jogos com Dinheiro Real"
|
|
|
+ },
|
|
|
+ // 墨西哥区域(预留,业务 APP_COUNTRY_CODE.MX)
|
|
|
+ "mx": {
|
|
|
+ "code": "mx",
|
|
|
+ "countryCode": "MX",
|
|
|
+ "locale": "es-MX",
|
|
|
+ "languages": ["es-MX", "en-US"],
|
|
|
+ "defaultLang": "es-MX",
|
|
|
+ "api": "https://us2api.uswinslots.com/",
|
|
|
+ "apiHost": "api1.usvip.org",
|
|
|
+ "ws": "wss://us2api.uswinslots.com:10000",
|
|
|
+ "wsPort": 10000,
|
|
|
+ "phoneCode": "+52",
|
|
|
+ "currency": "MXN",
|
|
|
+ "currencySymbol": "$",
|
|
|
+ "timezone": "America/Mexico_City",
|
|
|
+ "dateFormat": "DD/MM/YYYY",
|
|
|
+ "numberFormat": "es-MX",
|
|
|
+ "titleSuffix": "Tragamonedas Online y Juegos con Dinero Real"
|
|
|
+ },
|
|
|
+ // 俄罗斯区域(预留)
|
|
|
+ "ru": {
|
|
|
+ "code": "ru",
|
|
|
+ "countryCode": "RU",
|
|
|
+ "locale": "ru-RU",
|
|
|
+ "languages": ["ru-RU", "en-US"],
|
|
|
+ "defaultLang": "ru-RU",
|
|
|
+ "api": "https://us2api.uswinslots.com/",
|
|
|
+ "apiHost": "api1.usvip.org",
|
|
|
+ "ws": "wss://us2api.uswinslots.com:10000",
|
|
|
+ "wsPort": 10000,
|
|
|
+ "phoneCode": "+7",
|
|
|
+ "currency": "RUB",
|
|
|
+ "currencySymbol": "₽",
|
|
|
+ "timezone": "Europe/Moscow",
|
|
|
+ "dateFormat": "DD.MM.YYYY",
|
|
|
+ "numberFormat": "ru-RU",
|
|
|
+ "titleSuffix": "Онлайн-слоты и игры на реальные деньги"
|
|
|
+ },
|
|
|
+ // 欧盟区域(预留)
|
|
|
+ // 注意:pt-PT 是葡萄牙本土葡语,与 pt-BR 不同;当前仅有 pt-BR 语言包,如需 pt-PT 需另建 pt_PT.json
|
|
|
+ "eu": {
|
|
|
+ "code": "eu",
|
|
|
+ "countryCode": "EU",
|
|
|
+ "locale": "en-GB",
|
|
|
+ "languages": ["en-GB", "es-ES", "pt-PT"],
|
|
|
+ "defaultLang": "en-GB",
|
|
|
+ "api": "https://us2api.uswinslots.com/",
|
|
|
+ "apiHost": "api1.usvip.org",
|
|
|
+ "ws": "wss://us2api.uswinslots.com:10000",
|
|
|
+ "wsPort": 10000,
|
|
|
+ "phoneCode": "+44",
|
|
|
+ "currency": "EUR",
|
|
|
+ "currencySymbol": "€",
|
|
|
+ "timezone": "Europe/London",
|
|
|
+ "dateFormat": "DD/MM/YYYY",
|
|
|
+ "numberFormat": "en-GB",
|
|
|
+ "titleSuffix": "Online Slots & Real Money Games"
|
|
|
+ }
|
|
|
+ };
|
|
|
+ // 默认区域(site_config 未指定 region 时使用)
|
|
|
+ const DEFAULT_REGION = "us";
|
|
|
+ const sites_config = {
|
|
|
+ "default": {
|
|
|
+ "title": "LinoHalo",
|
|
|
+ "subtitle": "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
|
|
|
+ "product": "lionhalo",
|
|
|
+ "product_id": "1",
|
|
|
+ "logo": `/${res_path}/logos/lionhalo.png`,
|
|
|
+ "icon": `/${res_path}/icons/lionhalo.png`,
|
|
|
+ "favicon": `/${res_path}/favicons/lionhalo.ico`,
|
|
|
+ "res": `/${res_path}/res/default/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+
|
|
|
+ // route66slots.com - 66号公路/复古美式公路,红蓝复古路牌+棕榈树
|
|
|
+ "route66slots": {
|
|
|
+ "title": "Route66Slots",
|
|
|
+ "subtitle": "Cruise the reels on Route 66 — classic slots, endless road, nonstop wins.",
|
|
|
+ "product": "route66slots",
|
|
|
+ "product_id": "2",
|
|
|
+ "logo": `/${res_path}/logos/route66slots.webp`,
|
|
|
+ "icon": `/${res_path}/icons/route66slots.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/route66slots.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+ // outlawslots.com - 亡命之徒/西部通缉,棕黑通缉令+左轮/牛仔帽
|
|
|
+ "outlawslots": {
|
|
|
+ "title": "OutlawSlots",
|
|
|
+ "subtitle": "Play by your own rules — outlaw spins, wild wins, fast payouts.",
|
|
|
+ "product": "outlawslots",
|
|
|
+ "product_id": "3",
|
|
|
+ "logo": `/${res_path}/logos/outlawslots.webp`,
|
|
|
+ "icon": `/${res_path}/icons/outlawslots.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/outlawslots.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+ // cactusslots.com - 仙人掌/沙漠西部,绿色仙人掌+橙色落日
|
|
|
+ "cactusslots": {
|
|
|
+ "title": "CactusSlots",
|
|
|
+ "subtitle": "Wins bloom in the desert — sharp slots, sweet rewards, no dry spells.",
|
|
|
+ "product": "cactusslots",
|
|
|
+ "product_id": "4",
|
|
|
+ "logo": `/${res_path}/logos/cactusslots.webp`,
|
|
|
+ "icon": `/${res_path}/icons/cactusslots.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/cactusslots.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+ // canyonslots.com - 大峡谷/红岩,橙红岩层+峡谷剪影
|
|
|
+ "canyonslots": {
|
|
|
+ "title": "CanyonSlots",
|
|
|
+ "subtitle": "Strike deep for canyon gold — big drops, bigger jackpots, endless thrills.",
|
|
|
+ "product": "canyonslots",
|
|
|
+ "product_id": "5",
|
|
|
+ "logo": `/${res_path}/logos/canyonslots.webp`,
|
|
|
+ "icon": `/${res_path}/icons/canyonslots.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/canyonslots.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+
|
|
|
+ "diamondspin777": {
|
|
|
+ "title": "DiamondSpin777",
|
|
|
+ "subtitle": "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
|
|
|
+ "product": "diamondspin777",
|
|
|
+ "product_id": "6",
|
|
|
+ "logo": `/${res_path}/logos/diamondspin777.webp`,
|
|
|
+ "icon": `/${res_path}/icons/diamondspin777.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/diamondspin777.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+
|
|
|
+ "goldsaloonslots": {
|
|
|
+ "title": "GoldSaloonSlots",
|
|
|
+ "subtitle": "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
|
|
|
+ "product": "goldsaloonslots",
|
|
|
+ "product_id": "7",
|
|
|
+ "logo": `/${res_path}/logos/goldsaloonslots.webp`,
|
|
|
+ "icon": `/${res_path}/icons/goldsaloonslots.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/goldsaloonslots.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+
|
|
|
+ "jackpotvault777": {
|
|
|
+ "title": "JackpotVault777",
|
|
|
+ "subtitle": "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
|
|
|
+ "product": "jackpotvault777",
|
|
|
+ "product_id": "8",
|
|
|
+ "logo": `/${res_path}/logos/jackpotvault777.webp`,
|
|
|
+ "icon": `/${res_path}/icons/jackpotvault777.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/jackpotvault777.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+
|
|
|
+ "lucky7parlor": {
|
|
|
+ "title": "Lucky7Parlor",
|
|
|
+ "subtitle": "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
|
|
|
+ "product": "lucky7parlor",
|
|
|
+ "product_id": "9",
|
|
|
+ "logo": `/${res_path}/logos/lucky7parlor.webp`,
|
|
|
+ "icon": `/${res_path}/icons/lucky7parlor.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/lucky7parlor.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+
|
|
|
+ "prairieslots": {
|
|
|
+ "title": "PrairieSlots",
|
|
|
+ "subtitle": "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
|
|
|
+ "product": "prairieslots",
|
|
|
+ "product_id": "10",
|
|
|
+ "logo": `/${res_path}/logos/prairieslots.webp`,
|
|
|
+ "icon": `/${res_path}/icons/prairieslots.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/prairieslots.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+
|
|
|
+ "reelparlor": {
|
|
|
+ "title": "ReelParlor",
|
|
|
+ "subtitle": "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
|
|
|
+ "product": "reelparlor",
|
|
|
+ "product_id": "11",
|
|
|
+ "logo": `/${res_path}/logos/reelparlor.webp`,
|
|
|
+ "icon": `/${res_path}/icons/reelparlor.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/reelparlor.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+
|
|
|
+ "spinlodge": {
|
|
|
+ "title": "SpinLodge",
|
|
|
+ "subtitle": "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
|
|
|
+ "product": "spinlodge",
|
|
|
+ "product_id": "12",
|
|
|
+ "logo": `/${res_path}/logos/spinlodge.webp`,
|
|
|
+ "icon": `/${res_path}/icons/spinlodge.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/spinlodge.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+
|
|
|
+ "spinranch": {
|
|
|
+ "title": "SpinRanch",
|
|
|
+ "subtitle": "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
|
|
|
+ "product": "spinranch",
|
|
|
+ "product_id": "13",
|
|
|
+ "logo": `/${res_path}/logos/spinranch.webp`,
|
|
|
+ "icon": `/${res_path}/icons/spinranch.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/spinranch.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+
|
|
|
+ "vegasreel777": {
|
|
|
+ "title": "VegasReel777",
|
|
|
+ "subtitle": "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
|
|
|
+ "product": "vegasreel777",
|
|
|
+ "product_id": "14",
|
|
|
+ "logo": `/${res_path}/logos/vegasreel777.webp`,
|
|
|
+ "icon": `/${res_path}/icons/vegasreel777.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/vegasreel777.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+
|
|
|
+ "spinvault777": {
|
|
|
+ "title": "SpinVault777",
|
|
|
+ "subtitle": "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
|
|
|
+ "product": "spinvault777",
|
|
|
+ "product_id": "15",
|
|
|
+ "logo": `/${res_path}/logos/spinvault777.webp`,
|
|
|
+ "icon": `/${res_path}/icons/spinvault777.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/spinvault777.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+
|
|
|
+ "crownspin777": {
|
|
|
+ "title": "CrownSpin777",
|
|
|
+ "subtitle": "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
|
|
|
+ "product": "crownspin777",
|
|
|
+ "product_id": "16",
|
|
|
+ "logo": `/${res_path}/logos/crownspin777.webp`,
|
|
|
+ "icon": `/${res_path}/icons/crownspin777.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/crownspin777.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+
|
|
|
+ "turbospin777": {
|
|
|
+ "title": "TurboSpin777",
|
|
|
+ "subtitle": "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
|
|
|
+ "product": "turbospin777",
|
|
|
+ "product_id": "17",
|
|
|
+ "logo": `/${res_path}/logos/turbospin777.webp`,
|
|
|
+ "icon": `/${res_path}/icons/turbospin777.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/turbospin777.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+
|
|
|
+ "aceslots777": {
|
|
|
+ "title": "AceSlots777",
|
|
|
+ "subtitle": "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
|
|
|
+ "product": "aceslots777",
|
|
|
+ "product_id": "18",
|
|
|
+ "logo": `/${res_path}/logos/aceslots777.webp`,
|
|
|
+ "icon": `/${res_path}/icons/aceslots777.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/aceslots777.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+
|
|
|
+ "megaspinusa": {
|
|
|
+ "title": "MegaSpinUSA",
|
|
|
+ "subtitle": "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
|
|
|
+ "product": "megaspinusa",
|
|
|
+ "product_id": "19",
|
|
|
+ "logo": `/${res_path}/logos/megaspinusa.webp`,
|
|
|
+ "icon": `/${res_path}/icons/megaspinusa.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/megaspinusa.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+
|
|
|
+ "goldenspinusa": {
|
|
|
+ "title": "GoldenSpinUSA",
|
|
|
+ "subtitle": "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
|
|
|
+ "product": "goldenspinusa",
|
|
|
+ "product_id": "20",
|
|
|
+ "logo": `/${res_path}/logos/goldenspinusa.webp`,
|
|
|
+ "icon": `/${res_path}/icons/goldenspinusa.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/goldenspinusa.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ },
|
|
|
+
|
|
|
+ "spinkingusa": {
|
|
|
+ "title": "SpinKingUSA",
|
|
|
+ "subtitle": "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
|
|
|
+ "product": "spinkingusa",
|
|
|
+ "product_id": "14",
|
|
|
+ "logo": `/${res_path}/logos/spinkingusa.webp`,
|
|
|
+ "icon": `/${res_path}/icons/spinkingusa.webp`,
|
|
|
+ "favicon": `/${res_path}/favicons/spinkingusa.ico`,
|
|
|
+ "res": `/${res_path}/res/common/`,
|
|
|
+ "region": "us",
|
|
|
+ "theme": defaultTheme
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /** 从当前 path 解析 s_k_c 前缀(/s_k_c 或 /s_k_c/xxx),无则返回空字符串 */
|
|
|
+ const getPathPrefix = () => {
|
|
|
+ const pathname = window.location.pathname || "";
|
|
|
+ const m = pathname.match(/^\/([a-zA-Z0-9]+)_(\d+)(?:\/.*)?$/);
|
|
|
+ return m ? `/${m[1]}_${m[2]}` : "";
|
|
|
+ };
|
|
|
+ // localStorage 值是加密存储的(helpers.js / push_manager.js localStorageSet,前缀 a6072637)。
|
|
|
+ // index.html 不加载 push_manager.js,没有全局 localStorageGet,必须自带解密才能读出明文。
|
|
|
+ // 解密函数与 dmig.js / helpers.js 一致(密钥 xbd4jl,前缀 a6072637)。
|
|
|
+ const _ENC_HEAD = 'a6072637';
|
|
|
+ const _dmig_decrypt = function (str, pwd) {
|
|
|
+ if (!str || str === '') return '';
|
|
|
+ if (!pwd || pwd === '') pwd = 'xbd4jl';
|
|
|
+ pwd = encodeURIComponent(pwd);
|
|
|
+ if (str.length < 8 || pwd.length <= 0) return '';
|
|
|
+ var prand = '';
|
|
|
+ for (var i = 0; i < pwd.length; i++) prand += pwd.charCodeAt(i).toString();
|
|
|
+ var sPos = Math.floor(prand.length / 5);
|
|
|
+ var mult = parseInt(prand.charAt(sPos) + prand.charAt(sPos * 2) + prand.charAt(sPos * 3) + prand.charAt(sPos * 4) + prand.charAt(sPos * 5));
|
|
|
+ var incr = Math.round(pwd.length / 2);
|
|
|
+ var modu = Math.pow(2, 31) - 1;
|
|
|
+ var salt = parseInt(str.substring(str.length - 8), 16);
|
|
|
+ str = str.substring(0, str.length - 8);
|
|
|
+ prand += salt;
|
|
|
+ while (prand.length > 10) {
|
|
|
+ var left = prand, num = 0;
|
|
|
+ while (left.length > 0) { num += parseInt(left.substring(0, 10)); left = left.substring(10); }
|
|
|
+ prand = num.toString();
|
|
|
+ }
|
|
|
+ prand = (mult * prand + incr) % modu;
|
|
|
+ var encStr = '';
|
|
|
+ for (var i = 0; i < str.length; i += 2) {
|
|
|
+ encStr += String.fromCharCode(parseInt(str.substring(i, i + 2), 16) ^ Math.floor((prand / modu) * 255));
|
|
|
+ prand = (mult * prand + incr) % modu;
|
|
|
+ }
|
|
|
+ return decodeURIComponent(encStr);
|
|
|
+ };
|
|
|
+ const _dmig_decryptVal = function (val) {
|
|
|
+ if (typeof val === 'string' && val.indexOf(_ENC_HEAD) === 0) {
|
|
|
+ try { return _dmig_decrypt(val.substring(_ENC_HEAD.length)); } catch (e) { }
|
|
|
+ }
|
|
|
+ return val;
|
|
|
+ };
|
|
|
+ // 读 localStorage 并解密(密文带 a6072637 前缀;明文原样返回,幂等)
|
|
|
+ const lsGet = (k) => {
|
|
|
+ let v = "";
|
|
|
+ try { v = localStorage.getItem(k) || ""; } catch (e) { v = ""; }
|
|
|
+ return _dmig_decryptVal(v);
|
|
|
+ };
|
|
|
+ // App 运行时 quickSave() 写入的短码 s_k_c(已同步存到后端),无则返回 null
|
|
|
+ const getQuickSaveSKC = () => {
|
|
|
+ const s_k = lsGet("LOCAL_QUICK_SAVE_S_K");
|
|
|
+ const c = lsGet("LOCAL_ACTIVITY_C") || new URLSearchParams(window.location.search || "").get("c") || "";
|
|
|
+ return (s_k && c) ? { s_k, c } : null;
|
|
|
+ };
|
|
|
+ // iOS 安装专用:在页面加载时「预制」一个随机 s_k_c,挂到 window.__pwaPreSkc 并写进 manifest 的 start_url。
|
|
|
+ // 因为 iOS 只在加载时读一次 manifest,必须当时就放进合法的 /{s_k}_{c}/;点 download 时
|
|
|
+ // quickSaveForInstall 会读 window.__pwaPreSkc,按这个预制 s_k 把当前环境存到后端(s_k 不自己生成)。
|
|
|
+ const getInstallSKC = () => {
|
|
|
+ if (window.__pwaPreSkc && window.__pwaPreSkc.s_k) return window.__pwaPreSkc;
|
|
|
+ const CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
|
+ let sk = "";
|
|
|
+ for (let j = 0; j < 9; j++) sk += CHARS.charAt(Math.floor(Math.random() * 62));
|
|
|
+ const c = lsGet("LOCAL_ACTIVITY_C") || new URLSearchParams(window.location.search || "").get("c") || "0";
|
|
|
+ const skc = { s_k: sk, c: String(c) };
|
|
|
+ window.__pwaPreSkc = skc;
|
|
|
+ return skc;
|
|
|
+ };
|
|
|
+ const geyCommonJSON = () => {
|
|
|
+ const origin = window.location.origin;
|
|
|
+ const beginurl = origin + "/";
|
|
|
+ // start_url 的 s_k_c:iOS 用「预制」s_k(写进 manifest,并供 quickSaveForInstall 复用);
|
|
|
+ // 非 iOS 用本地预存的短码 s_k_c,path 仅兜底。
|
|
|
+ const skc = isIOSDevice() ? getInstallSKC() : getQuickSaveSKC();
|
|
|
+ const prefix = skc ? `/${skc.s_k}_${skc.c}` : getPathPrefix();
|
|
|
+ const siteurl = prefix ? origin + prefix + "/" : origin + "/";
|
|
|
+ const lkey = "LOCAL_START_PARAMS";
|
|
|
+ let search = window.location.search;
|
|
|
+ const cleanJumpApkSearch = (value = "") => {
|
|
|
+ if (!value || value === "?") return value || "";
|
|
|
+ try {
|
|
|
+ const params = new URLSearchParams(value.startsWith("?") ? value : `?${value}`);
|
|
|
+ params.delete("jumpapk");
|
|
|
+ const next = params.toString();
|
|
|
+ return next ? `?${next}` : "";
|
|
|
+ } catch (e) {
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ search = cleanJumpApkSearch(search);
|
|
|
+ const params = new URLSearchParams(search);
|
|
|
+ if (params.has("c")) {
|
|
|
+ localStorage.setItem(lkey, search);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ let lsearch = localStorage.getItem(lkey);
|
|
|
+ if (lsearch && lsearch.includes("jumpapk")) {
|
|
|
+ lsearch = cleanJumpApkSearch(lsearch);
|
|
|
+ if (lsearch) localStorage.setItem(lkey, lsearch);
|
|
|
+ else localStorage.removeItem(lkey);
|
|
|
+ }
|
|
|
+ if (lsearch == null && search !== "") localStorage.setItem(lkey, search);
|
|
|
+ search = lsearch || search;
|
|
|
+ }
|
|
|
+ // start_url 带上 launchedfrom=homescreen:PWA 从主屏图标启动时据此识别来源(标记放进启动 URL,而非浏览中的地址栏)
|
|
|
+ const startParams = new URLSearchParams((search || "").replace(/^\?/, ""));
|
|
|
+ startParams.set("launchedfrom", "homescreen");
|
|
|
+ const start_url = siteurl + "?" + startParams.toString();
|
|
|
+ const site_conf = getSiteConfig();
|
|
|
+ const icon_path = site_conf.icon;
|
|
|
+ let dir = "product";
|
|
|
+ if (site_conf.region === "br") dir = "product_br";
|
|
|
+ return {
|
|
|
+ name: '',
|
|
|
+ short_name: '',
|
|
|
+ description: '',
|
|
|
+ id: './',
|
|
|
+ start_url: start_url,
|
|
|
+ scope: './',
|
|
|
+ display: 'standalone',
|
|
|
+ background_color: '#2e303f',
|
|
|
+ theme_color: '#2e303f',
|
|
|
+ icons: [
|
|
|
+ {
|
|
|
+ src: `${beginurl}${icon_path}`,
|
|
|
+ sizes: '192x192',
|
|
|
+ type: 'image/png',
|
|
|
+ purpose: 'any maskable'
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ screenshots: [
|
|
|
+ {
|
|
|
+ src: `${beginurl}/${res_path}/${dir}/wide.webp`,
|
|
|
+ sizes: '600x338',
|
|
|
+ type: 'image/jpg',
|
|
|
+ form_factor: 'wide'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ src: `${beginurl}/${res_path}/${dir}/1.webp`,
|
|
|
+ sizes: '320x585',
|
|
|
+ type: 'image/png'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ src: `${beginurl}/${res_path}/${dir}/2.webp`,
|
|
|
+ sizes: '320x585',
|
|
|
+ type: 'image/png'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ src: `${beginurl}/${res_path}/${dir}/3.webp`,
|
|
|
+ sizes: '320x585',
|
|
|
+ type: 'image/png'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ src: `${beginurl}/${res_path}/${dir}/4.webp`,
|
|
|
+ sizes: '320x585',
|
|
|
+ type: 'image/png'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ src: `${beginurl}/${res_path}/${dir}/5.webp`,
|
|
|
+ sizes: '320x585',
|
|
|
+ type: 'image/png'
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ protocol_handlers: [
|
|
|
+ {
|
|
|
+ protocol: 'web+usslot',
|
|
|
+ url: `${siteurl}?launchedfrom=homescreen&pwaprotocolredirect=%s`
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ };
|
|
|
+ };
|
|
|
+ const getSettings = async () => {
|
|
|
+ const { origin, pathname } = window.location
|
|
|
+
|
|
|
+ // const url = window.location.href.replace(/\blandingpage\d*\.html\b/, 'manifest.json');
|
|
|
+ // const url =origin+pathname.substring(0,pathname.lastIndexOf('/'))+ '/manifest.json'
|
|
|
+ // const response = await fetch(url);
|
|
|
+ // if (!response.ok) {
|
|
|
+ // console.error('获取manifest文件失败!');
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
+ // const content = await response.json();
|
|
|
+ const defaultContent = geyCommonJSON();
|
|
|
+ const settings = Object.assign(defaultContent, {
|
|
|
+ name: window.themeConfig.title,
|
|
|
+ short_name: window.themeConfig.title,
|
|
|
+ description: window.themeConfig.subtitle,
|
|
|
+ lang: window.themeConfig.lang || 'en'
|
|
|
+ });
|
|
|
+ return settings;
|
|
|
+ };
|
|
|
+ const getSitePrefix = () => {
|
|
|
+ const hostname = window.location.hostname;
|
|
|
+ const parts = hostname.split('.');
|
|
|
+ if (parts[0] === "www") parts.shift();
|
|
|
+ return parts[0];
|
|
|
+ }
|
|
|
+ const getSiteConfig = () => {
|
|
|
+ // 按「完整域名(含 TLD)」精确路由:同一主名的不同后缀可指向不同配置。
|
|
|
+ // 表里没有的域名回退到 getSitePrefix()(只取中间那一段),现有品牌域名行为不变。
|
|
|
+ const HOST_ALIAS = {
|
|
|
+ "lionhalo.com": "default", // 主站 → id 1
|
|
|
+ // "usslot777.net": "xxxx", // 以后新后缀照此格式添加一行
|
|
|
+ };
|
|
|
+ const host = location.hostname.replace(/^www\./, "");
|
|
|
+ let prefix = HOST_ALIAS[host] || getSitePrefix();
|
|
|
+ if (location.hostname.includes("localhost")) prefix = "default" // 正式环境删除此行,使用 getSitePrefix() 返回值
|
|
|
+ const conf = sites_config[prefix] || sites_config["default"];
|
|
|
+ // 合并区域配置:site.region → regions[region] → 写回到 site.regionConfig
|
|
|
+ const regionKey = conf.region || DEFAULT_REGION;
|
|
|
+ const regionConf = regions[regionKey] || regions[DEFAULT_REGION];
|
|
|
+ // lang 优先级:site.lang > region.defaultLang
|
|
|
+ conf.region = regionKey;
|
|
|
+ conf.regionConfig = regionConf;
|
|
|
+ conf.lang = conf.lang || regionConf.defaultLang;
|
|
|
+ conf.api = conf.api || regionConf.api;
|
|
|
+ conf.apiHost = conf.apiHost || regionConf.apiHost;
|
|
|
+ conf.ws = conf.ws || regionConf.ws;
|
|
|
+ return conf;
|
|
|
+ }
|
|
|
+ const applyTheme = (theme = {}) => {
|
|
|
+ const root = document.documentElement;
|
|
|
+ if (theme != null) {
|
|
|
+ for (let key in theme) {
|
|
|
+ root.style.setProperty(`--${key}`, theme[key]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * iOS apple-touch-icon 必须是 PNG(webp 会静默失败→退回页面截图)。
|
|
|
+ * 品牌图标是 webp,这里映射到同名 -180.png;默认 icon-512.png 映射到 icon-180.png;
|
|
|
+ * 任何兜底都不会返回 webp。
|
|
|
+ */
|
|
|
+ const getAppleIconHref = () => {
|
|
|
+ const conf = window.themeConfig || {};
|
|
|
+ let href = conf.iconApple || "";
|
|
|
+ if (!href) {
|
|
|
+ const icon = conf.icon || "";
|
|
|
+ if (/\.webp$/i.test(icon)) href = icon.replace(/\.webp$/i, "-180.png");
|
|
|
+ else if (/icon-512\.png$/i.test(icon)) href = icon.replace(/icon-512\.png$/i, "icon-180.png");
|
|
|
+ else href = icon;
|
|
|
+ }
|
|
|
+ if (!href || /\.webp$/i.test(href)) href = `/${res_path}/icons/icon-180.png`;
|
|
|
+ return href;
|
|
|
+ };
|
|
|
+ const applyPageMeta = () => {
|
|
|
+ const lang = window.themeConfig?.lang || 'en';
|
|
|
+ const region = window.themeConfig?.regionConfig;
|
|
|
+ // 设置 html lang 属性(优先使用完整 locale,如 pt-BR)
|
|
|
+ document.documentElement.lang = region?.locale || lang;
|
|
|
+ // 设置页面标题(使用区域配置的标题后缀)
|
|
|
+ if (window.themeConfig?.title) {
|
|
|
+ document.title = `${window.themeConfig.title} | Online Slots & Real Money Games`;
|
|
|
+ window.game_title = window.themeConfig.title;
|
|
|
+ window.pwaTitle = window.themeConfig.title;
|
|
|
+ }
|
|
|
+ // 设置 favicon
|
|
|
+ if (window.themeConfig?.favicon) {
|
|
|
+ let favicon = document.querySelector('link[rel="icon"]');
|
|
|
+ if (favicon) {
|
|
|
+ favicon.href = window.themeConfig.favicon;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // iOS「添加到主屏幕」:图标只认 apple-touch-icon(必须 PNG),名称认 apple-mobile-web-app-title,
|
|
|
+ // 均不读 manifest;缺失时 iOS 用页面截图当图标。这里按品牌注入,幂等可重复执行。
|
|
|
+ const upsertLink = (rel, sizes) => {
|
|
|
+ const sel = `link[rel="${rel}"]` + (sizes ? `[sizes="${sizes}"]` : '');
|
|
|
+ let el = document.querySelector(sel);
|
|
|
+ if (!el) {
|
|
|
+ el = document.createElement('link');
|
|
|
+ el.rel = rel;
|
|
|
+ if (sizes) el.setAttribute('sizes', sizes);
|
|
|
+ document.head.appendChild(el);
|
|
|
+ }
|
|
|
+ return el;
|
|
|
+ };
|
|
|
+ const upsertMeta = (name) => {
|
|
|
+ let el = document.querySelector(`meta[name="${name}"]`);
|
|
|
+ if (!el) {
|
|
|
+ el = document.createElement('meta');
|
|
|
+ el.setAttribute('name', name);
|
|
|
+ document.head.appendChild(el);
|
|
|
+ }
|
|
|
+ return el;
|
|
|
+ };
|
|
|
+ const appleIcon = getAppleIconHref();
|
|
|
+ upsertLink('apple-touch-icon', '180x180').href = appleIcon;
|
|
|
+ upsertLink('apple-touch-icon', '').href = appleIcon; // 旧版 iOS 无 sizes 兜底
|
|
|
+ upsertMeta('apple-mobile-web-app-capable').setAttribute('content', 'yes');
|
|
|
+ if (window.themeConfig?.title) {
|
|
|
+ upsertMeta('apple-mobile-web-app-title').setAttribute('content', window.themeConfig.title);
|
|
|
+ }
|
|
|
+ // 设置 og:site_name
|
|
|
+ let ogSiteName = document.querySelector('meta[property="og:site_name"]');
|
|
|
+ if (ogSiteName && window.themeConfig?.title) {
|
|
|
+ ogSiteName.setAttribute('content', window.themeConfig.title);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const initSiteConfig = () => {
|
|
|
+ window.themeConfig = getSiteConfig();
|
|
|
+ applyTheme(window.themeConfig.theme);
|
|
|
+ applyPageMeta();
|
|
|
+ applyInitialLoading();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置首屏 Loading 的 logo 和主题色
|
|
|
+ const applyInitialLoading = () => {
|
|
|
+ const logo = document.getElementById('initial-logo');
|
|
|
+ if (logo && window.themeConfig?.logo) {
|
|
|
+ logo.src = window.themeConfig.logo;
|
|
|
+ }
|
|
|
+ // 更新 loading 圆圈的主题色
|
|
|
+ const loading = document.getElementById('initial-loading');
|
|
|
+ if (loading && window.themeConfig?.theme?.highlightColor) {
|
|
|
+ const spinner = loading.querySelector('div:last-of-type');
|
|
|
+ if (spinner) {
|
|
|
+ spinner.style.borderTopColor = window.themeConfig.theme.highlightColor;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 隐藏首屏 Loading(React 应用加载完成后调用)
|
|
|
+ window.hideInitialLoading = () => {
|
|
|
+ const loading = document.getElementById('initial-loading');
|
|
|
+ if (loading) {
|
|
|
+ loading.style.opacity = '0';
|
|
|
+ loading.style.transition = 'opacity 0.3s ease';
|
|
|
+ setTimeout(() => loading.remove(), 300);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const isIOSDevice = () => {
|
|
|
+ const ua = navigator.userAgent || "";
|
|
|
+ return /iPad|iPhone|iPod/.test(ua) || (navigator.platform === "MacIntel" && (navigator.maxTouchPoints || 0) > 1);
|
|
|
+ };
|
|
|
+ // 构建并注入 data: manifest(全平台)。iOS 只在页面加载时读一次 manifest,故其 start_url 的 s_k_c
|
|
|
+ // 由 getInstallSKC() 在加载时「预制」好写进去(见 geyCommonJSON),点 download 时 quickSaveForInstall
|
|
|
+ // 复用同一预制 s_k 存后端,保证 manifest 与后端一致,首次点击即生效、无需改地址栏或刷新。
|
|
|
+ const buildAndInjectManifest = async () => {
|
|
|
+ const settings = await getSettings();
|
|
|
+ const str = JSON.stringify(settings, null, 2);
|
|
|
+ let i = document.querySelector('link[rel="manifest"]');
|
|
|
+ if (!i) {
|
|
|
+ i = document.createElement('link');
|
|
|
+ i.rel = 'manifest';
|
|
|
+ document.head.appendChild(i);
|
|
|
+ }
|
|
|
+ i.href = 'data:text/json;charset=utf-8,' + encodeURIComponent(str);
|
|
|
+ };
|
|
|
+ // 暴露给 React(非 iOS 用):localStorage 更新后重建 manifest 让 start_url 跟上。
|
|
|
+ window.refreshPwaManifest = buildAndInjectManifest;
|
|
|
+
|
|
|
+ const load = async () => {
|
|
|
+ initSiteConfig();
|
|
|
+ await buildAndInjectManifest();
|
|
|
+ };
|
|
|
+
|
|
|
+ load();
|
|
|
+})();
|