react-os-shell 4.2.2 → 4.3.1

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 (58) hide show
  1. package/README.md +5 -0
  2. package/dist/{Browser-TPAIWPZX.js → Browser-674YMWMK.js} +6 -6
  3. package/dist/{Browser-TPAIWPZX.js.map → Browser-674YMWMK.js.map} +1 -1
  4. package/dist/{Calculator-RCNLBRHK.js → Calculator-3ULKK5ZA.js} +5 -5
  5. package/dist/{Calculator-RCNLBRHK.js.map → Calculator-3ULKK5ZA.js.map} +1 -1
  6. package/dist/ConfirmDialog-XJP67AHR.js +4 -0
  7. package/dist/{ConfirmDialog-QMBUHDXK.js.map → ConfirmDialog-XJP67AHR.js.map} +1 -1
  8. package/dist/{CurrencyConverter-CM5OTXWF.js → CurrencyConverter-JC2N7AY3.js} +5 -5
  9. package/dist/{CurrencyConverter-CM5OTXWF.js.map → CurrencyConverter-JC2N7AY3.js.map} +1 -1
  10. package/dist/{Documents-3BPIAGQT.js → Documents-MJKEUOOL.js} +6 -6
  11. package/dist/{Documents-3BPIAGQT.js.map → Documents-MJKEUOOL.js.map} +1 -1
  12. package/dist/{Files-CR3L5C2L.js → Files-BTZMPTL6.js} +8 -8
  13. package/dist/{Files-CR3L5C2L.js.map → Files-BTZMPTL6.js.map} +1 -1
  14. package/dist/{Notepad-C6JHCCF2.js → Notepad-NGLFEJLA.js} +6 -6
  15. package/dist/{Notepad-C6JHCCF2.js.map → Notepad-NGLFEJLA.js.map} +1 -1
  16. package/dist/{PomodoroTimer-EZMBYLQX.js → PomodoroTimer-RPCRTUKC.js} +6 -6
  17. package/dist/{PomodoroTimer-EZMBYLQX.js.map → PomodoroTimer-RPCRTUKC.js.map} +1 -1
  18. package/dist/{Preview-TFDEMTSH.js → Preview-H4S427VB.js} +6 -6
  19. package/dist/{Preview-TFDEMTSH.js.map → Preview-H4S427VB.js.map} +1 -1
  20. package/dist/{Sidebar-VF2IOOFX.js → Sidebar-E553SOXC.js} +4 -4
  21. package/dist/{Sidebar-VF2IOOFX.js.map → Sidebar-E553SOXC.js.map} +1 -1
  22. package/dist/{Spreadsheet-FRUPALW4.js → Spreadsheet-2YYUKKSY.js} +6 -6
  23. package/dist/{Spreadsheet-FRUPALW4.js.map → Spreadsheet-2YYUKKSY.js.map} +1 -1
  24. package/dist/{Stock-HL42NPTM.js → Stock-YTQ2OYQ7.js} +5 -5
  25. package/dist/{Stock-HL42NPTM.js.map → Stock-YTQ2OYQ7.js.map} +1 -1
  26. package/dist/{Weather-N74AKS6V.js → Weather-4I4EFUJO.js} +5 -5
  27. package/dist/{Weather-N74AKS6V.js.map → Weather-4I4EFUJO.js.map} +1 -1
  28. package/dist/{WorldClock-A2EDB57H.js → WorldClock-7PZI7VRE.js} +5 -5
  29. package/dist/{WorldClock-A2EDB57H.js.map → WorldClock-7PZI7VRE.js.map} +1 -1
  30. package/dist/apps/index.js +18 -18
  31. package/dist/chunk-3NZSR3ZG.js +20 -0
  32. package/dist/chunk-3NZSR3ZG.js.map +1 -0
  33. package/dist/{chunk-RKNJSV2T.js → chunk-ASRXGCSQ.js} +5 -5
  34. package/dist/{chunk-RKNJSV2T.js.map → chunk-ASRXGCSQ.js.map} +1 -1
  35. package/dist/{chunk-6Q4KYGMH.js → chunk-DKDD5KXG.js} +14 -3
  36. package/dist/chunk-DKDD5KXG.js.map +1 -0
  37. package/dist/chunk-K6MB36UJ.js +7 -0
  38. package/dist/{chunk-D36OPVAT.js.map → chunk-K6MB36UJ.js.map} +1 -1
  39. package/dist/{chunk-CWFH34LM.js → chunk-LBY7KH2W.js} +3 -3
  40. package/dist/{chunk-CWFH34LM.js.map → chunk-LBY7KH2W.js.map} +1 -1
  41. package/dist/{chunk-QJXXSMPG.js → chunk-PMPJLVZV.js} +3 -3
  42. package/dist/{chunk-QJXXSMPG.js.map → chunk-PMPJLVZV.js.map} +1 -1
  43. package/dist/{chunk-52RFL3OQ.js → chunk-QAKURGOG.js} +3 -3
  44. package/dist/{chunk-52RFL3OQ.js.map → chunk-QAKURGOG.js.map} +1 -1
  45. package/dist/{chunk-SI4XHEMM.js → chunk-VA6M46NL.js} +242 -13
  46. package/dist/chunk-VA6M46NL.js.map +1 -0
  47. package/dist/{chunk-5TU6DT3E.js → chunk-YF2XNVGN.js} +3 -3
  48. package/dist/{chunk-5TU6DT3E.js.map → chunk-YF2XNVGN.js.map} +1 -1
  49. package/dist/index.d.ts +222 -1
  50. package/dist/index.js +53 -16
  51. package/dist/index.js.map +1 -1
  52. package/package.json +3 -2
  53. package/dist/ConfirmDialog-QMBUHDXK.js +0 -4
  54. package/dist/chunk-6Q4KYGMH.js.map +0 -1
  55. package/dist/chunk-ADJ3CERD.js +0 -31
  56. package/dist/chunk-ADJ3CERD.js.map +0 -1
  57. package/dist/chunk-D36OPVAT.js +0 -7
  58. package/dist/chunk-SI4XHEMM.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/apps/Weather.tsx"],"names":["parts","h","m","t"],"mappings":"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","file":"Weather-N74AKS6V.js","sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { AVAILABLE_CITIES, fetchCityWeather, getCondition, toFahrenheit, type CityWeather } from './_weatherData';\n\nconst STORAGE_KEY = 'weather_city';\nconst LEGACY_KEY = 'weather_cities';\nconst SETTINGS_KEY = 'weather_appearance';\n\ninterface WeatherPrefs { useFahrenheit: boolean; showLocalTime: boolean; use24Hour: boolean }\nconst DEFAULT_PREFS: WeatherPrefs = { useFahrenheit: false, showLocalTime: true, use24Hour: false };\n\nfunction detectLocalCity(): string {\n try {\n const userTz = Intl.DateTimeFormat().resolvedOptions().timeZone;\n for (const [name, info] of Object.entries(AVAILABLE_CITIES)) {\n if (info.tz === userTz) return name;\n }\n } catch {}\n return 'London';\n}\n\nfunction loadCity(): string {\n const v = typeof localStorage !== 'undefined' ? localStorage.getItem(STORAGE_KEY) : null;\n if (v && AVAILABLE_CITIES[v]) return v;\n try {\n const arr = JSON.parse(localStorage.getItem(LEGACY_KEY) || '');\n if (Array.isArray(arr) && arr[0] && AVAILABLE_CITIES[arr[0]]) {\n localStorage.setItem(STORAGE_KEY, arr[0]);\n return arr[0];\n }\n } catch {}\n return detectLocalCity();\n}\n\nconst toF = toFahrenheit;\n\nfunction getTimeInTz(timezone: string, use24Hour = false): string {\n try {\n if (use24Hour) {\n const parts = new Intl.DateTimeFormat('en-US', { timeZone: timezone, hour: 'numeric', minute: '2-digit', hour12: false }).formatToParts(new Date());\n const h = parseInt(parts.find(p => p.type === 'hour')?.value || '0');\n const m = parseInt(parts.find(p => p.type === 'minute')?.value || '0');\n return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`;\n }\n const parts = new Intl.DateTimeFormat('en-US', { timeZone: timezone, hour: 'numeric', minute: '2-digit', hour12: true }).formatToParts(new Date());\n const h = parseInt(parts.find(p => p.type === 'hour')?.value || '12');\n const m = parseInt(parts.find(p => p.type === 'minute')?.value || '0');\n const period = parts.find(p => p.type === 'dayPeriod')?.value || '';\n return `${h}:${String(m).padStart(2, '0')} ${period}`;\n } catch { return ''; }\n}\n\n/**\n * Effect keyframes — tuned for a ~110 px-tall card so drops/flakes fall\n * across the full height before recycling. Multiple snow/rain variants\n * give the impression of independent particles instead of a hypnotic\n * lock-step pattern.\n */\nconst WX_KEYFRAMES = `\n@keyframes wx-rain-a { 0% { transform: translate(0,-20px); opacity: 0; } 10% { opacity: 0.95; } 100% { transform: translate(8px,140px); opacity: 0; } }\n@keyframes wx-rain-b { 0% { transform: translate(0,-20px); opacity: 0; } 12% { opacity: 0.85; } 100% { transform: translate(12px,140px); opacity: 0; } }\n@keyframes wx-rain-c { 0% { transform: translate(0,-20px); opacity: 0; } 10% { opacity: 1; } 100% { transform: translate(5px,140px); opacity: 0; } }\n@keyframes wx-snow-a { 0% { transform: translate(0,-12px) rotate(0deg); opacity: 0; } 10% { opacity: 0.9; } 50% { transform: translate(10px,55px) rotate(180deg); } 100% { transform: translate(-4px,140px) rotate(360deg); opacity: 0; } }\n@keyframes wx-snow-b { 0% { transform: translate(0,-12px) rotate(0deg); opacity: 0; } 10% { opacity: 0.85; } 50% { transform: translate(-12px,55px) rotate(-180deg); } 100% { transform: translate(6px,140px) rotate(-360deg); opacity: 0; } }\n@keyframes wx-snow-c { 0% { transform: translate(0,-12px); opacity: 0; } 10% { opacity: 0.7; } 100% { transform: translate(2px,140px); opacity: 0; } }\n@keyframes wx-drift-cloud { 0% { transform: translateX(-40%); } 100% { transform: translateX(140%); } }\n@keyframes wx-twinkle { 0%, 100% { opacity: 0.25; transform: scale(1); } 50% { opacity: 1; transform: scale(1.6); } }\n@keyframes wx-flash { 0%, 86%, 100% { opacity: 0; } 87% { opacity: 0.95; } 88% { opacity: 0.15; } 89% { opacity: 0.85; } 90% { opacity: 0; } }\n@keyframes wx-bolt { 0%, 86%, 90%, 100% { opacity: 0; } 87% { opacity: 1; } 89% { opacity: 0.85; } }\n@keyframes wx-sun-pulse { 0%, 100% { transform: scale(1); opacity: 0.65; } 50% { transform: scale(1.12); opacity: 0.95; } }\n@keyframes wx-sun-rays { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\n@keyframes wx-fog-drift { 0% { transform: translateX(-25%); opacity: 0.3; } 50% { opacity: 0.65; } 100% { transform: translateX(25%); opacity: 0.3; } }\n@keyframes wx-shooting-star { 0%, 95% { opacity: 0; transform: translate(0,0) scale(0); } 96% { opacity: 1; transform: translate(0,0) scale(1); } 100% { opacity: 0; transform: translate(40px,30px) scale(1); } }\n`;\n\nfunction SunEffect() {\n // Defined yellow-orange disc with halo + slowly-rotating ray sprite.\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n <div className=\"absolute -top-5 -right-5 w-24 h-24\" style={{ animation: 'wx-sun-rays 70s linear infinite' }}>\n <svg viewBox=\"0 0 100 100\" className=\"w-full h-full\">\n {Array.from({ length: 12 }).map((_, i) => (\n <rect key={i} x={49} y={3} width={2} height={14} rx={1}\n fill=\"rgba(255, 232, 130, 0.55)\"\n transform={`rotate(${i * 30} 50 50)`} />\n ))}\n </svg>\n </div>\n <div className=\"absolute top-1 right-1 w-10 h-10 rounded-full\"\n style={{\n background: 'radial-gradient(circle at 35% 35%, #fff8cc 0%, #ffd84a 55%, #ff9e2a 100%)',\n boxShadow: '0 0 18px 5px rgba(255, 200, 80, 0.55)',\n animation: 'wx-sun-pulse 4.5s ease-in-out infinite',\n }} />\n </div>\n );\n}\n\nfunction NightStarsEffect() {\n // Crescent moon (outer warm circle + offset dark circle to carve out the\n // bite) and a sparse scatter of stars twinkling at independent rates.\n // One slow-cycle shooting star adds a moment of motion without\n // distracting.\n const stars = Array.from({ length: 16 }).map((_, i) => ({\n left: `${(i * 53 + 11) % 95}%`,\n top: `${(i * 37 + 9) % 78}%`,\n size: 1 + ((i * 13) % 3),\n delay: `${(i * 0.41) % 4}s`,\n duration: `${2.5 + ((i * 7) % 5) * 0.6}s`,\n }));\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n {/* Crescent moon */}\n <div className=\"absolute top-1 right-1\">\n <svg viewBox=\"0 0 40 40\" className=\"w-9 h-9\" style={{ filter: 'drop-shadow(0 0 6px rgba(255,250,220,0.4))' }}>\n <defs>\n <radialGradient id=\"wx-moon-grad\" cx=\"35%\" cy=\"35%\">\n <stop offset=\"0\" stopColor=\"#fffae0\" />\n <stop offset=\"1\" stopColor=\"#d4c98a\" />\n </radialGradient>\n </defs>\n <circle cx={20} cy={20} r={13} fill=\"url(#wx-moon-grad)\" />\n <circle cx={26} cy={16} r={11} fill=\"rgba(15,23,42,1)\" />\n </svg>\n </div>\n {stars.map((s, i) => (\n <div key={i} className=\"absolute rounded-full bg-white\"\n style={{\n left: s.left, top: s.top, width: s.size, height: s.size,\n animation: `wx-twinkle ${s.duration} ease-in-out ${s.delay} infinite`,\n }} />\n ))}\n {/* Shooting star — appears once every ~12s */}\n <div className=\"absolute\" style={{ left: '15%', top: '20%', animation: 'wx-shooting-star 12s ease-out infinite' }}>\n <div className=\"w-12 h-px\"\n style={{ background: 'linear-gradient(to right, transparent, rgba(255,255,255,0.95))', boxShadow: '0 0 4px rgba(255,255,255,0.8)' }} />\n </div>\n </div>\n );\n}\n\nfunction CloudsEffect({ tone = 'light' as 'light' | 'dark' }) {\n const fill = tone === 'light' ? 'rgba(255,255,255,0.78)' : 'rgba(220,228,240,0.45)';\n const Cloud = ({ scale = 1 }) => (\n <svg viewBox=\"0 0 120 50\" className=\"w-32 h-12\" style={{ transform: `scale(${scale})`, filter: 'blur(0.6px)' }}>\n <ellipse cx={28} cy={36} rx={18} ry={11} fill={fill} />\n <ellipse cx={50} cy={28} rx={22} ry={15} fill={fill} />\n <ellipse cx={75} cy={32} rx={20} ry={12} fill={fill} />\n <ellipse cx={95} cy={38} rx={15} ry={9} fill={fill} />\n </svg>\n );\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n <div className=\"absolute\" style={{ top: '8%', animation: 'wx-drift-cloud 42s linear infinite' }}><Cloud scale={0.9} /></div>\n <div className=\"absolute\" style={{ top: '40%', animation: 'wx-drift-cloud 60s linear -22s infinite', opacity: 0.85 }}><Cloud scale={1.25} /></div>\n <div className=\"absolute\" style={{ top: '68%', animation: 'wx-drift-cloud 78s linear -45s infinite', opacity: 0.7 }}><Cloud scale={0.75} /></div>\n </div>\n );\n}\n\nfunction RainEffect({ heavy = false }: { heavy?: boolean }) {\n const count = heavy ? 26 : 16;\n const variants = ['wx-rain-a', 'wx-rain-b', 'wx-rain-c'];\n const drops = Array.from({ length: count }).map((_, i) => ({\n left: `${(i * 100 / count + (i * 11) % 7) % 100}%`,\n delay: `${(i * 0.087) % 1.3}s`,\n height: `${12 + (i % 4) * 5}px`,\n duration: `${0.7 + (i % 3) * 0.18}s`,\n variant: variants[i % variants.length],\n }));\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n {drops.map((d, i) => (\n <div key={i} className=\"absolute\"\n style={{\n left: d.left, top: '-20px',\n width: '1px', height: d.height,\n background: 'linear-gradient(180deg, rgba(180,210,255,0) 0%, rgba(220,235,255,0.85) 90%, rgba(255,255,255,0.95) 100%)',\n transform: 'rotate(8deg)',\n animation: `${d.variant} ${d.duration} linear ${d.delay} infinite`,\n transformOrigin: 'top',\n }} />\n ))}\n </div>\n );\n}\n\nfunction SnowEffect() {\n const variants = ['wx-snow-a', 'wx-snow-b', 'wx-snow-c'];\n const flakes = Array.from({ length: 16 }).map((_, i) => ({\n left: `${(i * 100 / 16 + (i * 13) % 5) % 100}%`,\n delay: `${(i * 0.43) % 5}s`,\n duration: `${4.5 + (i % 5)}s`,\n size: 3 + (i % 4) * 1.4,\n opacity: 0.65 + ((i * 7) % 4) * 0.08,\n variant: variants[i % variants.length],\n }));\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n {flakes.map((f, i) => (\n <div key={i} className=\"absolute rounded-full bg-white\"\n style={{\n left: f.left, top: '-12px',\n width: f.size, height: f.size,\n opacity: f.opacity,\n boxShadow: '0 0 4px rgba(255,255,255,0.65)',\n animation: `${f.variant} ${f.duration} linear ${f.delay} infinite`,\n }} />\n ))}\n </div>\n );\n}\n\nfunction ThunderEffect() {\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n <RainEffect heavy />\n {/* Sharp double-flash overlay */}\n <div className=\"absolute inset-0 bg-white\" style={{ animation: 'wx-flash 6s ease-out infinite' }} />\n {/* Lightning bolt — visible only during the flash peaks */}\n <div className=\"absolute inset-y-0 right-1/3 flex items-center justify-center pointer-events-none\"\n style={{ animation: 'wx-bolt 6s ease-out infinite' }}>\n <svg viewBox=\"0 0 18 60\" className=\"h-4/5\"\n style={{ filter: 'drop-shadow(0 0 6px rgba(255, 240, 150, 0.95)) drop-shadow(0 0 14px rgba(255, 220, 90, 0.7))' }}>\n <path d=\"M11 0 L2 28 L8 30 L4 60 L16 24 L9 22 Z\"\n fill=\"rgba(255, 250, 200, 0.98)\"\n stroke=\"rgba(255, 255, 255, 0.9)\" strokeWidth={0.3} />\n </svg>\n </div>\n </div>\n );\n}\n\nfunction FogEffect() {\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n {Array.from({ length: 4 }).map((_, i) => (\n <div key={i} className=\"absolute left-0 right-0\"\n style={{\n top: `${10 + i * 22}%`,\n height: '14px',\n background: 'linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.55) 50%, rgba(255,255,255,0) 100%)',\n filter: 'blur(2px)',\n animation: `wx-fog-drift ${10 + i * 3}s ease-in-out ${i * 0.7}s infinite alternate`,\n }} />\n ))}\n </div>\n );\n}\n\nfunction WeatherEffect({ code, isDay }: { code: number; isDay: boolean }) {\n if (code === 0 || code === 1) return isDay ? <SunEffect /> : <NightStarsEffect />;\n if (code === 2) return (\n <>\n {isDay ? <SunEffect /> : <NightStarsEffect />}\n <CloudsEffect tone={isDay ? 'light' : 'dark'} />\n </>\n );\n if (code === 3) return <CloudsEffect tone={isDay ? 'light' : 'dark'} />;\n if (code === 45 || code === 48) return <FogEffect />;\n if ([51, 53, 61, 80, 81].includes(code)) return <RainEffect />;\n if ([55, 63, 65, 82].includes(code)) return <RainEffect heavy />;\n if ([71, 73, 75].includes(code)) return <SnowEffect />;\n if ([95, 96, 99].includes(code)) return <ThunderEffect />;\n return null;\n}\n\nexport default function Weather() {\n const [city, setCity] = useState(loadCity);\n const [appearance, setAppearance] = useState(() => loadAppearance(SETTINGS_KEY));\n const [data, setData] = useState<CityWeather | null>(null);\n const [loading, setLoading] = useState(true);\n const [, setTick] = useState(0);\n useEffect(() => { const t = setInterval(() => setTick(n => n + 1), 60000); return () => clearInterval(t); }, []);\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configCity, setConfigCity] = useState(city);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n\n const { prefs: shellPrefs, save: saveShellPrefs } = useShellPrefs();\n const prefs: WeatherPrefs = { ...DEFAULT_PREFS, ...(shellPrefs.weather_prefs as WeatherPrefs | undefined ?? {}) };\n const [configPrefs, setConfigPrefs] = useState<WeatherPrefs>(prefs);\n\n useWidgetSettings(useCallback(() => {\n setConfigCity(city);\n setConfigAppearance({ ...appearance });\n setConfigPrefs({ ...prefs });\n setSettingsOpen(true);\n }, [city, appearance, prefs]));\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n fetchCityWeather(city).then(w => {\n if (cancelled) return;\n setData(w);\n setLoading(false);\n });\n return () => { cancelled = true; };\n }, [city]);\n\n const saveSettings = () => {\n setCity(configCity);\n setAppearance(configAppearance);\n saveShellPrefs({ weather_prefs: configPrefs });\n localStorage.setItem(STORAGE_KEY, configCity);\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(configAppearance));\n setSettingsOpen(false);\n };\n\n const t = (c: number) => prefs.useFahrenheit ? `${toF(c)}°F` : `${c}°`;\n\n // Half-height — tile is now ~110 px tall. Effect keyframes are tuned for\n // this so drops/flakes traverse the full height before recycling.\n const TILE_HEIGHT = 110;\n\n if (loading && !data) {\n return <div className=\"flex items-center justify-center h-full bg-gradient-to-b from-sky-400 to-blue-500 rounded-lg text-white/80 text-xs\" style={{ minHeight: TILE_HEIGHT }}>Loading…</div>;\n }\n if (!data) {\n return <div className=\"flex items-center justify-center h-full bg-slate-700 rounded-lg text-white/80 text-xs\" style={{ minHeight: TILE_HEIGHT }}>Couldn't load weather</div>;\n }\n\n const [condition, emoji, gradient] = getCondition(data.code, data.isDay);\n\n return (\n <>\n <style>{WX_KEYFRAMES}</style>\n <div className=\"rounded-lg overflow-hidden\"\n style={{\n backgroundColor: `rgba(15, 23, 42, ${appearance.activeOpacity / 100})`,\n backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined,\n }}>\n <div className={`relative rounded-lg overflow-hidden text-white bg-gradient-to-br ${gradient}`} style={{ height: TILE_HEIGHT }}>\n {/* Animated effects */}\n <WeatherEffect code={data.code} isDay={data.isDay} />\n\n {/* Compact two-row content */}\n <div className=\"relative z-10 px-3 py-2.5 flex flex-col h-full justify-between\">\n {/* Top: city + time | temp */}\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-base font-semibold leading-tight truncate drop-shadow-sm\">{data.city}</div>\n {prefs.showLocalTime && (\n <div className=\"text-[10px] opacity-90 leading-tight tabular-nums drop-shadow-sm\">\n {getTimeInTz(data.timezone, prefs.use24Hour)}\n </div>\n )}\n </div>\n <div className=\"text-3xl font-extralight leading-none tracking-tight tabular-nums shrink-0 drop-shadow-sm\">\n {t(data.temp)}\n </div>\n </div>\n\n {/* Bottom: condition | H/L */}\n <div className=\"flex items-end justify-between gap-2\">\n <div className=\"flex items-center gap-1.5 min-w-0\">\n <span className=\"text-lg leading-none drop-shadow-sm\">{emoji}</span>\n <span className=\"text-[11px] font-medium drop-shadow-sm truncate\">{condition}</span>\n </div>\n <span className=\"text-[10px] opacity-90 tabular-nums drop-shadow-sm shrink-0\">H:{t(data.high)} L:{t(data.low)}</span>\n </div>\n </div>\n </div>\n </div>\n\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"Weather Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance} onSave={saveSettings}>\n <div className=\"space-y-3\">\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Display</h3>\n <div className=\"flex items-center gap-3 mb-2\">\n <span className=\"text-sm text-gray-600 w-24\">Temperature</span>\n <div className=\"flex gap-1\">\n {([{ key: false, label: '°C' }, { key: true, label: '°F' }] as const).map(o => (\n <button key={String(o.key)} onClick={() => setConfigPrefs(p => ({ ...p, useFahrenheit: o.key }))}\n className={`px-3 py-1 text-xs font-medium rounded-lg border transition-colors ${configPrefs.useFahrenheit === o.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`}>\n {o.label}\n </button>\n ))}\n </div>\n </div>\n <div className=\"flex items-center gap-3 mb-2\">\n <span className=\"text-sm text-gray-600 w-24\">Time Format</span>\n <div className=\"flex gap-1\">\n {([{ key: false, label: 'AM/PM' }, { key: true, label: '24H' }] as const).map(o => (\n <button key={String(o.key)} onClick={() => setConfigPrefs(p => ({ ...p, use24Hour: o.key }))}\n className={`px-3 py-1 text-xs font-medium rounded-lg border transition-colors ${configPrefs.use24Hour === o.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`}>\n {o.label}\n </button>\n ))}\n </div>\n </div>\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input type=\"checkbox\" checked={configPrefs.showLocalTime} onChange={e => setConfigPrefs(p => ({ ...p, showLocalTime: e.target.checked }))}\n className=\"rounded border-gray-300 text-blue-600 h-3.5 w-3.5\" />\n <span className=\"text-sm text-gray-600\">Show local time</span>\n </label>\n </div>\n </div>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">City</h3>\n <select value={configCity} onChange={e => setConfigCity(e.target.value)}\n className=\"w-full bg-gray-50 border border-gray-200 rounded px-2 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500\">\n {Object.keys(AVAILABLE_CITIES).map(name => (\n <option key={name} value={name}>{name}</option>\n ))}\n </select>\n <p className=\"mt-1 text-[10px] text-gray-400\">Auto-detected from your timezone; change if needed.</p>\n </div>\n </WidgetSettingsModal>\n </>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/apps/Weather.tsx"],"names":["parts","h","m","t"],"mappings":"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","file":"Weather-4I4EFUJO.js","sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { AVAILABLE_CITIES, fetchCityWeather, getCondition, toFahrenheit, type CityWeather } from './_weatherData';\n\nconst STORAGE_KEY = 'weather_city';\nconst LEGACY_KEY = 'weather_cities';\nconst SETTINGS_KEY = 'weather_appearance';\n\ninterface WeatherPrefs { useFahrenheit: boolean; showLocalTime: boolean; use24Hour: boolean }\nconst DEFAULT_PREFS: WeatherPrefs = { useFahrenheit: false, showLocalTime: true, use24Hour: false };\n\nfunction detectLocalCity(): string {\n try {\n const userTz = Intl.DateTimeFormat().resolvedOptions().timeZone;\n for (const [name, info] of Object.entries(AVAILABLE_CITIES)) {\n if (info.tz === userTz) return name;\n }\n } catch {}\n return 'London';\n}\n\nfunction loadCity(): string {\n const v = typeof localStorage !== 'undefined' ? localStorage.getItem(STORAGE_KEY) : null;\n if (v && AVAILABLE_CITIES[v]) return v;\n try {\n const arr = JSON.parse(localStorage.getItem(LEGACY_KEY) || '');\n if (Array.isArray(arr) && arr[0] && AVAILABLE_CITIES[arr[0]]) {\n localStorage.setItem(STORAGE_KEY, arr[0]);\n return arr[0];\n }\n } catch {}\n return detectLocalCity();\n}\n\nconst toF = toFahrenheit;\n\nfunction getTimeInTz(timezone: string, use24Hour = false): string {\n try {\n if (use24Hour) {\n const parts = new Intl.DateTimeFormat('en-US', { timeZone: timezone, hour: 'numeric', minute: '2-digit', hour12: false }).formatToParts(new Date());\n const h = parseInt(parts.find(p => p.type === 'hour')?.value || '0');\n const m = parseInt(parts.find(p => p.type === 'minute')?.value || '0');\n return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`;\n }\n const parts = new Intl.DateTimeFormat('en-US', { timeZone: timezone, hour: 'numeric', minute: '2-digit', hour12: true }).formatToParts(new Date());\n const h = parseInt(parts.find(p => p.type === 'hour')?.value || '12');\n const m = parseInt(parts.find(p => p.type === 'minute')?.value || '0');\n const period = parts.find(p => p.type === 'dayPeriod')?.value || '';\n return `${h}:${String(m).padStart(2, '0')} ${period}`;\n } catch { return ''; }\n}\n\n/**\n * Effect keyframes — tuned for a ~110 px-tall card so drops/flakes fall\n * across the full height before recycling. Multiple snow/rain variants\n * give the impression of independent particles instead of a hypnotic\n * lock-step pattern.\n */\nconst WX_KEYFRAMES = `\n@keyframes wx-rain-a { 0% { transform: translate(0,-20px); opacity: 0; } 10% { opacity: 0.95; } 100% { transform: translate(8px,140px); opacity: 0; } }\n@keyframes wx-rain-b { 0% { transform: translate(0,-20px); opacity: 0; } 12% { opacity: 0.85; } 100% { transform: translate(12px,140px); opacity: 0; } }\n@keyframes wx-rain-c { 0% { transform: translate(0,-20px); opacity: 0; } 10% { opacity: 1; } 100% { transform: translate(5px,140px); opacity: 0; } }\n@keyframes wx-snow-a { 0% { transform: translate(0,-12px) rotate(0deg); opacity: 0; } 10% { opacity: 0.9; } 50% { transform: translate(10px,55px) rotate(180deg); } 100% { transform: translate(-4px,140px) rotate(360deg); opacity: 0; } }\n@keyframes wx-snow-b { 0% { transform: translate(0,-12px) rotate(0deg); opacity: 0; } 10% { opacity: 0.85; } 50% { transform: translate(-12px,55px) rotate(-180deg); } 100% { transform: translate(6px,140px) rotate(-360deg); opacity: 0; } }\n@keyframes wx-snow-c { 0% { transform: translate(0,-12px); opacity: 0; } 10% { opacity: 0.7; } 100% { transform: translate(2px,140px); opacity: 0; } }\n@keyframes wx-drift-cloud { 0% { transform: translateX(-40%); } 100% { transform: translateX(140%); } }\n@keyframes wx-twinkle { 0%, 100% { opacity: 0.25; transform: scale(1); } 50% { opacity: 1; transform: scale(1.6); } }\n@keyframes wx-flash { 0%, 86%, 100% { opacity: 0; } 87% { opacity: 0.95; } 88% { opacity: 0.15; } 89% { opacity: 0.85; } 90% { opacity: 0; } }\n@keyframes wx-bolt { 0%, 86%, 90%, 100% { opacity: 0; } 87% { opacity: 1; } 89% { opacity: 0.85; } }\n@keyframes wx-sun-pulse { 0%, 100% { transform: scale(1); opacity: 0.65; } 50% { transform: scale(1.12); opacity: 0.95; } }\n@keyframes wx-sun-rays { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\n@keyframes wx-fog-drift { 0% { transform: translateX(-25%); opacity: 0.3; } 50% { opacity: 0.65; } 100% { transform: translateX(25%); opacity: 0.3; } }\n@keyframes wx-shooting-star { 0%, 95% { opacity: 0; transform: translate(0,0) scale(0); } 96% { opacity: 1; transform: translate(0,0) scale(1); } 100% { opacity: 0; transform: translate(40px,30px) scale(1); } }\n`;\n\nfunction SunEffect() {\n // Defined yellow-orange disc with halo + slowly-rotating ray sprite.\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n <div className=\"absolute -top-5 -right-5 w-24 h-24\" style={{ animation: 'wx-sun-rays 70s linear infinite' }}>\n <svg viewBox=\"0 0 100 100\" className=\"w-full h-full\">\n {Array.from({ length: 12 }).map((_, i) => (\n <rect key={i} x={49} y={3} width={2} height={14} rx={1}\n fill=\"rgba(255, 232, 130, 0.55)\"\n transform={`rotate(${i * 30} 50 50)`} />\n ))}\n </svg>\n </div>\n <div className=\"absolute top-1 right-1 w-10 h-10 rounded-full\"\n style={{\n background: 'radial-gradient(circle at 35% 35%, #fff8cc 0%, #ffd84a 55%, #ff9e2a 100%)',\n boxShadow: '0 0 18px 5px rgba(255, 200, 80, 0.55)',\n animation: 'wx-sun-pulse 4.5s ease-in-out infinite',\n }} />\n </div>\n );\n}\n\nfunction NightStarsEffect() {\n // Crescent moon (outer warm circle + offset dark circle to carve out the\n // bite) and a sparse scatter of stars twinkling at independent rates.\n // One slow-cycle shooting star adds a moment of motion without\n // distracting.\n const stars = Array.from({ length: 16 }).map((_, i) => ({\n left: `${(i * 53 + 11) % 95}%`,\n top: `${(i * 37 + 9) % 78}%`,\n size: 1 + ((i * 13) % 3),\n delay: `${(i * 0.41) % 4}s`,\n duration: `${2.5 + ((i * 7) % 5) * 0.6}s`,\n }));\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n {/* Crescent moon */}\n <div className=\"absolute top-1 right-1\">\n <svg viewBox=\"0 0 40 40\" className=\"w-9 h-9\" style={{ filter: 'drop-shadow(0 0 6px rgba(255,250,220,0.4))' }}>\n <defs>\n <radialGradient id=\"wx-moon-grad\" cx=\"35%\" cy=\"35%\">\n <stop offset=\"0\" stopColor=\"#fffae0\" />\n <stop offset=\"1\" stopColor=\"#d4c98a\" />\n </radialGradient>\n </defs>\n <circle cx={20} cy={20} r={13} fill=\"url(#wx-moon-grad)\" />\n <circle cx={26} cy={16} r={11} fill=\"rgba(15,23,42,1)\" />\n </svg>\n </div>\n {stars.map((s, i) => (\n <div key={i} className=\"absolute rounded-full bg-white\"\n style={{\n left: s.left, top: s.top, width: s.size, height: s.size,\n animation: `wx-twinkle ${s.duration} ease-in-out ${s.delay} infinite`,\n }} />\n ))}\n {/* Shooting star — appears once every ~12s */}\n <div className=\"absolute\" style={{ left: '15%', top: '20%', animation: 'wx-shooting-star 12s ease-out infinite' }}>\n <div className=\"w-12 h-px\"\n style={{ background: 'linear-gradient(to right, transparent, rgba(255,255,255,0.95))', boxShadow: '0 0 4px rgba(255,255,255,0.8)' }} />\n </div>\n </div>\n );\n}\n\nfunction CloudsEffect({ tone = 'light' as 'light' | 'dark' }) {\n const fill = tone === 'light' ? 'rgba(255,255,255,0.78)' : 'rgba(220,228,240,0.45)';\n const Cloud = ({ scale = 1 }) => (\n <svg viewBox=\"0 0 120 50\" className=\"w-32 h-12\" style={{ transform: `scale(${scale})`, filter: 'blur(0.6px)' }}>\n <ellipse cx={28} cy={36} rx={18} ry={11} fill={fill} />\n <ellipse cx={50} cy={28} rx={22} ry={15} fill={fill} />\n <ellipse cx={75} cy={32} rx={20} ry={12} fill={fill} />\n <ellipse cx={95} cy={38} rx={15} ry={9} fill={fill} />\n </svg>\n );\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n <div className=\"absolute\" style={{ top: '8%', animation: 'wx-drift-cloud 42s linear infinite' }}><Cloud scale={0.9} /></div>\n <div className=\"absolute\" style={{ top: '40%', animation: 'wx-drift-cloud 60s linear -22s infinite', opacity: 0.85 }}><Cloud scale={1.25} /></div>\n <div className=\"absolute\" style={{ top: '68%', animation: 'wx-drift-cloud 78s linear -45s infinite', opacity: 0.7 }}><Cloud scale={0.75} /></div>\n </div>\n );\n}\n\nfunction RainEffect({ heavy = false }: { heavy?: boolean }) {\n const count = heavy ? 26 : 16;\n const variants = ['wx-rain-a', 'wx-rain-b', 'wx-rain-c'];\n const drops = Array.from({ length: count }).map((_, i) => ({\n left: `${(i * 100 / count + (i * 11) % 7) % 100}%`,\n delay: `${(i * 0.087) % 1.3}s`,\n height: `${12 + (i % 4) * 5}px`,\n duration: `${0.7 + (i % 3) * 0.18}s`,\n variant: variants[i % variants.length],\n }));\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n {drops.map((d, i) => (\n <div key={i} className=\"absolute\"\n style={{\n left: d.left, top: '-20px',\n width: '1px', height: d.height,\n background: 'linear-gradient(180deg, rgba(180,210,255,0) 0%, rgba(220,235,255,0.85) 90%, rgba(255,255,255,0.95) 100%)',\n transform: 'rotate(8deg)',\n animation: `${d.variant} ${d.duration} linear ${d.delay} infinite`,\n transformOrigin: 'top',\n }} />\n ))}\n </div>\n );\n}\n\nfunction SnowEffect() {\n const variants = ['wx-snow-a', 'wx-snow-b', 'wx-snow-c'];\n const flakes = Array.from({ length: 16 }).map((_, i) => ({\n left: `${(i * 100 / 16 + (i * 13) % 5) % 100}%`,\n delay: `${(i * 0.43) % 5}s`,\n duration: `${4.5 + (i % 5)}s`,\n size: 3 + (i % 4) * 1.4,\n opacity: 0.65 + ((i * 7) % 4) * 0.08,\n variant: variants[i % variants.length],\n }));\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n {flakes.map((f, i) => (\n <div key={i} className=\"absolute rounded-full bg-white\"\n style={{\n left: f.left, top: '-12px',\n width: f.size, height: f.size,\n opacity: f.opacity,\n boxShadow: '0 0 4px rgba(255,255,255,0.65)',\n animation: `${f.variant} ${f.duration} linear ${f.delay} infinite`,\n }} />\n ))}\n </div>\n );\n}\n\nfunction ThunderEffect() {\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n <RainEffect heavy />\n {/* Sharp double-flash overlay */}\n <div className=\"absolute inset-0 bg-white\" style={{ animation: 'wx-flash 6s ease-out infinite' }} />\n {/* Lightning bolt — visible only during the flash peaks */}\n <div className=\"absolute inset-y-0 right-1/3 flex items-center justify-center pointer-events-none\"\n style={{ animation: 'wx-bolt 6s ease-out infinite' }}>\n <svg viewBox=\"0 0 18 60\" className=\"h-4/5\"\n style={{ filter: 'drop-shadow(0 0 6px rgba(255, 240, 150, 0.95)) drop-shadow(0 0 14px rgba(255, 220, 90, 0.7))' }}>\n <path d=\"M11 0 L2 28 L8 30 L4 60 L16 24 L9 22 Z\"\n fill=\"rgba(255, 250, 200, 0.98)\"\n stroke=\"rgba(255, 255, 255, 0.9)\" strokeWidth={0.3} />\n </svg>\n </div>\n </div>\n );\n}\n\nfunction FogEffect() {\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n {Array.from({ length: 4 }).map((_, i) => (\n <div key={i} className=\"absolute left-0 right-0\"\n style={{\n top: `${10 + i * 22}%`,\n height: '14px',\n background: 'linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.55) 50%, rgba(255,255,255,0) 100%)',\n filter: 'blur(2px)',\n animation: `wx-fog-drift ${10 + i * 3}s ease-in-out ${i * 0.7}s infinite alternate`,\n }} />\n ))}\n </div>\n );\n}\n\nfunction WeatherEffect({ code, isDay }: { code: number; isDay: boolean }) {\n if (code === 0 || code === 1) return isDay ? <SunEffect /> : <NightStarsEffect />;\n if (code === 2) return (\n <>\n {isDay ? <SunEffect /> : <NightStarsEffect />}\n <CloudsEffect tone={isDay ? 'light' : 'dark'} />\n </>\n );\n if (code === 3) return <CloudsEffect tone={isDay ? 'light' : 'dark'} />;\n if (code === 45 || code === 48) return <FogEffect />;\n if ([51, 53, 61, 80, 81].includes(code)) return <RainEffect />;\n if ([55, 63, 65, 82].includes(code)) return <RainEffect heavy />;\n if ([71, 73, 75].includes(code)) return <SnowEffect />;\n if ([95, 96, 99].includes(code)) return <ThunderEffect />;\n return null;\n}\n\nexport default function Weather() {\n const [city, setCity] = useState(loadCity);\n const [appearance, setAppearance] = useState(() => loadAppearance(SETTINGS_KEY));\n const [data, setData] = useState<CityWeather | null>(null);\n const [loading, setLoading] = useState(true);\n const [, setTick] = useState(0);\n useEffect(() => { const t = setInterval(() => setTick(n => n + 1), 60000); return () => clearInterval(t); }, []);\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configCity, setConfigCity] = useState(city);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n\n const { prefs: shellPrefs, save: saveShellPrefs } = useShellPrefs();\n const prefs: WeatherPrefs = { ...DEFAULT_PREFS, ...(shellPrefs.weather_prefs as WeatherPrefs | undefined ?? {}) };\n const [configPrefs, setConfigPrefs] = useState<WeatherPrefs>(prefs);\n\n useWidgetSettings(useCallback(() => {\n setConfigCity(city);\n setConfigAppearance({ ...appearance });\n setConfigPrefs({ ...prefs });\n setSettingsOpen(true);\n }, [city, appearance, prefs]));\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n fetchCityWeather(city).then(w => {\n if (cancelled) return;\n setData(w);\n setLoading(false);\n });\n return () => { cancelled = true; };\n }, [city]);\n\n const saveSettings = () => {\n setCity(configCity);\n setAppearance(configAppearance);\n saveShellPrefs({ weather_prefs: configPrefs });\n localStorage.setItem(STORAGE_KEY, configCity);\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(configAppearance));\n setSettingsOpen(false);\n };\n\n const t = (c: number) => prefs.useFahrenheit ? `${toF(c)}°F` : `${c}°`;\n\n // Half-height — tile is now ~110 px tall. Effect keyframes are tuned for\n // this so drops/flakes traverse the full height before recycling.\n const TILE_HEIGHT = 110;\n\n if (loading && !data) {\n return <div className=\"flex items-center justify-center h-full bg-gradient-to-b from-sky-400 to-blue-500 rounded-lg text-white/80 text-xs\" style={{ minHeight: TILE_HEIGHT }}>Loading…</div>;\n }\n if (!data) {\n return <div className=\"flex items-center justify-center h-full bg-slate-700 rounded-lg text-white/80 text-xs\" style={{ minHeight: TILE_HEIGHT }}>Couldn't load weather</div>;\n }\n\n const [condition, emoji, gradient] = getCondition(data.code, data.isDay);\n\n return (\n <>\n <style>{WX_KEYFRAMES}</style>\n <div className=\"rounded-lg overflow-hidden\"\n style={{\n backgroundColor: `rgba(15, 23, 42, ${appearance.activeOpacity / 100})`,\n backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined,\n }}>\n <div className={`relative rounded-lg overflow-hidden text-white bg-gradient-to-br ${gradient}`} style={{ height: TILE_HEIGHT }}>\n {/* Animated effects */}\n <WeatherEffect code={data.code} isDay={data.isDay} />\n\n {/* Compact two-row content */}\n <div className=\"relative z-10 px-3 py-2.5 flex flex-col h-full justify-between\">\n {/* Top: city + time | temp */}\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-base font-semibold leading-tight truncate drop-shadow-sm\">{data.city}</div>\n {prefs.showLocalTime && (\n <div className=\"text-[10px] opacity-90 leading-tight tabular-nums drop-shadow-sm\">\n {getTimeInTz(data.timezone, prefs.use24Hour)}\n </div>\n )}\n </div>\n <div className=\"text-3xl font-extralight leading-none tracking-tight tabular-nums shrink-0 drop-shadow-sm\">\n {t(data.temp)}\n </div>\n </div>\n\n {/* Bottom: condition | H/L */}\n <div className=\"flex items-end justify-between gap-2\">\n <div className=\"flex items-center gap-1.5 min-w-0\">\n <span className=\"text-lg leading-none drop-shadow-sm\">{emoji}</span>\n <span className=\"text-[11px] font-medium drop-shadow-sm truncate\">{condition}</span>\n </div>\n <span className=\"text-[10px] opacity-90 tabular-nums drop-shadow-sm shrink-0\">H:{t(data.high)} L:{t(data.low)}</span>\n </div>\n </div>\n </div>\n </div>\n\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"Weather Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance} onSave={saveSettings}>\n <div className=\"space-y-3\">\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Display</h3>\n <div className=\"flex items-center gap-3 mb-2\">\n <span className=\"text-sm text-gray-600 w-24\">Temperature</span>\n <div className=\"flex gap-1\">\n {([{ key: false, label: '°C' }, { key: true, label: '°F' }] as const).map(o => (\n <button key={String(o.key)} onClick={() => setConfigPrefs(p => ({ ...p, useFahrenheit: o.key }))}\n className={`px-3 py-1 text-xs font-medium rounded-lg border transition-colors ${configPrefs.useFahrenheit === o.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`}>\n {o.label}\n </button>\n ))}\n </div>\n </div>\n <div className=\"flex items-center gap-3 mb-2\">\n <span className=\"text-sm text-gray-600 w-24\">Time Format</span>\n <div className=\"flex gap-1\">\n {([{ key: false, label: 'AM/PM' }, { key: true, label: '24H' }] as const).map(o => (\n <button key={String(o.key)} onClick={() => setConfigPrefs(p => ({ ...p, use24Hour: o.key }))}\n className={`px-3 py-1 text-xs font-medium rounded-lg border transition-colors ${configPrefs.use24Hour === o.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`}>\n {o.label}\n </button>\n ))}\n </div>\n </div>\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input type=\"checkbox\" checked={configPrefs.showLocalTime} onChange={e => setConfigPrefs(p => ({ ...p, showLocalTime: e.target.checked }))}\n className=\"rounded border-gray-300 text-blue-600 h-3.5 w-3.5\" />\n <span className=\"text-sm text-gray-600\">Show local time</span>\n </label>\n </div>\n </div>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">City</h3>\n <select value={configCity} onChange={e => setConfigCity(e.target.value)}\n className=\"w-full bg-gray-50 border border-gray-200 rounded px-2 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500\">\n {Object.keys(AVAILABLE_CITIES).map(name => (\n <option key={name} value={name}>{name}</option>\n ))}\n </select>\n <p className=\"mt-1 text-[10px] text-gray-400\">Auto-detected from your timezone; change if needed.</p>\n </div>\n </WidgetSettingsModal>\n </>\n );\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { AVAILABLE_CITIES, fetchCityWeather, getCondition, toFahrenheit } from './chunk-7CCHEEYC.js';
2
- import { loadAppearance, WidgetSettingsModal } from './chunk-QJXXSMPG.js';
3
- import { useShellPrefs, useWidgetSettings } from './chunk-SI4XHEMM.js';
4
- import './chunk-6Q4KYGMH.js';
2
+ import { loadAppearance, WidgetSettingsModal } from './chunk-PMPJLVZV.js';
3
+ import { useShellPrefs, useWidgetSettings } from './chunk-VA6M46NL.js';
4
+ import './chunk-DKDD5KXG.js';
5
5
  import { useState, useEffect, useCallback } from 'react';
6
6
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
7
7
 
@@ -190,5 +190,5 @@ function WorldClock() {
190
190
  }
191
191
 
192
192
  export { WorldClock as default };
193
- //# sourceMappingURL=WorldClock-A2EDB57H.js.map
194
- //# sourceMappingURL=WorldClock-A2EDB57H.js.map
193
+ //# sourceMappingURL=WorldClock-7PZI7VRE.js.map
194
+ //# sourceMappingURL=WorldClock-7PZI7VRE.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/apps/WorldClock.tsx"],"names":[],"mappings":";;;;;;;AAMA,IAAM,YAAA,GAAe,wBAAA;AACrB,IAAM,cAAA,GAAiB,CAAC,QAAA,EAAU,UAAA,EAAY,UAAU,CAAA;AAQxD,SAAS,WAAA,CAAY,IAAY,GAAA,EAA2C;AAC1E,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,IAAI,IAAA,CAAK,cAAA,CAAe,OAAA,EAAS;AAAA,MAC7C,QAAA,EAAU,EAAA;AAAA,MAAI,IAAA,EAAM,SAAA;AAAA,MAAW,MAAA,EAAQ,SAAA;AAAA,MAAW,MAAA,EAAQ;AAAA,KAC3D,CAAA,CAAE,aAAA,CAAc,GAAG,CAAA;AACpB,IAAA,MAAM,CAAA,GAAI,MAAM,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,IAAA,KAAS,MAAM,GAAG,KAAA,IAAS,IAAA;AACvD,IAAA,MAAM,CAAA,GAAI,MAAM,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,IAAA,KAAS,QAAQ,GAAG,KAAA,IAAS,IAAA;AACzD,IAAA,MAAM,IAAA,GAAA,CAAQ,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,WAAW,CAAA,EAAG,KAAA,IAAS,EAAA,EAAI,WAAA,EAAY;AAChF,IAAA,OAAO,EAAE,IAAA,EAAM,CAAA,EAAG,CAAC,CAAA,CAAA,EAAI,CAAC,IAAI,IAAA,EAAK;AAAA,EACnC,CAAA,CAAA,MAAQ;AAAE,IAAA,OAAO,EAAE,IAAA,EAAM,EAAA,EAAI,IAAA,EAAM,EAAA,EAAG;AAAA,EAAG;AAC3C;AAUe,SAAR,UAAA,GAA8B;AACnC,EAAA,MAAM,EAAE,KAAA,EAAO,IAAA,EAAK,GAAI,aAAA,EAAc;AACtC,EAAA,MAAM,CAAC,YAAY,aAAa,CAAA,GAAI,SAAS,MAAM,cAAA,CAAe,YAAY,CAAC,CAAA;AAC/E,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAS,KAAK,CAAA;AACtD,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,QAAA,CAAmB,EAAE,CAAA;AAC7D,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAI,SAA2B,UAAU,CAAA;AAErF,EAAA,MAAM,OAAA,GAAwB;AAAA,IAC5B,aAAA,EAAe,CAAC,CAAE,KAAA,CAAM,aAAA,EAA4C;AAAA,GACtE;AACA,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAAS,OAAO,CAAA;AAI1D,EAAA,MAAM,CAAC,KAAK,MAAM,CAAA,GAAI,SAAS,sBAAM,IAAI,MAAM,CAAA;AAC/C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,CAAA,GAAI,YAAY,MAAM,MAAA,qBAAW,IAAA,EAAM,CAAA,EAAG,EAAA,GAAK,GAAI,CAAA;AACzD,IAAA,OAAO,MAAM,cAAc,CAAC,CAAA;AAAA,EAC9B,CAAA,EAAG,EAAE,CAAA;AAKL,EAAA,MAAM,WAAmC,MAAA,CAAO,WAAA;AAAA,IAC9C,MAAA,CAAO,OAAA,CAAQ,gBAAgB,CAAA,CAAE,IAAI,CAAC,CAAC,IAAA,EAAM,IAAI,CAAA,KAAM,CAAC,IAAA,CAAK,EAAA,EAAI,IAAI,CAAC;AAAA,GACxE;AACA,EAAA,MAAM,YAAY,KAAA,CAAM,YAAA;AACxB,EAAA,MAAM,UAAoB,MAAM;AAC9B,IAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,SAAS,KAAK,SAAA,CAAU,MAAA,KAAW,GAAG,OAAO,cAAA;AAChE,IAAA,MAAM,MAAgB,EAAC;AACvB,IAAA,KAAA,MAAW,KAAK,SAAA,EAAW;AACzB,MAAA,MAAM,SAAS,gBAAA,CAAiB,CAAC,CAAA,GAAI,CAAA,GAAI,SAAS,CAAC,CAAA;AACnD,MAAA,IAAI,MAAA,IAAU,CAAC,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG,GAAA,CAAI,KAAK,MAAM,CAAA;AAAA,IACtD;AACA,IAAA,OAAO,GAAA,CAAI,SAAS,GAAA,GAAM,cAAA;AAAA,EAC5B,CAAA,GAAG;AAEH,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,QAAA,CAAsC,EAAE,CAAA;AAChE,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,IAAI,CAAA;AAE3C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,CAAC,YAAY;AACX,MAAA,MAAM,OAAoC,EAAC;AAC3C,MAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,OAAM,CAAA,KAAK;AACtC,QAAA,MAAM,CAAA,GAAI,MAAM,gBAAA,CAAiB,CAAC,CAAA;AAClC,QAAA,IAAI,CAAA,EAAG,IAAA,CAAK,CAAC,CAAA,GAAI,CAAA;AAAA,MACnB,CAAC,CAAC,CAAA;AACF,MAAA,IAAI,CAAC,SAAA,EAAW;AAAE,QAAA,OAAA,CAAQ,IAAI,CAAA;AAAG,QAAA,UAAA,CAAW,KAAK,CAAA;AAAA,MAAG;AAAA,IACtD,CAAA,GAAG;AACH,IAAA,OAAO,MAAM;AAAE,MAAA,SAAA,GAAY,IAAA;AAAA,IAAM,CAAA;AAAA,EACnC,GAAG,CAAC,MAAA,CAAO,IAAA,CAAK,GAAG,CAAC,CAAC,CAAA;AAErB,EAAA,iBAAA,CAAkB,YAAY,MAAM;AAClC,IAAA,eAAA,CAAgB,CAAC,GAAG,MAAM,CAAC,CAAA;AAC3B,IAAA,mBAAA,CAAoB,EAAE,GAAG,UAAA,EAAY,CAAA;AACrC,IAAA,gBAAA,CAAiB,EAAE,GAAG,OAAA,EAAS,CAAA;AAC/B,IAAA,eAAA,CAAgB,IAAI,CAAA;AAAA,EACtB,CAAA,EAAG,CAAC,MAAA,CAAO,IAAA,CAAK,GAAG,GAAG,UAAA,EAAY,OAAA,CAAQ,aAAa,CAAC,CAAC,CAAA;AAEzD,EAAA,MAAM,eAAe,MAAM;AACzB,IAAA,IAAI,YAAA,CAAa,WAAW,CAAA,EAAG;AAC/B,IAAA,IAAA,CAAK;AAAA,MACH,YAAA,EAAc,YAAA;AAAA,MACd,aAAA,EAAe,EAAE,GAAI,KAAA,CAAM,iBAAuC,EAAC,EAAI,aAAA,EAAe,aAAA,CAAc,aAAA;AAAc,KACnH,CAAA;AACD,IAAA,aAAA,CAAc,gBAAgB,CAAA;AAC9B,IAAA,YAAA,CAAa,OAAA,CAAQ,YAAA,EAAc,IAAA,CAAK,SAAA,CAAU,gBAAgB,CAAC,CAAA;AACnE,IAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,EACvB,CAAA;AAEA,EAAA,MAAM,UAAA,GAAa,CAAC,CAAA,KAAc,OAAA,CAAQ,aAAA,GAAgB,CAAA,EAAG,YAAA,CAAa,CAAC,CAAC,CAAA,IAAA,CAAA,GAAM,CAAA,EAAG,CAAC,CAAA,IAAA,CAAA;AAEtF,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EAME,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO;AAAA,UACL,eAAA,EAAiB,CAAA,yCAAA,EAA4C,UAAA,CAAW,aAAA,GAAgB,GAAG,CAAA,CAAA,CAAA;AAAA,UAC3F,gBAAgB,UAAA,CAAW,UAAA,GAAa,IAAI,CAAA,KAAA,EAAQ,UAAA,CAAW,UAAU,CAAA,GAAA,CAAA,GAAQ;AAAA,SACnF;AAAA,QACA,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0BAAA,EACZ,QAAA,EAAA;AAAA,UAAA,OAAA,IAAW,MAAA,CAAO,KAAA,CAAM,CAAA,CAAA,KAAK,CAAC,IAAA,CAAK,CAAC,CAAC,CAAA,oBACpC,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6CAAA,EAA8C,QAAA,EAAA,eAAA,EAAQ,CAAA;AAAA,UAEtE,MAAA,CAAO,GAAA,CAAI,CAAC,QAAA,KAAa;AACxB,YAAA,MAAM,CAAA,GAAI,KAAK,QAAQ,CAAA;AACvB,YAAA,MAAM,EAAA,GAAK,gBAAA,CAAiB,QAAQ,CAAA,EAAG,EAAA,IAAM,KAAA;AAC7C,YAAA,MAAM,EAAE,IAAA,EAAM,IAAA,EAAK,GAAI,WAAA,CAAY,IAAI,GAAG,CAAA;AAC1C,YAAA,IAAI,CAAC,CAAA,EAAG;AACN,cAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAmB,SAAA,EAAU,WAAA,EAC5B,QAAA,EAAA;AAAA,gCAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,2CAAA,EACb,QAAA,EAAA;AAAA,kCAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iEAAA,EAAmE,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,kCAC5F,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,oDAAA,EAAsD,QAAA,EAAA;AAAA,oBAAA,IAAA;AAAA,oCAAK,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAAA,EAAgC,QAAA,EAAA,IAAA,EAAK;AAAA,mBAAA,EAAO;AAAA,iBAAA,EACzI,CAAA;AAAA,gCACA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EAAiC,QAAA,EAAA,uBAAA,EAAgB;AAAA,eAAA,EAAA,EALxD,QAMV,CAAA;AAAA,YAEJ;AACA,YAAA,MAAM,CAAC,WAAW,KAAK,CAAA,GAAI,aAAa,CAAA,CAAE,IAAA,EAAM,EAAE,KAAK,CAAA;AACvD,YAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAmB,SAAA,EAAU,WAAA,EAE5B,QAAA,EAAA;AAAA,8BAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,2CAAA,EACb,QAAA,EAAA;AAAA,gCAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iEAAA,EAAmE,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,oCAC3F,MAAA,EAAA,EAAK,SAAA,EAAU,+FAA+F,QAAA,EAAA,UAAA,CAAW,CAAA,CAAE,IAAI,CAAA,EAAE;AAAA,eAAA,EACpI,CAAA;AAAA,8BAIA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4DAAA,EACb,QAAA,EAAA;AAAA,gCAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,iDAAA,EACb,QAAA,EAAA;AAAA,kCAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iCAAA,EAAmC,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,kCACzD,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mDAAA,EACb,QAAA,EAAA;AAAA,oBAAA,IAAA;AAAA,oCAAK,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0CAAA,EAA4C,QAAA,EAAA,IAAA,EAAK;AAAA,mBAAA,EACzE,CAAA;AAAA,kCACA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,wBAAA,EAAyB,QAAA,EAAA,MAAA,EAAC,CAAA;AAAA,kCAC1C,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,UAAA,EAAY,QAAA,EAAA,SAAA,EAAU;AAAA,iBAAA,EACxC,CAAA;AAAA,gCACA,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qCAAA,EAAsC,QAAA,EAAA;AAAA,kBAAA,IAAA;AAAA,kBAAG,UAAA,CAAW,EAAE,IAAI,CAAA;AAAA,kBAAE,KAAA;AAAA,kBAAI,UAAA,CAAW,EAAE,GAAG;AAAA,iBAAA,EAAE;AAAA,eAAA,EACpG;AAAA,aAAA,EAAA,EAnBQ,QAoBV,CAAA;AAAA,UAEJ,CAAC;AAAA,SAAA,EACH;AAAA;AAAA,KACF;AAAA,oBAEA,IAAA;AAAA,MAAC,mBAAA;AAAA,MAAA;AAAA,QAAoB,IAAA,EAAM,YAAA;AAAA,QAAc,OAAA,EAAS,MAAM,eAAA,CAAgB,KAAK,CAAA;AAAA,QAAG,KAAA,EAAM,sBAAA;AAAA,QACpF,UAAA,EAAY,gBAAA;AAAA,QAAkB,kBAAA,EAAoB,mBAAA;AAAA,QAAqB,MAAA,EAAQ,YAAA;AAAA,QAC/E,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,0CAAA,EAA2C,QAAA,EAAA,SAAA,EAAO,CAAA;AAAA,4BAChE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EACb,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,4BAAA,EAA6B,QAAA,EAAA,aAAA,EAAW,CAAA;AAAA,kCACvD,KAAA,EAAA,EAAI,SAAA,EAAU,cACX,QAAA,EAAA,CAAC,EAAE,KAAK,KAAA,EAAO,KAAA,EAAO,SAAK,EAAG,EAAE,KAAK,IAAA,EAAM,KAAA,EAAO,SAAM,CAAA,CAAY,IAAI,CAAA,CAAA,qBACxE,GAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBAA2B,OAAA,EAAS,MAAM,gBAAA,CAAiB,CAAA,CAAA,MAAM,EAAE,GAAG,CAAA,EAAG,aAAA,EAAe,CAAA,CAAE,GAAA,EAAI,CAAE,CAAA;AAAA,kBAC/F,WAAW,CAAA,kEAAA,EAAqE,aAAA,CAAc,kBAAkB,CAAA,CAAE,GAAA,GAAM,2CAA2C,yDAAyD,CAAA,CAAA;AAAA,kBAC3N,QAAA,EAAA,CAAA,CAAE;AAAA,iBAAA;AAAA,gBAFQ,MAAA,CAAO,EAAE,GAAG;AAAA,eAI1B,CAAA,EACH;AAAA,aAAA,EACF,CAAA;AAAA,4BACA,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,gCAAA,EAAiC,QAAA,EAAA,iCAAA,EAA+B;AAAA,WAAA,EAC/E,CAAA;AAAA,+BACC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,0CAAA,EAA2C,QAAA,EAAA,QAAA,EAAM,CAAA;AAAA,4BAC/D,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iDAAA,EACZ,QAAA,EAAA,MAAA,CAAO,IAAA,CAAK,gBAAgB,CAAA,CAAE,GAAA,CAAI,CAAA,IAAA,qBACjC,IAAA,CAAC,OAAA,EAAA,EAAiB,WAAU,mFAAA,EAC1B,QAAA,EAAA;AAAA,8BAAA,GAAA;AAAA,gBAAC,OAAA;AAAA,gBAAA;AAAA,kBAAM,IAAA,EAAK,UAAA;AAAA,kBAAW,OAAA,EAAS,YAAA,CAAa,QAAA,CAAS,IAAI,CAAA;AAAA,kBACxD,UAAU,MAAM,eAAA,CAAgB,UAAQ,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,GAAI,IAAA,CAAK,MAAA,CAAO,CAAA,CAAA,KAAK,MAAM,IAAI,CAAA,GAAI,CAAC,GAAG,IAAA,EAAM,IAAI,CAAC,CAAA;AAAA,kBAC5G,SAAA,EAAU;AAAA;AAAA,eAAwE;AAAA,cACnF;AAAA,aAAA,EAAA,EAJS,IAKZ,CACD,CAAA,EACH;AAAA,WAAA,EACF;AAAA;AAAA;AAAA;AACF,GAAA,EACF,CAAA;AAEJ","file":"WorldClock-A2EDB57H.js","sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { AVAILABLE_CITIES, fetchCityWeather, getCondition, toFahrenheit, type CityWeather } from './_weatherData';\n\nconst SETTINGS_KEY = 'world_clock_appearance';\nconst DEFAULT_CITIES = ['London', 'Shanghai', 'New York'];\n\ninterface WeatherPrefs { useFahrenheit: boolean }\n\n/**\n * Resolve the local time for the supplied IANA timezone into a digital\n * `12:34` + `AM` / `PM` pair. Used by the World Clock rows.\n */\nfunction digitalTime(tz: string, now: Date): { time: string; ampm: string } {\n try {\n const parts = new Intl.DateTimeFormat('en-US', {\n timeZone: tz, hour: 'numeric', minute: '2-digit', hour12: true,\n }).formatToParts(now);\n const h = parts.find(p => p.type === 'hour')?.value || '12';\n const m = parts.find(p => p.type === 'minute')?.value || '00';\n const ampm = (parts.find(p => p.type === 'dayPeriod')?.value || '').toUpperCase();\n return { time: `${h}:${m}`, ampm };\n } catch { return { time: '', ampm: '' }; }\n}\n\n/**\n * World Clock widget — multi-city list. Each row pairs a tiny analogue\n * clock (minimal-style: ring, four cardinal dots, two hands) with the\n * city's current weather. The weather emoji doubles as a day/night cue\n * (☀ vs 🌙 for clear, the same icons for everything else). Reads the\n * shared Open-Meteo cache so it doesn't re-hit the API when the Weather\n * widget already has the data.\n */\nexport default function WorldClock() {\n const { prefs, save } = useShellPrefs();\n const [appearance, setAppearance] = useState(() => loadAppearance(SETTINGS_KEY));\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configCities, setConfigCities] = useState<string[]>([]);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n\n const wxPrefs: WeatherPrefs = {\n useFahrenheit: !!(prefs.weather_prefs as WeatherPrefs | undefined)?.useFahrenheit,\n };\n const [configWxPrefs, setConfigWxPrefs] = useState(wxPrefs);\n\n // Tick once every 30 s so the analogue minute-hands drift smoothly. We\n // don't show seconds so faster polling is wasted re-renders.\n const [now, setNow] = useState(() => new Date());\n useEffect(() => {\n const t = setInterval(() => setNow(new Date()), 30 * 1000);\n return () => clearInterval(t);\n }, []);\n\n // Resolve the saved city list and migrate the legacy IANA-timezone\n // format (`Europe/London`) over to the new city-name format\n // (`London`).\n const tzToCity: Record<string, string> = Object.fromEntries(\n Object.entries(AVAILABLE_CITIES).map(([city, info]) => [info.tz, city])\n );\n const rawClocks = prefs.world_clocks as string[] | undefined;\n const cities: string[] = (() => {\n if (!Array.isArray(rawClocks) || rawClocks.length === 0) return DEFAULT_CITIES;\n const out: string[] = [];\n for (const v of rawClocks) {\n const asCity = AVAILABLE_CITIES[v] ? v : tzToCity[v];\n if (asCity && !out.includes(asCity)) out.push(asCity);\n }\n return out.length ? out : DEFAULT_CITIES;\n })();\n\n const [data, setData] = useState<Record<string, CityWeather>>({});\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n (async () => {\n const next: Record<string, CityWeather> = {};\n await Promise.all(cities.map(async c => {\n const w = await fetchCityWeather(c);\n if (w) next[c] = w;\n }));\n if (!cancelled) { setData(next); setLoading(false); }\n })();\n return () => { cancelled = true; };\n }, [cities.join(',')]);\n\n useWidgetSettings(useCallback(() => {\n setConfigCities([...cities]);\n setConfigAppearance({ ...appearance });\n setConfigWxPrefs({ ...wxPrefs });\n setSettingsOpen(true);\n }, [cities.join(','), appearance, wxPrefs.useFahrenheit]));\n\n const saveSettings = () => {\n if (configCities.length === 0) return;\n save({\n world_clocks: configCities,\n weather_prefs: { ...(prefs.weather_prefs as object | undefined ?? {}), useFahrenheit: configWxPrefs.useFahrenheit },\n });\n setAppearance(configAppearance);\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(configAppearance));\n setSettingsOpen(false);\n };\n\n const formatTemp = (c: number) => wxPrefs.useFahrenheit ? `${toFahrenheit(c)}°` : `${c}°`;\n\n return (\n <>\n {/* Theme-aware panel — same colour as the taskbar so all dashboard\n * widgets read as a coordinated set across light and dark themes.\n * Rows use `divide-y` rather than per-row border classes so the\n * last row never paints a stray separator line at the panel's\n * bottom edge. */}\n <div\n style={{\n backgroundColor: `rgb(var(--taskbar-bg-rgb, 243 244 246) / ${appearance.activeOpacity / 100})`,\n backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined,\n }}>\n <div className=\"divide-y divide-gray-200\">\n {loading && cities.every(c => !data[c]) && (\n <div className=\"px-3 py-6 text-center text-xs text-gray-500\">Loading…</div>\n )}\n {cities.map((cityName) => {\n const w = data[cityName];\n const tz = AVAILABLE_CITIES[cityName]?.tz ?? 'UTC';\n const { time, ampm } = digitalTime(tz, now);\n if (!w) {\n return (\n <div key={cityName} className=\"px-4 py-3\">\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-[15px] font-semibold tracking-tight text-gray-900 truncate\">{cityName}</span>\n <span className=\"tabular-nums text-[13px] font-medium text-gray-500\">{time}<span className=\"text-[9px] ml-0.5 opacity-70\">{ampm}</span></span>\n </div>\n <div className=\"text-[11px] text-gray-400 mt-1\">Loading weather…</div>\n </div>\n );\n }\n const [condition, emoji] = getCondition(w.code, w.isDay);\n return (\n <div key={cityName} className=\"px-4 py-3\">\n {/* Top — city name on the left, big temperature on the right. */}\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-[15px] font-semibold tracking-tight text-gray-900 truncate\">{cityName}</span>\n <span className=\"text-[26px] font-extralight leading-none tabular-nums tracking-tight text-gray-900 shrink-0\">{formatTemp(w.temp)}</span>\n </div>\n\n {/* Bottom — emoji · digital time · condition on the left;\n H/L on the right. */}\n <div className=\"flex items-center justify-between gap-2 mt-1.5 text-[11px]\">\n <div className=\"flex items-center gap-1.5 min-w-0 text-gray-500\">\n <span className=\"text-base leading-none shrink-0\">{emoji}</span>\n <span className=\"tabular-nums font-semibold text-gray-700 shrink-0\">\n {time}<span className=\"text-[9px] font-medium ml-0.5 opacity-70\">{ampm}</span>\n </span>\n <span className=\"text-gray-300 shrink-0\">·</span>\n <span className=\"truncate\">{condition}</span>\n </div>\n <span className=\"tabular-nums text-gray-500 shrink-0\">H:{formatTemp(w.high)} L:{formatTemp(w.low)}</span>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"World Clock Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance} onSave={saveSettings}>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Display</h3>\n <div className=\"flex items-center gap-3 mb-2\">\n <span className=\"text-sm text-gray-600 w-24\">Temperature</span>\n <div className=\"flex gap-1\">\n {([{ key: false, label: '°C' }, { key: true, label: '°F' }] as const).map(o => (\n <button key={String(o.key)} onClick={() => setConfigWxPrefs(p => ({ ...p, useFahrenheit: o.key }))}\n className={`px-3 py-1 text-xs font-medium rounded-lg border transition-colors ${configWxPrefs.useFahrenheit === o.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`}>\n {o.label}\n </button>\n ))}\n </div>\n </div>\n <p className=\"text-[10px] text-gray-400 mt-1\">Shared with the Weather widget.</p>\n </div>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Cities</h3>\n <div className=\"grid grid-cols-2 gap-1 max-h-56 overflow-y-auto\">\n {Object.keys(AVAILABLE_CITIES).map(name => (\n <label key={name} className=\"flex items-center gap-2 text-sm py-1 cursor-pointer hover:bg-gray-50 rounded px-2\">\n <input type=\"checkbox\" checked={configCities.includes(name)}\n onChange={() => setConfigCities(prev => prev.includes(name) ? prev.filter(c => c !== name) : [...prev, name])}\n className=\"rounded border-gray-300 text-blue-600 focus:ring-blue-500 h-3.5 w-3.5\" />\n {name}\n </label>\n ))}\n </div>\n </div>\n </WidgetSettingsModal>\n </>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/apps/WorldClock.tsx"],"names":[],"mappings":";;;;;;;AAMA,IAAM,YAAA,GAAe,wBAAA;AACrB,IAAM,cAAA,GAAiB,CAAC,QAAA,EAAU,UAAA,EAAY,UAAU,CAAA;AAQxD,SAAS,WAAA,CAAY,IAAY,GAAA,EAA2C;AAC1E,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,IAAI,IAAA,CAAK,cAAA,CAAe,OAAA,EAAS;AAAA,MAC7C,QAAA,EAAU,EAAA;AAAA,MAAI,IAAA,EAAM,SAAA;AAAA,MAAW,MAAA,EAAQ,SAAA;AAAA,MAAW,MAAA,EAAQ;AAAA,KAC3D,CAAA,CAAE,aAAA,CAAc,GAAG,CAAA;AACpB,IAAA,MAAM,CAAA,GAAI,MAAM,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,IAAA,KAAS,MAAM,GAAG,KAAA,IAAS,IAAA;AACvD,IAAA,MAAM,CAAA,GAAI,MAAM,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,IAAA,KAAS,QAAQ,GAAG,KAAA,IAAS,IAAA;AACzD,IAAA,MAAM,IAAA,GAAA,CAAQ,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,WAAW,CAAA,EAAG,KAAA,IAAS,EAAA,EAAI,WAAA,EAAY;AAChF,IAAA,OAAO,EAAE,IAAA,EAAM,CAAA,EAAG,CAAC,CAAA,CAAA,EAAI,CAAC,IAAI,IAAA,EAAK;AAAA,EACnC,CAAA,CAAA,MAAQ;AAAE,IAAA,OAAO,EAAE,IAAA,EAAM,EAAA,EAAI,IAAA,EAAM,EAAA,EAAG;AAAA,EAAG;AAC3C;AAUe,SAAR,UAAA,GAA8B;AACnC,EAAA,MAAM,EAAE,KAAA,EAAO,IAAA,EAAK,GAAI,aAAA,EAAc;AACtC,EAAA,MAAM,CAAC,YAAY,aAAa,CAAA,GAAI,SAAS,MAAM,cAAA,CAAe,YAAY,CAAC,CAAA;AAC/E,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAS,KAAK,CAAA;AACtD,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,QAAA,CAAmB,EAAE,CAAA;AAC7D,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAI,SAA2B,UAAU,CAAA;AAErF,EAAA,MAAM,OAAA,GAAwB;AAAA,IAC5B,aAAA,EAAe,CAAC,CAAE,KAAA,CAAM,aAAA,EAA4C;AAAA,GACtE;AACA,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAAS,OAAO,CAAA;AAI1D,EAAA,MAAM,CAAC,KAAK,MAAM,CAAA,GAAI,SAAS,sBAAM,IAAI,MAAM,CAAA;AAC/C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,CAAA,GAAI,YAAY,MAAM,MAAA,qBAAW,IAAA,EAAM,CAAA,EAAG,EAAA,GAAK,GAAI,CAAA;AACzD,IAAA,OAAO,MAAM,cAAc,CAAC,CAAA;AAAA,EAC9B,CAAA,EAAG,EAAE,CAAA;AAKL,EAAA,MAAM,WAAmC,MAAA,CAAO,WAAA;AAAA,IAC9C,MAAA,CAAO,OAAA,CAAQ,gBAAgB,CAAA,CAAE,IAAI,CAAC,CAAC,IAAA,EAAM,IAAI,CAAA,KAAM,CAAC,IAAA,CAAK,EAAA,EAAI,IAAI,CAAC;AAAA,GACxE;AACA,EAAA,MAAM,YAAY,KAAA,CAAM,YAAA;AACxB,EAAA,MAAM,UAAoB,MAAM;AAC9B,IAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,SAAS,KAAK,SAAA,CAAU,MAAA,KAAW,GAAG,OAAO,cAAA;AAChE,IAAA,MAAM,MAAgB,EAAC;AACvB,IAAA,KAAA,MAAW,KAAK,SAAA,EAAW;AACzB,MAAA,MAAM,SAAS,gBAAA,CAAiB,CAAC,CAAA,GAAI,CAAA,GAAI,SAAS,CAAC,CAAA;AACnD,MAAA,IAAI,MAAA,IAAU,CAAC,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG,GAAA,CAAI,KAAK,MAAM,CAAA;AAAA,IACtD;AACA,IAAA,OAAO,GAAA,CAAI,SAAS,GAAA,GAAM,cAAA;AAAA,EAC5B,CAAA,GAAG;AAEH,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,QAAA,CAAsC,EAAE,CAAA;AAChE,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,IAAI,CAAA;AAE3C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,CAAC,YAAY;AACX,MAAA,MAAM,OAAoC,EAAC;AAC3C,MAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,OAAM,CAAA,KAAK;AACtC,QAAA,MAAM,CAAA,GAAI,MAAM,gBAAA,CAAiB,CAAC,CAAA;AAClC,QAAA,IAAI,CAAA,EAAG,IAAA,CAAK,CAAC,CAAA,GAAI,CAAA;AAAA,MACnB,CAAC,CAAC,CAAA;AACF,MAAA,IAAI,CAAC,SAAA,EAAW;AAAE,QAAA,OAAA,CAAQ,IAAI,CAAA;AAAG,QAAA,UAAA,CAAW,KAAK,CAAA;AAAA,MAAG;AAAA,IACtD,CAAA,GAAG;AACH,IAAA,OAAO,MAAM;AAAE,MAAA,SAAA,GAAY,IAAA;AAAA,IAAM,CAAA;AAAA,EACnC,GAAG,CAAC,MAAA,CAAO,IAAA,CAAK,GAAG,CAAC,CAAC,CAAA;AAErB,EAAA,iBAAA,CAAkB,YAAY,MAAM;AAClC,IAAA,eAAA,CAAgB,CAAC,GAAG,MAAM,CAAC,CAAA;AAC3B,IAAA,mBAAA,CAAoB,EAAE,GAAG,UAAA,EAAY,CAAA;AACrC,IAAA,gBAAA,CAAiB,EAAE,GAAG,OAAA,EAAS,CAAA;AAC/B,IAAA,eAAA,CAAgB,IAAI,CAAA;AAAA,EACtB,CAAA,EAAG,CAAC,MAAA,CAAO,IAAA,CAAK,GAAG,GAAG,UAAA,EAAY,OAAA,CAAQ,aAAa,CAAC,CAAC,CAAA;AAEzD,EAAA,MAAM,eAAe,MAAM;AACzB,IAAA,IAAI,YAAA,CAAa,WAAW,CAAA,EAAG;AAC/B,IAAA,IAAA,CAAK;AAAA,MACH,YAAA,EAAc,YAAA;AAAA,MACd,aAAA,EAAe,EAAE,GAAI,KAAA,CAAM,iBAAuC,EAAC,EAAI,aAAA,EAAe,aAAA,CAAc,aAAA;AAAc,KACnH,CAAA;AACD,IAAA,aAAA,CAAc,gBAAgB,CAAA;AAC9B,IAAA,YAAA,CAAa,OAAA,CAAQ,YAAA,EAAc,IAAA,CAAK,SAAA,CAAU,gBAAgB,CAAC,CAAA;AACnE,IAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,EACvB,CAAA;AAEA,EAAA,MAAM,UAAA,GAAa,CAAC,CAAA,KAAc,OAAA,CAAQ,aAAA,GAAgB,CAAA,EAAG,YAAA,CAAa,CAAC,CAAC,CAAA,IAAA,CAAA,GAAM,CAAA,EAAG,CAAC,CAAA,IAAA,CAAA;AAEtF,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EAME,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO;AAAA,UACL,eAAA,EAAiB,CAAA,yCAAA,EAA4C,UAAA,CAAW,aAAA,GAAgB,GAAG,CAAA,CAAA,CAAA;AAAA,UAC3F,gBAAgB,UAAA,CAAW,UAAA,GAAa,IAAI,CAAA,KAAA,EAAQ,UAAA,CAAW,UAAU,CAAA,GAAA,CAAA,GAAQ;AAAA,SACnF;AAAA,QACA,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0BAAA,EACZ,QAAA,EAAA;AAAA,UAAA,OAAA,IAAW,MAAA,CAAO,KAAA,CAAM,CAAA,CAAA,KAAK,CAAC,IAAA,CAAK,CAAC,CAAC,CAAA,oBACpC,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6CAAA,EAA8C,QAAA,EAAA,eAAA,EAAQ,CAAA;AAAA,UAEtE,MAAA,CAAO,GAAA,CAAI,CAAC,QAAA,KAAa;AACxB,YAAA,MAAM,CAAA,GAAI,KAAK,QAAQ,CAAA;AACvB,YAAA,MAAM,EAAA,GAAK,gBAAA,CAAiB,QAAQ,CAAA,EAAG,EAAA,IAAM,KAAA;AAC7C,YAAA,MAAM,EAAE,IAAA,EAAM,IAAA,EAAK,GAAI,WAAA,CAAY,IAAI,GAAG,CAAA;AAC1C,YAAA,IAAI,CAAC,CAAA,EAAG;AACN,cAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAmB,SAAA,EAAU,WAAA,EAC5B,QAAA,EAAA;AAAA,gCAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,2CAAA,EACb,QAAA,EAAA;AAAA,kCAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iEAAA,EAAmE,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,kCAC5F,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,oDAAA,EAAsD,QAAA,EAAA;AAAA,oBAAA,IAAA;AAAA,oCAAK,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAAA,EAAgC,QAAA,EAAA,IAAA,EAAK;AAAA,mBAAA,EAAO;AAAA,iBAAA,EACzI,CAAA;AAAA,gCACA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EAAiC,QAAA,EAAA,uBAAA,EAAgB;AAAA,eAAA,EAAA,EALxD,QAMV,CAAA;AAAA,YAEJ;AACA,YAAA,MAAM,CAAC,WAAW,KAAK,CAAA,GAAI,aAAa,CAAA,CAAE,IAAA,EAAM,EAAE,KAAK,CAAA;AACvD,YAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAmB,SAAA,EAAU,WAAA,EAE5B,QAAA,EAAA;AAAA,8BAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,2CAAA,EACb,QAAA,EAAA;AAAA,gCAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iEAAA,EAAmE,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,oCAC3F,MAAA,EAAA,EAAK,SAAA,EAAU,+FAA+F,QAAA,EAAA,UAAA,CAAW,CAAA,CAAE,IAAI,CAAA,EAAE;AAAA,eAAA,EACpI,CAAA;AAAA,8BAIA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4DAAA,EACb,QAAA,EAAA;AAAA,gCAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,iDAAA,EACb,QAAA,EAAA;AAAA,kCAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iCAAA,EAAmC,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,kCACzD,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mDAAA,EACb,QAAA,EAAA;AAAA,oBAAA,IAAA;AAAA,oCAAK,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0CAAA,EAA4C,QAAA,EAAA,IAAA,EAAK;AAAA,mBAAA,EACzE,CAAA;AAAA,kCACA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,wBAAA,EAAyB,QAAA,EAAA,MAAA,EAAC,CAAA;AAAA,kCAC1C,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,UAAA,EAAY,QAAA,EAAA,SAAA,EAAU;AAAA,iBAAA,EACxC,CAAA;AAAA,gCACA,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qCAAA,EAAsC,QAAA,EAAA;AAAA,kBAAA,IAAA;AAAA,kBAAG,UAAA,CAAW,EAAE,IAAI,CAAA;AAAA,kBAAE,KAAA;AAAA,kBAAI,UAAA,CAAW,EAAE,GAAG;AAAA,iBAAA,EAAE;AAAA,eAAA,EACpG;AAAA,aAAA,EAAA,EAnBQ,QAoBV,CAAA;AAAA,UAEJ,CAAC;AAAA,SAAA,EACH;AAAA;AAAA,KACF;AAAA,oBAEA,IAAA;AAAA,MAAC,mBAAA;AAAA,MAAA;AAAA,QAAoB,IAAA,EAAM,YAAA;AAAA,QAAc,OAAA,EAAS,MAAM,eAAA,CAAgB,KAAK,CAAA;AAAA,QAAG,KAAA,EAAM,sBAAA;AAAA,QACpF,UAAA,EAAY,gBAAA;AAAA,QAAkB,kBAAA,EAAoB,mBAAA;AAAA,QAAqB,MAAA,EAAQ,YAAA;AAAA,QAC/E,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,0CAAA,EAA2C,QAAA,EAAA,SAAA,EAAO,CAAA;AAAA,4BAChE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EACb,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,4BAAA,EAA6B,QAAA,EAAA,aAAA,EAAW,CAAA;AAAA,kCACvD,KAAA,EAAA,EAAI,SAAA,EAAU,cACX,QAAA,EAAA,CAAC,EAAE,KAAK,KAAA,EAAO,KAAA,EAAO,SAAK,EAAG,EAAE,KAAK,IAAA,EAAM,KAAA,EAAO,SAAM,CAAA,CAAY,IAAI,CAAA,CAAA,qBACxE,GAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBAA2B,OAAA,EAAS,MAAM,gBAAA,CAAiB,CAAA,CAAA,MAAM,EAAE,GAAG,CAAA,EAAG,aAAA,EAAe,CAAA,CAAE,GAAA,EAAI,CAAE,CAAA;AAAA,kBAC/F,WAAW,CAAA,kEAAA,EAAqE,aAAA,CAAc,kBAAkB,CAAA,CAAE,GAAA,GAAM,2CAA2C,yDAAyD,CAAA,CAAA;AAAA,kBAC3N,QAAA,EAAA,CAAA,CAAE;AAAA,iBAAA;AAAA,gBAFQ,MAAA,CAAO,EAAE,GAAG;AAAA,eAI1B,CAAA,EACH;AAAA,aAAA,EACF,CAAA;AAAA,4BACA,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,gCAAA,EAAiC,QAAA,EAAA,iCAAA,EAA+B;AAAA,WAAA,EAC/E,CAAA;AAAA,+BACC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,0CAAA,EAA2C,QAAA,EAAA,QAAA,EAAM,CAAA;AAAA,4BAC/D,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iDAAA,EACZ,QAAA,EAAA,MAAA,CAAO,IAAA,CAAK,gBAAgB,CAAA,CAAE,GAAA,CAAI,CAAA,IAAA,qBACjC,IAAA,CAAC,OAAA,EAAA,EAAiB,WAAU,mFAAA,EAC1B,QAAA,EAAA;AAAA,8BAAA,GAAA;AAAA,gBAAC,OAAA;AAAA,gBAAA;AAAA,kBAAM,IAAA,EAAK,UAAA;AAAA,kBAAW,OAAA,EAAS,YAAA,CAAa,QAAA,CAAS,IAAI,CAAA;AAAA,kBACxD,UAAU,MAAM,eAAA,CAAgB,UAAQ,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,GAAI,IAAA,CAAK,MAAA,CAAO,CAAA,CAAA,KAAK,MAAM,IAAI,CAAA,GAAI,CAAC,GAAG,IAAA,EAAM,IAAI,CAAC,CAAA;AAAA,kBAC5G,SAAA,EAAU;AAAA;AAAA,eAAwE;AAAA,cACnF;AAAA,aAAA,EAAA,EAJS,IAKZ,CACD,CAAA,EACH;AAAA,WAAA,EACF;AAAA;AAAA;AAAA;AACF,GAAA,EACF,CAAA;AAEJ","file":"WorldClock-7PZI7VRE.js","sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { AVAILABLE_CITIES, fetchCityWeather, getCondition, toFahrenheit, type CityWeather } from './_weatherData';\n\nconst SETTINGS_KEY = 'world_clock_appearance';\nconst DEFAULT_CITIES = ['London', 'Shanghai', 'New York'];\n\ninterface WeatherPrefs { useFahrenheit: boolean }\n\n/**\n * Resolve the local time for the supplied IANA timezone into a digital\n * `12:34` + `AM` / `PM` pair. Used by the World Clock rows.\n */\nfunction digitalTime(tz: string, now: Date): { time: string; ampm: string } {\n try {\n const parts = new Intl.DateTimeFormat('en-US', {\n timeZone: tz, hour: 'numeric', minute: '2-digit', hour12: true,\n }).formatToParts(now);\n const h = parts.find(p => p.type === 'hour')?.value || '12';\n const m = parts.find(p => p.type === 'minute')?.value || '00';\n const ampm = (parts.find(p => p.type === 'dayPeriod')?.value || '').toUpperCase();\n return { time: `${h}:${m}`, ampm };\n } catch { return { time: '', ampm: '' }; }\n}\n\n/**\n * World Clock widget — multi-city list. Each row pairs a tiny analogue\n * clock (minimal-style: ring, four cardinal dots, two hands) with the\n * city's current weather. The weather emoji doubles as a day/night cue\n * (☀ vs 🌙 for clear, the same icons for everything else). Reads the\n * shared Open-Meteo cache so it doesn't re-hit the API when the Weather\n * widget already has the data.\n */\nexport default function WorldClock() {\n const { prefs, save } = useShellPrefs();\n const [appearance, setAppearance] = useState(() => loadAppearance(SETTINGS_KEY));\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configCities, setConfigCities] = useState<string[]>([]);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n\n const wxPrefs: WeatherPrefs = {\n useFahrenheit: !!(prefs.weather_prefs as WeatherPrefs | undefined)?.useFahrenheit,\n };\n const [configWxPrefs, setConfigWxPrefs] = useState(wxPrefs);\n\n // Tick once every 30 s so the analogue minute-hands drift smoothly. We\n // don't show seconds so faster polling is wasted re-renders.\n const [now, setNow] = useState(() => new Date());\n useEffect(() => {\n const t = setInterval(() => setNow(new Date()), 30 * 1000);\n return () => clearInterval(t);\n }, []);\n\n // Resolve the saved city list and migrate the legacy IANA-timezone\n // format (`Europe/London`) over to the new city-name format\n // (`London`).\n const tzToCity: Record<string, string> = Object.fromEntries(\n Object.entries(AVAILABLE_CITIES).map(([city, info]) => [info.tz, city])\n );\n const rawClocks = prefs.world_clocks as string[] | undefined;\n const cities: string[] = (() => {\n if (!Array.isArray(rawClocks) || rawClocks.length === 0) return DEFAULT_CITIES;\n const out: string[] = [];\n for (const v of rawClocks) {\n const asCity = AVAILABLE_CITIES[v] ? v : tzToCity[v];\n if (asCity && !out.includes(asCity)) out.push(asCity);\n }\n return out.length ? out : DEFAULT_CITIES;\n })();\n\n const [data, setData] = useState<Record<string, CityWeather>>({});\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n (async () => {\n const next: Record<string, CityWeather> = {};\n await Promise.all(cities.map(async c => {\n const w = await fetchCityWeather(c);\n if (w) next[c] = w;\n }));\n if (!cancelled) { setData(next); setLoading(false); }\n })();\n return () => { cancelled = true; };\n }, [cities.join(',')]);\n\n useWidgetSettings(useCallback(() => {\n setConfigCities([...cities]);\n setConfigAppearance({ ...appearance });\n setConfigWxPrefs({ ...wxPrefs });\n setSettingsOpen(true);\n }, [cities.join(','), appearance, wxPrefs.useFahrenheit]));\n\n const saveSettings = () => {\n if (configCities.length === 0) return;\n save({\n world_clocks: configCities,\n weather_prefs: { ...(prefs.weather_prefs as object | undefined ?? {}), useFahrenheit: configWxPrefs.useFahrenheit },\n });\n setAppearance(configAppearance);\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(configAppearance));\n setSettingsOpen(false);\n };\n\n const formatTemp = (c: number) => wxPrefs.useFahrenheit ? `${toFahrenheit(c)}°` : `${c}°`;\n\n return (\n <>\n {/* Theme-aware panel — same colour as the taskbar so all dashboard\n * widgets read as a coordinated set across light and dark themes.\n * Rows use `divide-y` rather than per-row border classes so the\n * last row never paints a stray separator line at the panel's\n * bottom edge. */}\n <div\n style={{\n backgroundColor: `rgb(var(--taskbar-bg-rgb, 243 244 246) / ${appearance.activeOpacity / 100})`,\n backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined,\n }}>\n <div className=\"divide-y divide-gray-200\">\n {loading && cities.every(c => !data[c]) && (\n <div className=\"px-3 py-6 text-center text-xs text-gray-500\">Loading…</div>\n )}\n {cities.map((cityName) => {\n const w = data[cityName];\n const tz = AVAILABLE_CITIES[cityName]?.tz ?? 'UTC';\n const { time, ampm } = digitalTime(tz, now);\n if (!w) {\n return (\n <div key={cityName} className=\"px-4 py-3\">\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-[15px] font-semibold tracking-tight text-gray-900 truncate\">{cityName}</span>\n <span className=\"tabular-nums text-[13px] font-medium text-gray-500\">{time}<span className=\"text-[9px] ml-0.5 opacity-70\">{ampm}</span></span>\n </div>\n <div className=\"text-[11px] text-gray-400 mt-1\">Loading weather…</div>\n </div>\n );\n }\n const [condition, emoji] = getCondition(w.code, w.isDay);\n return (\n <div key={cityName} className=\"px-4 py-3\">\n {/* Top — city name on the left, big temperature on the right. */}\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-[15px] font-semibold tracking-tight text-gray-900 truncate\">{cityName}</span>\n <span className=\"text-[26px] font-extralight leading-none tabular-nums tracking-tight text-gray-900 shrink-0\">{formatTemp(w.temp)}</span>\n </div>\n\n {/* Bottom — emoji · digital time · condition on the left;\n H/L on the right. */}\n <div className=\"flex items-center justify-between gap-2 mt-1.5 text-[11px]\">\n <div className=\"flex items-center gap-1.5 min-w-0 text-gray-500\">\n <span className=\"text-base leading-none shrink-0\">{emoji}</span>\n <span className=\"tabular-nums font-semibold text-gray-700 shrink-0\">\n {time}<span className=\"text-[9px] font-medium ml-0.5 opacity-70\">{ampm}</span>\n </span>\n <span className=\"text-gray-300 shrink-0\">·</span>\n <span className=\"truncate\">{condition}</span>\n </div>\n <span className=\"tabular-nums text-gray-500 shrink-0\">H:{formatTemp(w.high)} L:{formatTemp(w.low)}</span>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"World Clock Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance} onSave={saveSettings}>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Display</h3>\n <div className=\"flex items-center gap-3 mb-2\">\n <span className=\"text-sm text-gray-600 w-24\">Temperature</span>\n <div className=\"flex gap-1\">\n {([{ key: false, label: '°C' }, { key: true, label: '°F' }] as const).map(o => (\n <button key={String(o.key)} onClick={() => setConfigWxPrefs(p => ({ ...p, useFahrenheit: o.key }))}\n className={`px-3 py-1 text-xs font-medium rounded-lg border transition-colors ${configWxPrefs.useFahrenheit === o.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`}>\n {o.label}\n </button>\n ))}\n </div>\n </div>\n <p className=\"text-[10px] text-gray-400 mt-1\">Shared with the Weather widget.</p>\n </div>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Cities</h3>\n <div className=\"grid grid-cols-2 gap-1 max-h-56 overflow-y-auto\">\n {Object.keys(AVAILABLE_CITIES).map(name => (\n <label key={name} className=\"flex items-center gap-2 text-sm py-1 cursor-pointer hover:bg-gray-50 rounded px-2\">\n <input type=\"checkbox\" checked={configCities.includes(name)}\n onChange={() => setConfigCities(prev => prev.includes(name) ? prev.filter(c => c !== name) : [...prev, name])}\n className=\"rounded border-gray-300 text-blue-600 focus:ring-blue-500 h-3.5 w-3.5\" />\n {name}\n </label>\n ))}\n </div>\n </div>\n </WidgetSettingsModal>\n </>\n );\n}\n"]}
@@ -1,26 +1,26 @@
1
1
  export { setBrowserStartUrl } from '../chunk-BFBWLCO6.js';
2
- export { openFilesInTrashMode, setFilesDemoTree } from '../chunk-CWFH34LM.js';
3
- import '../chunk-52RFL3OQ.js';
2
+ export { openFilesInTrashMode, setFilesDemoTree } from '../chunk-LBY7KH2W.js';
3
+ import '../chunk-QAKURGOG.js';
4
4
  export { setPdfPreview } from '../chunk-BV6SQ46N.js';
5
- export { BUILTIN_APP_INFO } from '../chunk-RKNJSV2T.js';
5
+ export { BUILTIN_APP_INFO } from '../chunk-ASRXGCSQ.js';
6
6
  export { setSpreadsheetPreview } from '../chunk-4SQU5YV6.js';
7
- import '../chunk-D36OPVAT.js';
8
- import '../chunk-SI4XHEMM.js';
9
- import '../chunk-6Q4KYGMH.js';
7
+ import '../chunk-K6MB36UJ.js';
8
+ import '../chunk-VA6M46NL.js';
9
+ import '../chunk-DKDD5KXG.js';
10
10
  import { lazy } from 'react';
11
11
 
12
- var Calculator = lazy(() => import('../Calculator-RCNLBRHK.js'));
13
- var Spreadsheet = lazy(() => import('../Spreadsheet-FRUPALW4.js'));
14
- var Weather = lazy(() => import('../Weather-N74AKS6V.js'));
15
- var CurrencyConverter = lazy(() => import('../CurrencyConverter-CM5OTXWF.js'));
16
- var PomodoroTimer = lazy(() => import('../PomodoroTimer-EZMBYLQX.js'));
17
- var Notepad = lazy(() => import('../Notepad-C6JHCCF2.js'));
18
- var WorldClock = lazy(() => import('../WorldClock-A2EDB57H.js'));
19
- var Stock = lazy(() => import('../Stock-HL42NPTM.js'));
20
- var Preview = lazy(() => import('../Preview-TFDEMTSH.js'));
21
- var Documents = lazy(() => import('../Documents-3BPIAGQT.js'));
22
- var Files = lazy(() => import('../Files-CR3L5C2L.js'));
23
- var Browser = lazy(() => import('../Browser-TPAIWPZX.js'));
12
+ var Calculator = lazy(() => import('../Calculator-3ULKK5ZA.js'));
13
+ var Spreadsheet = lazy(() => import('../Spreadsheet-2YYUKKSY.js'));
14
+ var Weather = lazy(() => import('../Weather-4I4EFUJO.js'));
15
+ var CurrencyConverter = lazy(() => import('../CurrencyConverter-JC2N7AY3.js'));
16
+ var PomodoroTimer = lazy(() => import('../PomodoroTimer-RPCRTUKC.js'));
17
+ var Notepad = lazy(() => import('../Notepad-NGLFEJLA.js'));
18
+ var WorldClock = lazy(() => import('../WorldClock-7PZI7VRE.js'));
19
+ var Stock = lazy(() => import('../Stock-YTQ2OYQ7.js'));
20
+ var Preview = lazy(() => import('../Preview-H4S427VB.js'));
21
+ var Documents = lazy(() => import('../Documents-MJKEUOOL.js'));
22
+ var Files = lazy(() => import('../Files-BTZMPTL6.js'));
23
+ var Browser = lazy(() => import('../Browser-674YMWMK.js'));
24
24
  var utilityApps = {
25
25
  "/calculator": { component: Calculator, label: "Calculator", size: "sm", allowPinOnTop: true, utility: true, widget: true, dimensions: [280, 420] },
26
26
  "/spreadsheet": { component: Spreadsheet, label: "Spreadsheets", size: "2xl", appStyle: true, multiInstance: true },
@@ -0,0 +1,20 @@
1
+ import { useShellAuth } from './chunk-DKDD5KXG.js';
2
+
3
+ // src/contexts/AuthContext.tsx
4
+ var _authBridge = {};
5
+ function setShellAuthBridge(bridge) {
6
+ _authBridge = bridge;
7
+ }
8
+ function useAuth() {
9
+ const { hasAnyPerm } = useShellAuth();
10
+ return {
11
+ user: _authBridge.user,
12
+ logout: _authBridge.logout ?? (() => {
13
+ }),
14
+ hasAnyPerm
15
+ };
16
+ }
17
+
18
+ export { setShellAuthBridge, useAuth };
19
+ //# sourceMappingURL=chunk-3NZSR3ZG.js.map
20
+ //# sourceMappingURL=chunk-3NZSR3ZG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/contexts/AuthContext.tsx"],"names":[],"mappings":";;;AAoBA,IAAI,cAAyD,EAAC;AAGvD,SAAS,mBAAmB,MAAA,EAAmD;AACpF,EAAA,WAAA,GAAc,MAAA;AAChB;AAEO,SAAS,OAAA,GAAU;AACxB,EAAA,MAAM,EAAE,UAAA,EAAW,GAAI,YAAA,EAAa;AACpC,EAAA,OAAO;AAAA,IACL,MAAM,WAAA,CAAY,IAAA;AAAA,IAClB,MAAA,EAAQ,WAAA,CAAY,MAAA,KAAW,MAAM;AAAA,IAAC,CAAA,CAAA;AAAA,IACtC;AAAA,GACF;AACF","file":"chunk-3NZSR3ZG.js","sourcesContent":["/**\n * INTERNAL stub — bridges legacy `useAuth()` calls inside the shell to the\n * new <ShellAuthProvider> contract.\n *\n * The shell only ever uses `hasAnyPerm` for nav-item visibility plus `user`\n * + `logout` for the profile menu. Consumers pass these in via\n * <ShellAuthProvider value={{...}}> at the App root.\n *\n * Long-term this file is removed when call sites migrate to `useShellAuth()`\n * + Layout's `user` / `onLogout` props directly.\n */\nimport { useShellAuth } from '../shell/ShellAuth';\n\ninterface ShellUser {\n email?: string;\n first_name?: string;\n last_name?: string;\n avatar_url?: string;\n}\n\nlet _authBridge: { user?: ShellUser; logout?: () => void } = {};\n\n/** Consumer registers user-identity + logout handler once at app startup. */\nexport function setShellAuthBridge(bridge: { user?: ShellUser; logout?: () => void }) {\n _authBridge = bridge;\n}\n\nexport function useAuth() {\n const { hasAnyPerm } = useShellAuth();\n return {\n user: _authBridge.user,\n logout: _authBridge.logout ?? (() => {}),\n hasAnyPerm,\n };\n}\n"]}
@@ -1,6 +1,6 @@
1
- import { VERSION } from './chunk-D36OPVAT.js';
2
- import { useWindowMenuItem, Modal } from './chunk-SI4XHEMM.js';
3
- import { navIcons } from './chunk-6Q4KYGMH.js';
1
+ import { VERSION } from './chunk-K6MB36UJ.js';
2
+ import { useWindowMenuItem, Modal } from './chunk-VA6M46NL.js';
3
+ import { navIcons } from './chunk-DKDD5KXG.js';
4
4
  import { useState, useCallback, isValidElement, cloneElement } from 'react';
5
5
  import { jsx, jsxs } from 'react/jsx-runtime';
6
6
 
@@ -75,5 +75,5 @@ function AboutApp({ app }) {
75
75
  }
76
76
 
77
77
  export { AboutApp, BUILTIN_APP_INFO };
78
- //# sourceMappingURL=chunk-RKNJSV2T.js.map
79
- //# sourceMappingURL=chunk-RKNJSV2T.js.map
78
+ //# sourceMappingURL=chunk-ASRXGCSQ.js.map
79
+ //# sourceMappingURL=chunk-ASRXGCSQ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/apps/_about.tsx"],"names":[],"mappings":"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","file":"chunk-RKNJSV2T.js","sourcesContent":["/**\n * Shared \"About\" dialog for the bundled apps.\n *\n * Each bundled app carries its own version (independent of the package\n * version) so app-level changes can be tracked without bumping every app at\n * once. `<AboutApp app=\"…\" />` registers an \"About <Name>\" item in the\n * window title menu and renders the dialog: app icon, name, app version and\n * the react-os-shell attribution + shell version.\n *\n * Bump an app's version in `BUILTIN_APP_INFO` whenever that app's behaviour\n * changes, alongside the package-level CHANGELOG entry.\n */\nimport { useCallback, useState, isValidElement, cloneElement, type ReactElement } from 'react';\nimport Modal, { useWindowMenuItem } from '../shell/Modal';\nimport { navIcons } from '../shell-config/nav';\nimport { VERSION } from '../version';\n\nexport interface BuiltinAppInfo {\n /** Display name — matches the window-registry label. */\n name: string;\n /** App version, independent of the package version. */\n version: string;\n /** One-line summary shown in the About dialog. */\n description: string;\n /** Registry route — used to look up the consumer-registered nav icon. */\n route: string;\n}\n\nexport const BUILTIN_APP_INFO = {\n spreadsheet: {\n name: 'Spreadsheets',\n version: '1.1.0',\n route: '/spreadsheet',\n description: 'Multi-sheet spreadsheet editor with CSV / TSV import and export.',\n },\n notepad: {\n name: 'Notepad',\n version: '1.0.0',\n route: '/notepad',\n description: 'Color-coded notes with checklists, desktop stickies and entity autolinking.',\n },\n documents: {\n name: 'Documents',\n version: '1.1.0',\n route: '/documents',\n description: 'Letter-page editor for Word documents and plain-text files — images, lists, alignment.',\n },\n preview: {\n name: 'Preview',\n version: '1.2.1',\n route: '/preview',\n description: 'Viewer for PDF documents, images, DXF drawings and 3D models — CAD-style measuring with object snap and an AutoCAD-like command bar.',\n },\n files: {\n name: 'Files',\n version: '1.1.0',\n route: '/files',\n description: 'Personal file manager with folders, uploads, quota, trash and desktop shortcut folders.',\n },\n browser: {\n name: 'Browser',\n version: '1.0.1',\n route: '/browser',\n description: 'Minimal web browser with bookmarks, history and navigation bar.',\n },\n} satisfies Record<string, BuiltinAppInfo>;\n\nexport type BuiltinAppId = keyof typeof BUILTIN_APP_INFO;\n\nconst ABOUT_MENU_ICON = (\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z\" />\n </svg>\n);\n\n// Generic window glyph shown when the consumer hasn't registered a nav icon\n// for the app's route (same fallback shape as the Modal title bar).\nconst FALLBACK_APP_ICON = (\n <svg className=\"h-9 w-9\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3.75 6.75A2.25 2.25 0 016 4.5h12a2.25 2.25 0 012.25 2.25v10.5A2.25 2.25 0 0118 19.5H6a2.25 2.25 0 01-2.25-2.25V6.75z M3.75 9h16.5\" />\n </svg>\n);\n\n/** Registers \"About <Name>\" in the window title menu and renders the dialog.\n * Render anywhere inside the app's window. */\nexport default function AboutApp({ app }: { app: BuiltinAppId }) {\n const info = BUILTIN_APP_INFO[app];\n const [open, setOpen] = useState(false);\n const openDialog = useCallback(() => setOpen(true), []);\n useWindowMenuItem(`About ${info.name}`, openDialog, ABOUT_MENU_ICON);\n\n if (!open) return null;\n\n const registered = navIcons[info.route];\n const appIcon = isValidElement(registered)\n ? cloneElement(registered as ReactElement, { className: 'h-9 w-9' } as any)\n : FALLBACK_APP_ICON;\n\n return (\n <Modal open onClose={() => setOpen(false)} title={`About ${info.name}`} size=\"sm\" compact bodyScroll={false} autoHeight dimensions={[320, 320]}>\n <div className=\"flex flex-col items-center text-center px-5 pt-5 pb-4\">\n <div className=\"flex h-16 w-16 items-center justify-center rounded-2xl bg-gray-100 text-gray-600 shrink-0\">\n {appIcon}\n </div>\n <h2 className=\"mt-3 text-lg font-bold text-gray-900\">{info.name}</h2>\n <p className=\"text-[11px] font-mono text-gray-400\">Version {info.version}</p>\n <p className=\"mt-2 text-xs text-gray-500 leading-relaxed\">{info.description}</p>\n <div className=\"mt-4 pt-3 border-t border-gray-200 w-full\">\n <p className=\"text-[11px] text-gray-500\">\n Part of the <span className=\"font-medium text-gray-700\">react-os-shell</span> desktop environment\n </p>\n {VERSION && <p className=\"mt-0.5 text-[10px] font-mono text-gray-400\">shell v{VERSION}</p>}\n </div>\n </div>\n </Modal>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/apps/_about.tsx"],"names":[],"mappings":"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","file":"chunk-ASRXGCSQ.js","sourcesContent":["/**\n * Shared \"About\" dialog for the bundled apps.\n *\n * Each bundled app carries its own version (independent of the package\n * version) so app-level changes can be tracked without bumping every app at\n * once. `<AboutApp app=\"…\" />` registers an \"About <Name>\" item in the\n * window title menu and renders the dialog: app icon, name, app version and\n * the react-os-shell attribution + shell version.\n *\n * Bump an app's version in `BUILTIN_APP_INFO` whenever that app's behaviour\n * changes, alongside the package-level CHANGELOG entry.\n */\nimport { useCallback, useState, isValidElement, cloneElement, type ReactElement } from 'react';\nimport Modal, { useWindowMenuItem } from '../shell/Modal';\nimport { navIcons } from '../shell-config/nav';\nimport { VERSION } from '../version';\n\nexport interface BuiltinAppInfo {\n /** Display name — matches the window-registry label. */\n name: string;\n /** App version, independent of the package version. */\n version: string;\n /** One-line summary shown in the About dialog. */\n description: string;\n /** Registry route — used to look up the consumer-registered nav icon. */\n route: string;\n}\n\nexport const BUILTIN_APP_INFO = {\n spreadsheet: {\n name: 'Spreadsheets',\n version: '1.1.0',\n route: '/spreadsheet',\n description: 'Multi-sheet spreadsheet editor with CSV / TSV import and export.',\n },\n notepad: {\n name: 'Notepad',\n version: '1.0.0',\n route: '/notepad',\n description: 'Color-coded notes with checklists, desktop stickies and entity autolinking.',\n },\n documents: {\n name: 'Documents',\n version: '1.1.0',\n route: '/documents',\n description: 'Letter-page editor for Word documents and plain-text files — images, lists, alignment.',\n },\n preview: {\n name: 'Preview',\n version: '1.2.1',\n route: '/preview',\n description: 'Viewer for PDF documents, images, DXF drawings and 3D models — CAD-style measuring with object snap and an AutoCAD-like command bar.',\n },\n files: {\n name: 'Files',\n version: '1.1.0',\n route: '/files',\n description: 'Personal file manager with folders, uploads, quota, trash and desktop shortcut folders.',\n },\n browser: {\n name: 'Browser',\n version: '1.0.1',\n route: '/browser',\n description: 'Minimal web browser with bookmarks, history and navigation bar.',\n },\n} satisfies Record<string, BuiltinAppInfo>;\n\nexport type BuiltinAppId = keyof typeof BUILTIN_APP_INFO;\n\nconst ABOUT_MENU_ICON = (\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z\" />\n </svg>\n);\n\n// Generic window glyph shown when the consumer hasn't registered a nav icon\n// for the app's route (same fallback shape as the Modal title bar).\nconst FALLBACK_APP_ICON = (\n <svg className=\"h-9 w-9\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3.75 6.75A2.25 2.25 0 016 4.5h12a2.25 2.25 0 012.25 2.25v10.5A2.25 2.25 0 0118 19.5H6a2.25 2.25 0 01-2.25-2.25V6.75z M3.75 9h16.5\" />\n </svg>\n);\n\n/** Registers \"About <Name>\" in the window title menu and renders the dialog.\n * Render anywhere inside the app's window. */\nexport default function AboutApp({ app }: { app: BuiltinAppId }) {\n const info = BUILTIN_APP_INFO[app];\n const [open, setOpen] = useState(false);\n const openDialog = useCallback(() => setOpen(true), []);\n useWindowMenuItem(`About ${info.name}`, openDialog, ABOUT_MENU_ICON);\n\n if (!open) return null;\n\n const registered = navIcons[info.route];\n const appIcon = isValidElement(registered)\n ? cloneElement(registered as ReactElement, { className: 'h-9 w-9' } as any)\n : FALLBACK_APP_ICON;\n\n return (\n <Modal open onClose={() => setOpen(false)} title={`About ${info.name}`} size=\"sm\" compact bodyScroll={false} autoHeight dimensions={[320, 320]}>\n <div className=\"flex flex-col items-center text-center px-5 pt-5 pb-4\">\n <div className=\"flex h-16 w-16 items-center justify-center rounded-2xl bg-gray-100 text-gray-600 shrink-0\">\n {appIcon}\n </div>\n <h2 className=\"mt-3 text-lg font-bold text-gray-900\">{info.name}</h2>\n <p className=\"text-[11px] font-mono text-gray-400\">Version {info.version}</p>\n <p className=\"mt-2 text-xs text-gray-500 leading-relaxed\">{info.description}</p>\n <div className=\"mt-4 pt-3 border-t border-gray-200 w-full\">\n <p className=\"text-[11px] text-gray-500\">\n Part of the <span className=\"font-medium text-gray-700\">react-os-shell</span> desktop environment\n </p>\n {VERSION && <p className=\"mt-0.5 text-[10px] font-mono text-gray-400\">shell v{VERSION}</p>}\n </div>\n </div>\n </Modal>\n );\n}\n"]}
@@ -1,3 +1,6 @@
1
+ import { createContext, useContext } from 'react';
2
+ import { jsx } from 'react/jsx-runtime';
3
+
1
4
  // src/shell/nav-types.ts
2
5
  function isSection(item) {
3
6
  return "items" in item;
@@ -33,6 +36,14 @@ function setShellNavIcons(icons) {
33
36
  var sectionIcons = {};
34
37
  var navSections = [];
35
38
  var startMenuCategories = { erp: [], system: [], virtual: [], footer: [] };
39
+ var DEFAULT = { hasAnyPerm: () => true };
40
+ var ShellAuthContext = createContext(DEFAULT);
41
+ function ShellAuthProvider({ value, children }) {
42
+ return /* @__PURE__ */ jsx(ShellAuthContext.Provider, { value, children });
43
+ }
44
+ function useShellAuth() {
45
+ return useContext(ShellAuthContext);
46
+ }
36
47
 
37
48
  // src/utils/glass.ts
38
49
  function getMenuOpacity() {
@@ -90,6 +101,6 @@ function glassStyle(opacity) {
90
101
  var GLASS_DIVIDER = "border-white/20";
91
102
  var GLASS_INPUT_BG = "glass-input-bg";
92
103
 
93
- export { GLASS_DIVIDER, GLASS_INPUT_BG, glassStyle, isReachable, isSection, navIcons, navSections, sectionIcons, setShellNavIcons, startMenuCategories, visibleChildren };
94
- //# sourceMappingURL=chunk-6Q4KYGMH.js.map
95
- //# sourceMappingURL=chunk-6Q4KYGMH.js.map
104
+ export { GLASS_DIVIDER, GLASS_INPUT_BG, ShellAuthProvider, glassStyle, isReachable, isSection, navIcons, navSections, sectionIcons, setShellNavIcons, startMenuCategories, useShellAuth, visibleChildren };
105
+ //# sourceMappingURL=chunk-DKDD5KXG.js.map
106
+ //# sourceMappingURL=chunk-DKDD5KXG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shell/nav-types.ts","../src/shell-config/nav.tsx","../src/shell/ShellAuth.tsx","../src/utils/glass.ts"],"names":[],"mappings":"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","file":"chunk-DKDD5KXG.js","sourcesContent":["/**\n * Nav data types used by <Layout> + <StartMenu>. The actual sections, icons,\n * and categories are consumer-supplied via Layout props — the package never\n * ships nav DATA, only the shape it expects.\n */\nimport type { ReactNode } from 'react';\n\nexport interface NavItem {\n to: string;\n label: string;\n perms?: string[];\n dividerAfter?: boolean;\n /** Optional 3rd-level sub-items. Hovering the parent in <StartMenu> opens\n * a nested flyout; in <Sidebar> the parent becomes an inline sub-accordion. */\n children?: NavItem[];\n}\n\nexport interface NavSection {\n label: string;\n items: NavItem[];\n perms?: string[];\n /** Optional landing route for clicks on the section title itself\n * (e.g. R&D's `/rd` dashboard). */\n to?: string;\n}\n\nexport interface VirtualSection {\n label: string;\n items: NavItem[];\n icon?: ReactNode;\n}\n\nexport interface StartMenuCategories {\n /** Section labels rendered in the \"ERP\" group (bold, with section icon). */\n erp: string[];\n /** Section labels rendered in the \"system\" group. */\n system: string[];\n /** Optional virtual flyouts (e.g. a \"Utilities\" tray). */\n virtual?: VirtualSection[];\n /** Optional section labels pinned to the bottom of the menu, next to the user\n * profile, separated from the ERP group by a divider. */\n footer?: string[];\n /** Optional flat top-level items pinned to the bottom of the menu, next to\n * the user profile, separated from the ERP group by a divider. Unlike\n * `footer` (section labels rendered as flyouts), these render as direct\n * clickable rows — use for standalone destinations like System Preferences\n * or a bug-report link. */\n footerItems?: NavItem[];\n}\n\nexport function isSection(item: NavSection | NavItem): item is NavSection {\n return 'items' in item;\n}\n\n/** The host app's permission predicate — `useAuth().hasAnyPerm`. */\ntype HasAnyPerm = (perms: string[]) => boolean;\n\n/**\n * The sub-items of `item` this user may actually see.\n *\n * Every affordance for a nested group has to be derived from THIS list — the\n * chevron that advertises it, the hover handler that opens it, and the flyout\n * itself. Reading the raw `item.children` for the chevron while filtering only\n * for the flyout put an arrow on groups whose children were all\n * permission-hidden: hovering one highlighted the row and opened nothing.\n */\nexport function visibleChildren(item: NavItem, hasAnyPerm: HasAnyPerm): NavItem[] {\n return (item.children ?? []).filter(c => !c.perms || hasAnyPerm(c.perms));\n}\n\n/**\n * Whether a nav row leads anywhere for this user: either it's a plain\n * destination, or it's a group with at least one visible child. A group whose\n * children are all hidden has nothing to open — and by convention a group's\n * `to` is a synthetic key that never navigates, so there is nothing to fall\n * back to either. Such a row is dropped rather than rendered inert.\n */\nexport function isReachable(item: NavItem, hasAnyPerm: HasAnyPerm): boolean {\n return !item.children?.length || visibleChildren(item, hasAnyPerm).length > 0;\n}\n","/**\n * INTERNAL stub — package-side compatibility for files that legacy-imported\n * default nav data from `shell-config/nav`. The package never ships nav\n * DATA; consumers always supply `navSections` / `navIcons` / `sectionIcons` /\n * `categories` as Layout props.\n *\n * Empty defaults exported here so the copied files compile during the\n * extraction transition. Each consumer-facing field is also re-exported as\n * a TYPE alias for code that only needed the shape.\n */\nimport type { ReactNode } from 'react';\nimport type { NavItem, NavSection, StartMenuCategories, VirtualSection } from '../shell/nav-types';\n\n// Live proxy: WindowManager reads window-title icons from this module-level\n// map. Consumers register their full icon set once at app startup so the\n// title bars show the same glyphs as the start menu.\nconst _navIcons: Record<string, ReactNode> = {};\nexport const navIcons: Record<string, ReactNode> = new Proxy(_navIcons, {\n get(_t, k: string) { return _navIcons[k]; },\n has(_t, k: string) { return k in _navIcons; },\n ownKeys() { return Object.keys(_navIcons); },\n getOwnPropertyDescriptor(_t, k: string) {\n if (k in _navIcons) return { configurable: true, enumerable: true, value: _navIcons[k] };\n return undefined;\n },\n});\nexport function setShellNavIcons(icons: Record<string, ReactNode>): void {\n for (const k of Object.keys(_navIcons)) delete _navIcons[k];\n Object.assign(_navIcons, icons);\n}\n\nexport const sectionIcons: Record<string, ReactNode> = {};\nexport const navSections: (NavSection | NavItem)[] = [];\nexport const startMenuCategories: StartMenuCategories = { erp: [], system: [], virtual: [], footer: [] };\n\nexport { isSection } from '../shell/nav-types';\nexport type { NavItem, NavSection, StartMenuCategories, VirtualSection };\n","/**\n * Shell-side auth surface — JUST permission checking. The shell never\n * authenticates anyone or holds tokens; it only asks \"is the current user\n * allowed to see this nav item?\".\n *\n * Consumer wraps the app:\n *\n * <ShellAuthProvider value={{ hasAnyPerm: (perms) => myAuth.has(...perms) }}>\n * <Layout ... />\n * </ShellAuthProvider>\n *\n * When no provider is mounted, every permission check returns true — useful\n * for demos and consumers that don't gate their UI.\n */\nimport { createContext, useContext, type ReactNode } from 'react';\n\nexport interface ShellAuth {\n /** Returns true if the current user has any of the listed permission codes. */\n hasAnyPerm: (perms: string[]) => boolean;\n}\n\nconst DEFAULT: ShellAuth = { hasAnyPerm: () => true };\n\nconst ShellAuthContext = createContext<ShellAuth>(DEFAULT);\n\nexport function ShellAuthProvider({ value, children }: { value: ShellAuth; children: ReactNode }) {\n return <ShellAuthContext.Provider value={value}>{children}</ShellAuthContext.Provider>;\n}\n\nexport function useShellAuth(): ShellAuth {\n return useContext(ShellAuthContext);\n}\n","import type { CSSProperties } from 'react';\n\n/** Read the system menu opacity from CSS custom property set by Layout */\nfunction getMenuOpacity(): number {\n try {\n const val = getComputedStyle(document.documentElement).getPropertyValue('--menu-opacity')?.trim();\n if (val) return parseFloat(val);\n } catch {}\n return 0.95;\n}\n\nfunction isDarkTheme(): boolean {\n try {\n return document.documentElement.getAttribute('data-theme') === 'dark';\n } catch {\n return false;\n }\n}\n\n/** Whether the \"Reduce transparency\" preference is active (root class set by\n * Layout). When on, glass surfaces render solid + blur-free — the blur is the\n * GPU-expensive part, and dropping it is the point of the setting. */\nfunction reduceTransparency(): boolean {\n try {\n return document.documentElement.classList.contains('rosh-reduce-transparency');\n } catch {\n return false;\n }\n}\n\n/** Frosted glass style — shared across all menus, popups, and glass UI elements.\n * Reads --menu-opacity CSS variable set by the theme system, and adapts the\n * base tint to dark mode so menus don't stay light-cream when text is light. */\nexport function glassStyle(opacity?: number): CSSProperties {\n const o = opacity ?? getMenuOpacity();\n if (reduceTransparency()) {\n // Reduce-transparency: a fully opaque, blur-free surface. No\n // backdrop-filter (the expensive part on low-end GPUs) and a solid\n // background so menus/popups stay legible over any wallpaper. The global\n // stylesheet rule also strips backdrop-filter, but returning a solid\n // background here is what keeps the surface from reading as washed-out\n // translucent glass with the blur gone.\n return isDarkTheme()\n ? {\n background: '#1e1e2e',\n border: '1px solid rgba(255,255,255,0.12)',\n boxShadow: '0 8px 24px rgba(0,0,0,0.5)',\n }\n : {\n background: '#ffffff',\n border: '1px solid rgba(0,0,0,0.12)',\n boxShadow: '0 8px 24px rgba(0,0,0,0.18)',\n };\n }\n if (isDarkTheme()) {\n // Dark frosted glass — Catppuccin-aligned base (#1e1e2e / 30,30,46) with\n // a subtle gradient and lighter inner highlight.\n return {\n background: `linear-gradient(135deg, rgba(30,30,46,${o * 0.85}) 0%, rgba(24,24,37,${o * 0.75}) 50%, rgba(30,30,46,${o * 0.85}) 100%)`,\n backdropFilter: 'blur(40px) saturate(1.6)',\n WebkitBackdropFilter: 'blur(40px) saturate(1.6)',\n border: '1px solid rgba(255,255,255,0.08)',\n boxShadow: 'inset 0 1px 0 rgba(255,255,255,0.06), inset 0 -1px 0 rgba(0,0,0,0.4), 0 8px 32px rgba(0,0,0,0.5), 0 2px 8px rgba(0,0,0,0.3)',\n };\n }\n return {\n background: `linear-gradient(135deg, rgba(255,255,255,${o * 0.85}) 0%, rgba(255,255,255,${o * 0.65}) 50%, rgba(255,255,255,${o * 0.75}) 100%)`,\n backdropFilter: 'blur(40px) saturate(1.8)',\n WebkitBackdropFilter: 'blur(40px) saturate(1.8)',\n border: '1px solid rgba(255,255,255,0.35)',\n boxShadow: 'inset 0 1px 0 rgba(255,255,255,0.4), inset 0 -1px 0 rgba(255,255,255,0.1), 0 8px 32px rgba(0,0,0,0.15), 0 2px 8px rgba(0,0,0,0.08)',\n };\n}\n\n/** Glass divider border color */\nexport const GLASS_DIVIDER = 'border-white/20';\n\n/** Glass input/search bar background — declared in styles.css so it can adapt\n * to dark mode (a flat `bg-white/15` reads as a too-bright tile on the dark\n * glass gradient). */\nexport const GLASS_INPUT_BG = 'glass-input-bg';\n"]}
@@ -0,0 +1,7 @@
1
+ // src/version.ts
2
+ var VERSION = "4.3.1" ;
3
+ var APP_VERSION = VERSION;
4
+
5
+ export { APP_VERSION, VERSION };
6
+ //# sourceMappingURL=chunk-K6MB36UJ.js.map
7
+ //# sourceMappingURL=chunk-K6MB36UJ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/version.ts"],"names":[],"mappings":";AAIO,IAAM,OAAA,GAAwD,OAAA;AAG9D,IAAM,WAAA,GAAc","file":"chunk-D36OPVAT.js","sourcesContent":["declare const __PKG_VERSION__: string | undefined;\n\n/** Package version, injected by tsup at build time. Stays as an empty\n * string when the source is consumed without a build (e.g. tests). */\nexport const VERSION: string = typeof __PKG_VERSION__ === 'string' ? __PKG_VERSION__ : '';\n\n/** Legacy alias kept so existing consumers do not break. */\nexport const APP_VERSION = VERSION;\n"]}
1
+ {"version":3,"sources":["../src/version.ts"],"names":[],"mappings":";AAIO,IAAM,OAAA,GAAwD,OAAA;AAG9D,IAAM,WAAA,GAAc","file":"chunk-K6MB36UJ.js","sourcesContent":["declare const __PKG_VERSION__: string | undefined;\n\n/** Package version, injected by tsup at build time. Stays as an empty\n * string when the source is consumed without a build (e.g. tests). */\nexport const VERSION: string = typeof __PKG_VERSION__ === 'string' ? __PKG_VERSION__ : '';\n\n/** Legacy alias kept so existing consumers do not break. */\nexport const APP_VERSION = VERSION;\n"]}
@@ -1,4 +1,4 @@
1
- import { requestFilesTrashView } from './chunk-52RFL3OQ.js';
1
+ import { requestFilesTrashView } from './chunk-QAKURGOG.js';
2
2
 
3
3
  // src/apps/_filesShared.ts
4
4
  var filesDemoTree = null;
@@ -13,5 +13,5 @@ function openFilesInTrashMode() {
13
13
  }
14
14
 
15
15
  export { getFilesDemoTree, openFilesInTrashMode, setFilesDemoTree };
16
- //# sourceMappingURL=chunk-CWFH34LM.js.map
17
- //# sourceMappingURL=chunk-CWFH34LM.js.map
16
+ //# sourceMappingURL=chunk-LBY7KH2W.js.map
17
+ //# sourceMappingURL=chunk-LBY7KH2W.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/apps/_filesShared.ts"],"names":[],"mappings":";;;AAwBA,IAAI,aAAA,GAAwC,IAAA;AAErC,SAAS,iBAAiB,IAAA,EAA8B;AAC7D,EAAA,aAAA,GAAgB,IAAA;AAClB;AAGO,SAAS,gBAAA,GAA2C;AACzD,EAAA,OAAO,aAAA;AACT;AAKO,SAAS,oBAAA,GAAuB;AACrC,EAAA,qBAAA,EAAsB;AACxB","file":"chunk-CWFH34LM.js","sourcesContent":["/**\n * Files app config — the tiny consumer-facing surface of the Files app\n * (demo-tree injection + trash-mode open). Lives apart from Files.tsx so\n * importing these from `react-os-shell/apps` never drags the Files\n * implementation into a host's startup bundle; the Files window component\n * stays behind its React.lazy dynamic import.\n */\nimport { requestFilesTrashView } from '../shell/desktopIcons';\n\n/**\n * Demo filesystem. When a consumer (e.g. the demo app) injects a static tree\n * via `setFilesDemoTree`, Files browses it in-memory — no file server needed.\n * Browse-only: upload / new-folder / rename / delete / trash are hidden while a\n * demo tree is set. Consumers with a real file server never call it, so their\n * behaviour is unchanged.\n */\nexport interface FilesDemoNode {\n name: string;\n kind: 'file' | 'folder';\n size?: number;\n modifiedAt?: string;\n children?: FilesDemoNode[];\n}\n\nlet filesDemoTree: FilesDemoNode[] | null = null;\n\nexport function setFilesDemoTree(tree: FilesDemoNode[] | null) {\n filesDemoTree = tree;\n}\n\n/** @internal Current injected demo tree, if any — read by Files.tsx. */\nexport function getFilesDemoTree(): FilesDemoNode[] | null {\n return filesDemoTree;\n}\n\n// Side-channel for opening Files on a specific view (trash, desktop folder).\n// The flag + event plumbing lives in shell/desktopIcons.tsx; this wrapper is\n// kept because consumers import it from the package.\nexport function openFilesInTrashMode() {\n requestFilesTrashView();\n}\n"]}
1
+ {"version":3,"sources":["../src/apps/_filesShared.ts"],"names":[],"mappings":";;;AAwBA,IAAI,aAAA,GAAwC,IAAA;AAErC,SAAS,iBAAiB,IAAA,EAA8B;AAC7D,EAAA,aAAA,GAAgB,IAAA;AAClB;AAGO,SAAS,gBAAA,GAA2C;AACzD,EAAA,OAAO,aAAA;AACT;AAKO,SAAS,oBAAA,GAAuB;AACrC,EAAA,qBAAA,EAAsB;AACxB","file":"chunk-LBY7KH2W.js","sourcesContent":["/**\n * Files app config — the tiny consumer-facing surface of the Files app\n * (demo-tree injection + trash-mode open). Lives apart from Files.tsx so\n * importing these from `react-os-shell/apps` never drags the Files\n * implementation into a host's startup bundle; the Files window component\n * stays behind its React.lazy dynamic import.\n */\nimport { requestFilesTrashView } from '../shell/desktopIcons';\n\n/**\n * Demo filesystem. When a consumer (e.g. the demo app) injects a static tree\n * via `setFilesDemoTree`, Files browses it in-memory — no file server needed.\n * Browse-only: upload / new-folder / rename / delete / trash are hidden while a\n * demo tree is set. Consumers with a real file server never call it, so their\n * behaviour is unchanged.\n */\nexport interface FilesDemoNode {\n name: string;\n kind: 'file' | 'folder';\n size?: number;\n modifiedAt?: string;\n children?: FilesDemoNode[];\n}\n\nlet filesDemoTree: FilesDemoNode[] | null = null;\n\nexport function setFilesDemoTree(tree: FilesDemoNode[] | null) {\n filesDemoTree = tree;\n}\n\n/** @internal Current injected demo tree, if any — read by Files.tsx. */\nexport function getFilesDemoTree(): FilesDemoNode[] | null {\n return filesDemoTree;\n}\n\n// Side-channel for opening Files on a specific view (trash, desktop folder).\n// The flag + event plumbing lives in shell/desktopIcons.tsx; this wrapper is\n// kept because consumers import it from the package.\nexport function openFilesInTrashMode() {\n requestFilesTrashView();\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { Modal } from './chunk-SI4XHEMM.js';
1
+ import { Modal } from './chunk-VA6M46NL.js';
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
3
 
4
4
  var DEFAULT_APPEARANCE = { activeOpacity: 70, inactiveOpacity: 50, activeBlur: 0, inactiveBlur: 0 };
@@ -138,5 +138,5 @@ function WidgetSettingsModal({ open, onClose, title, appearance, onAppearanceCha
138
138
  }
139
139
 
140
140
  export { WidgetSettingsModal, loadAppearance };
141
- //# sourceMappingURL=chunk-QJXXSMPG.js.map
142
- //# sourceMappingURL=chunk-QJXXSMPG.js.map
141
+ //# sourceMappingURL=chunk-PMPJLVZV.js.map
142
+ //# sourceMappingURL=chunk-PMPJLVZV.js.map