react-os-shell 2.9.3 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Browser-3SDJFEZW.js +7 -0
- package/dist/{Browser-23ULR34J.js.map → Browser-3SDJFEZW.js.map} +1 -1
- package/dist/{Calculator-RI2AXFNQ.js → Calculator-LGYXEZTY.js} +4 -4
- package/dist/{Calculator-RI2AXFNQ.js.map → Calculator-LGYXEZTY.js.map} +1 -1
- package/dist/{CurrencyConverter-TVSLZLYL.js → CurrencyConverter-JI5ECSQA.js} +4 -4
- package/dist/{CurrencyConverter-TVSLZLYL.js.map → CurrencyConverter-JI5ECSQA.js.map} +1 -1
- package/dist/{Documents-BGCOIW5E.js → Documents-HCHGAFPB.js} +4 -4
- package/dist/{Documents-BGCOIW5E.js.map → Documents-HCHGAFPB.js.map} +1 -1
- package/dist/Files-FYWUNLBY.js +12 -0
- package/dist/{Files-X7ERMLDM.js.map → Files-FYWUNLBY.js.map} +1 -1
- package/dist/{Notepad-OTOYAF4L.js → Notepad-WRS7EMCK.js} +4 -4
- package/dist/{Notepad-OTOYAF4L.js.map → Notepad-WRS7EMCK.js.map} +1 -1
- package/dist/{PomodoroTimer-FZP7SKPY.js → PomodoroTimer-5WZ37PLI.js} +5 -5
- package/dist/{PomodoroTimer-FZP7SKPY.js.map → PomodoroTimer-5WZ37PLI.js.map} +1 -1
- package/dist/Preview-HOLQVFSU.js +8 -0
- package/dist/{Preview-XSX4HVK6.js.map → Preview-HOLQVFSU.js.map} +1 -1
- package/dist/Spreadsheet-MRUQ4LJR.js +7 -0
- package/dist/{Spreadsheet-4FOA6E6K.js.map → Spreadsheet-MRUQ4LJR.js.map} +1 -1
- package/dist/{Stock-36BKWEUO.js → Stock-ERDFTUOZ.js} +4 -4
- package/dist/{Stock-36BKWEUO.js.map → Stock-ERDFTUOZ.js.map} +1 -1
- package/dist/{Weather-QUHBOFVA.js → Weather-6WBY4ANL.js} +4 -4
- package/dist/{Weather-QUHBOFVA.js.map → Weather-6WBY4ANL.js.map} +1 -1
- package/dist/{WorldClock-2UY5R4L3.js → WorldClock-ZOLBVSJC.js} +4 -4
- package/dist/{WorldClock-2UY5R4L3.js.map → WorldClock-ZOLBVSJC.js.map} +1 -1
- package/dist/apps/index.js +19 -20
- package/dist/apps/index.js.map +1 -1
- package/dist/{chunk-BJS5UCR6.js → chunk-6OWYD4O6.js} +20 -7
- package/dist/chunk-6OWYD4O6.js.map +1 -0
- package/dist/{chunk-MIFS2574.js → chunk-6VMTAVUD.js} +3 -3
- package/dist/{chunk-MIFS2574.js.map → chunk-6VMTAVUD.js.map} +1 -1
- package/dist/{chunk-DVXRDQEN.js → chunk-D7QQTFM3.js} +4 -4
- package/dist/{chunk-DVXRDQEN.js.map → chunk-D7QQTFM3.js.map} +1 -1
- package/dist/{chunk-Y2L2DBL6.js → chunk-QS2MEW6R.js} +5 -5
- package/dist/{chunk-Y2L2DBL6.js.map → chunk-QS2MEW6R.js.map} +1 -1
- package/dist/{chunk-HKBUFA4V.js → chunk-SKNOGIDC.js} +997 -7
- package/dist/chunk-SKNOGIDC.js.map +1 -0
- package/dist/{chunk-HMV37F2X.js → chunk-X4MB43G2.js} +4 -4
- package/dist/{chunk-HMV37F2X.js.map → chunk-X4MB43G2.js.map} +1 -1
- package/dist/{chunk-T2P7CZ3S.js → chunk-XRBSB7FX.js} +3 -3
- package/dist/{chunk-T2P7CZ3S.js.map → chunk-XRBSB7FX.js.map} +1 -1
- package/dist/{chunk-YWANIOU6.js → chunk-XRCABX52.js} +4 -4
- package/dist/{chunk-YWANIOU6.js.map → chunk-XRCABX52.js.map} +1 -1
- package/dist/{chunk-UWNETCYO.js → chunk-XVCEFF6M.js} +4 -4
- package/dist/{chunk-UWNETCYO.js.map → chunk-XVCEFF6M.js.map} +1 -1
- package/dist/index.d.ts +1 -125
- package/dist/index.js +17 -512
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/Browser-23ULR34J.js +0 -7
- package/dist/Files-X7ERMLDM.js +0 -13
- package/dist/ImageAnnotator-55NPWJ2R.js +0 -4
- package/dist/ImageAnnotator-55NPWJ2R.js.map +0 -1
- package/dist/Preview-XSX4HVK6.js +0 -9
- package/dist/Spreadsheet-4FOA6E6K.js +0 -7
- package/dist/chunk-BJS5UCR6.js.map +0 -1
- package/dist/chunk-HKBUFA4V.js.map +0 -1
- package/dist/chunk-NUPYEVU4.js +0 -999
- package/dist/chunk-NUPYEVU4.js.map +0 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { Browser as default, setBrowserStartUrl } from './chunk-D7QQTFM3.js';
|
|
2
|
+
import './chunk-XRCABX52.js';
|
|
3
|
+
import './chunk-6OWYD4O6.js';
|
|
4
|
+
import './chunk-UBN4IUDE.js';
|
|
5
|
+
import './chunk-ZF6AYO4G.js';
|
|
6
|
+
//# sourceMappingURL=Browser-3SDJFEZW.js.map
|
|
7
|
+
//# sourceMappingURL=Browser-3SDJFEZW.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"Browser-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"Browser-3SDJFEZW.js"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { loadAppearance, WidgetSettingsModal } from './chunk-
|
|
2
|
-
import { useWidgetSettings } from './chunk-
|
|
1
|
+
import { loadAppearance, WidgetSettingsModal } from './chunk-XRBSB7FX.js';
|
|
2
|
+
import { useWidgetSettings } from './chunk-6OWYD4O6.js';
|
|
3
3
|
import './chunk-UBN4IUDE.js';
|
|
4
4
|
import './chunk-ZF6AYO4G.js';
|
|
5
5
|
import { useState, useCallback, useEffect } from 'react';
|
|
@@ -181,5 +181,5 @@ function Calculator() {
|
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
export { Calculator as default };
|
|
184
|
-
//# sourceMappingURL=Calculator-
|
|
185
|
-
//# sourceMappingURL=Calculator-
|
|
184
|
+
//# sourceMappingURL=Calculator-LGYXEZTY.js.map
|
|
185
|
+
//# sourceMappingURL=Calculator-LGYXEZTY.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/apps/Calculator.tsx"],"names":[],"mappings":"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","file":"Calculator-RI2AXFNQ.js","sourcesContent":["import { useState, useCallback, useEffect } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\n\ntype Op = '+' | '-' | '×' | '÷' | null;\nconst CALC_SETTINGS_KEY = 'calc_appearance';\n\nexport default function Calculator() {\n const [display, setDisplay] = useState('0');\n const [prev, setPrev] = useState<number | null>(null);\n const [op, setOp] = useState<Op>(null);\n const [resetNext, setResetNext] = useState(false);\n const [lastExpr, setLastExpr] = useState('');\n const [history, setHistory] = useState<string[]>([]);\n const [copied, setCopied] = useState(false);\n const [appearance, setAppearance] = useState(() => loadAppearance(CALC_SETTINGS_KEY));\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n\n useWidgetSettings(useCallback(() => {\n setConfigAppearance({ ...appearance });\n setSettingsOpen(true);\n }, [appearance]));\n\n const append = useCallback((ch: string) => {\n setLastExpr('');\n setDisplay(d => {\n if (resetNext || d === '0') {\n setResetNext(false);\n return ch === '.' ? '0.' : ch;\n }\n if (ch === '.' && d.includes('.')) return d;\n return d + ch;\n });\n }, [resetNext]);\n\n const clear = useCallback(() => {\n setDisplay('0');\n setPrev(null);\n setOp(null);\n setResetNext(false);\n }, []);\n\n const compute = useCallback((a: number, b: number, operator: Op): number => {\n switch (operator) {\n case '+': return a + b;\n case '-': return a - b;\n case '×': return a * b;\n case '÷': return b === 0 ? 0 : a / b;\n default: return b;\n }\n }, []);\n\n const handleOp = useCallback((nextOp: Op) => {\n const current = parseFloat(display);\n if (prev !== null && op && !resetNext) {\n const result = compute(prev, current, op);\n setDisplay(String(result));\n setPrev(result);\n setHistory(h => [`${prev} ${op} ${current} = ${result}`, ...h].slice(0, 20));\n } else {\n setPrev(current);\n }\n setOp(nextOp);\n setResetNext(true);\n }, [display, prev, op, resetNext, compute]);\n\n const equals = useCallback(() => {\n if (prev === null || !op) return;\n const current = parseFloat(display);\n const result = compute(prev, current, op);\n const expr = `${prev} ${op} ${current} =`;\n setHistory(h => [`${expr} ${result}`, ...h].slice(0, 20));\n setLastExpr(expr);\n setDisplay(String(result));\n setPrev(null);\n setOp(null);\n setResetNext(true);\n }, [display, prev, op, compute]);\n\n const percent = useCallback(() => {\n setDisplay(d => String(parseFloat(d) / 100));\n }, []);\n\n const negate = useCallback(() => {\n setDisplay(d => d.startsWith('-') ? d.slice(1) : d === '0' ? d : '-' + d);\n }, []);\n\n // Keyboard support\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n const tag = (e.target as HTMLElement).tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return;\n if (e.key >= '0' && e.key <= '9') append(e.key);\n else if (e.key === '.') append('.');\n else if (e.key === '+') handleOp('+');\n else if (e.key === '-') handleOp('-');\n else if (e.key === '*') handleOp('×');\n else if (e.key === '/') { e.preventDefault(); handleOp('÷'); }\n else if (e.key === 'Enter' || e.key === '=') equals();\n else if (e.key === 'Escape') clear();\n else if (e.key === 'Backspace') setDisplay(d => d.length > 1 ? d.slice(0, -1) : '0');\n else if (e.key === '%') percent();\n };\n window.addEventListener('keydown', handler);\n return () => window.removeEventListener('keydown', handler);\n }, [append, handleOp, equals, clear, percent]);\n\n const btn = 'flex items-center justify-center rounded-lg text-sm font-medium transition-colors';\n const numBtn = `${btn} bg-white border border-gray-200 text-gray-900 hover:bg-gray-50 active:bg-gray-100`;\n const opBtn = `${btn} bg-blue-50 border border-blue-200 text-blue-700 hover:bg-blue-100 active:bg-blue-200`;\n const fnBtn = `${btn} bg-gray-100 border border-gray-200 text-gray-600 hover:bg-gray-200 active:bg-gray-300`;\n const eqBtn = `${btn} bg-blue-600 text-white hover:bg-blue-700 active:bg-blue-800`;\n\n // Format display for readability\n const formatDisplay = (val: string) => {\n const num = parseFloat(val);\n if (isNaN(num)) return val;\n if (val.endsWith('.') || val.endsWith('.0')) return val;\n if (Math.abs(num) < 1e15 && val.length < 16) return val;\n return num.toExponential(6);\n };\n\n return (\n <>\n <div className=\"flex flex-col h-full\" style={{\n opacity: appearance.activeOpacity / 100,\n backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined,\n }}>\n {/* Display — 5-line area with history + current value */}\n <div className=\"bg-slate-200 rounded-t-lg px-4 py-2 group/display relative flex flex-col justify-end min-h-[120px] border-b border-slate-300\">\n {/* History lines (most recent at bottom, above current) */}\n <div className=\"flex flex-col justify-end flex-1 overflow-hidden\">\n {history.slice(0, 3).reverse().map((h, i) => (\n <div key={i} className=\"text-[11px] text-slate-400 text-right font-mono truncate\">{h}</div>\n ))}\n </div>\n {/* Current expression */}\n {(lastExpr || (op && prev !== null)) && (\n <div className=\"text-base text-slate-600 text-right font-mono\">\n {lastExpr || `${prev} ${op} ${!resetNext ? display : ''}`}\n </div>\n )}\n {/* Current value */}\n <div className=\"flex items-center gap-2\">\n <button onClick={() => { navigator.clipboard.writeText(display); setCopied(true); setTimeout(() => setCopied(false), 1200); }}\n title=\"Copy result\"\n className=\"shrink-0 text-slate-300 hover:text-slate-500 transition-colors opacity-0 group-hover/display:opacity-100\">\n {copied\n ? <svg className=\"h-5 w-5 text-green-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 13l4 4L19 7\" /></svg>\n : <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" /></svg>\n }\n </button>\n <div className=\"text-right text-4xl font-mono font-bold text-slate-800 truncate flex-1\">\n {formatDisplay(display)}\n </div>\n </div>\n </div>\n\n {/* Buttons */}\n <div className=\"grid grid-cols-4 grid-rows-5 gap-1.5 flex-1 min-h-0 p-2\">\n <button onClick={clear} className={fnBtn}>AC</button>\n <button onClick={negate} className={fnBtn}>+/−</button>\n <button onClick={percent} className={fnBtn}>%</button>\n <button onClick={() => handleOp('÷')} className={`${opBtn} ${op === '÷' ? 'ring-2 ring-blue-400' : ''}`}>÷</button>\n\n <button onClick={() => append('7')} className={numBtn}>7</button>\n <button onClick={() => append('8')} className={numBtn}>8</button>\n <button onClick={() => append('9')} className={numBtn}>9</button>\n <button onClick={() => handleOp('×')} className={`${opBtn} ${op === '×' ? 'ring-2 ring-blue-400' : ''}`}>×</button>\n\n <button onClick={() => append('4')} className={numBtn}>4</button>\n <button onClick={() => append('5')} className={numBtn}>5</button>\n <button onClick={() => append('6')} className={numBtn}>6</button>\n <button onClick={() => handleOp('-')} className={`${opBtn} ${op === '-' ? 'ring-2 ring-blue-400' : ''}`}>−</button>\n\n <button onClick={() => append('1')} className={numBtn}>1</button>\n <button onClick={() => append('2')} className={numBtn}>2</button>\n <button onClick={() => append('3')} className={numBtn}>3</button>\n <button onClick={() => handleOp('+')} className={`${opBtn} ${op === '+' ? 'ring-2 ring-blue-400' : ''}`}>+</button>\n\n <button onClick={() => append('0')} className={`${numBtn} col-span-2`}>0</button>\n <button onClick={() => append('.')} className={numBtn}>.</button>\n <button onClick={equals} className={eqBtn}>=</button>\n </div>\n\n </div>\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"Calculator Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance}\n onSave={() => { setAppearance(configAppearance); localStorage.setItem(CALC_SETTINGS_KEY, JSON.stringify(configAppearance)); setSettingsOpen(false); }} />\n </>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/apps/Calculator.tsx"],"names":[],"mappings":";;;;;;;AAKA,IAAM,iBAAA,GAAoB,iBAAA;AAEX,SAAR,UAAA,GAA8B;AACnC,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,GAAG,CAAA;AAC1C,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAwB,IAAI,CAAA;AACpD,EAAA,MAAM,CAAC,EAAA,EAAI,KAAK,CAAA,GAAI,SAAa,IAAI,CAAA;AACrC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAChD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,EAAE,CAAA;AAC3C,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,QAAA,CAAmB,EAAE,CAAA;AACnD,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAAS,KAAK,CAAA;AAC1C,EAAA,MAAM,CAAC,YAAY,aAAa,CAAA,GAAI,SAAS,MAAM,cAAA,CAAe,iBAAiB,CAAC,CAAA;AACpF,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAS,KAAK,CAAA;AACtD,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAI,SAA2B,UAAU,CAAA;AAErF,EAAA,iBAAA,CAAkB,YAAY,MAAM;AAClC,IAAA,mBAAA,CAAoB,EAAE,GAAG,UAAA,EAAY,CAAA;AACrC,IAAA,eAAA,CAAgB,IAAI,CAAA;AAAA,EACtB,CAAA,EAAG,CAAC,UAAU,CAAC,CAAC,CAAA;AAEhB,EAAA,MAAM,MAAA,GAAS,WAAA,CAAY,CAAC,EAAA,KAAe;AACzC,IAAA,WAAA,CAAY,EAAE,CAAA;AACd,IAAA,UAAA,CAAW,CAAA,CAAA,KAAK;AACd,MAAA,IAAI,SAAA,IAAa,MAAM,GAAA,EAAK;AAC1B,QAAA,YAAA,CAAa,KAAK,CAAA;AAClB,QAAA,OAAO,EAAA,KAAO,MAAM,IAAA,GAAO,EAAA;AAAA,MAC7B;AACA,MAAA,IAAI,OAAO,GAAA,IAAO,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,OAAO,CAAA;AAC1C,MAAA,OAAO,CAAA,GAAI,EAAA;AAAA,IACb,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,MAAM,KAAA,GAAQ,YAAY,MAAM;AAC9B,IAAA,UAAA,CAAW,GAAG,CAAA;AACd,IAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,IAAA,KAAA,CAAM,IAAI,CAAA;AACV,IAAA,YAAA,CAAa,KAAK,CAAA;AAAA,EACpB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,OAAA,GAAU,WAAA,CAAY,CAAC,CAAA,EAAW,GAAW,QAAA,KAAyB;AAC1E,IAAA,QAAQ,QAAA;AAAU,MAChB,KAAK,GAAA;AAAK,QAAA,OAAO,CAAA,GAAI,CAAA;AAAA,MACrB,KAAK,GAAA;AAAK,QAAA,OAAO,CAAA,GAAI,CAAA;AAAA,MACrB,KAAK,MAAA;AAAK,QAAA,OAAO,CAAA,GAAI,CAAA;AAAA,MACrB,KAAK,MAAA;AAAK,QAAA,OAAO,CAAA,KAAM,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,CAAA;AAAA,MACnC;AAAS,QAAA,OAAO,CAAA;AAAA;AAClB,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,QAAA,GAAW,WAAA,CAAY,CAAC,MAAA,KAAe;AAC3C,IAAA,MAAM,OAAA,GAAU,WAAW,OAAO,CAAA;AAClC,IAAA,IAAI,IAAA,KAAS,IAAA,IAAQ,EAAA,IAAM,CAAC,SAAA,EAAW;AACrC,MAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,IAAA,EAAM,OAAA,EAAS,EAAE,CAAA;AACxC,MAAA,UAAA,CAAW,MAAA,CAAO,MAAM,CAAC,CAAA;AACzB,MAAA,OAAA,CAAQ,MAAM,CAAA;AACd,MAAA,UAAA,CAAW,OAAK,CAAC,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA,EAAI,OAAO,CAAA,GAAA,EAAM,MAAM,IAAI,GAAG,CAAC,EAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA;AAAA,IAC7E,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,OAAO,CAAA;AAAA,IACjB;AACA,IAAA,KAAA,CAAM,MAAM,CAAA;AACZ,IAAA,YAAA,CAAa,IAAI,CAAA;AAAA,EACnB,GAAG,CAAC,OAAA,EAAS,MAAM,EAAA,EAAI,SAAA,EAAW,OAAO,CAAC,CAAA;AAE1C,EAAA,MAAM,MAAA,GAAS,YAAY,MAAM;AAC/B,IAAA,IAAI,IAAA,KAAS,IAAA,IAAQ,CAAC,EAAA,EAAI;AAC1B,IAAA,MAAM,OAAA,GAAU,WAAW,OAAO,CAAA;AAClC,IAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,IAAA,EAAM,OAAA,EAAS,EAAE,CAAA;AACxC,IAAA,MAAM,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,EAAE,IAAI,OAAO,CAAA,EAAA,CAAA;AACrC,IAAA,UAAA,CAAW,CAAA,CAAA,KAAK,CAAC,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA,EAAI,GAAG,CAAC,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA;AACxD,IAAA,WAAA,CAAY,IAAI,CAAA;AAChB,IAAA,UAAA,CAAW,MAAA,CAAO,MAAM,CAAC,CAAA;AACzB,IAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,IAAA,KAAA,CAAM,IAAI,CAAA;AACV,IAAA,YAAA,CAAa,IAAI,CAAA;AAAA,EACnB,GAAG,CAAC,OAAA,EAAS,IAAA,EAAM,EAAA,EAAI,OAAO,CAAC,CAAA;AAE/B,EAAA,MAAM,OAAA,GAAU,YAAY,MAAM;AAChC,IAAA,UAAA,CAAW,OAAK,MAAA,CAAO,UAAA,CAAW,CAAC,CAAA,GAAI,GAAG,CAAC,CAAA;AAAA,EAC7C,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,MAAA,GAAS,YAAY,MAAM;AAC/B,IAAA,UAAA,CAAW,CAAA,CAAA,KAAK,CAAA,CAAE,UAAA,CAAW,GAAG,CAAA,GAAI,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,GAAI,CAAA,KAAM,GAAA,GAAM,CAAA,GAAI,MAAM,CAAC,CAAA;AAAA,EAC1E,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,OAAA,GAAU,CAAC,CAAA,KAAqB;AACpC,MAAA,MAAM,GAAA,GAAO,EAAE,MAAA,CAAuB,OAAA;AACtC,MAAA,IAAI,GAAA,KAAQ,OAAA,IAAW,GAAA,KAAQ,UAAA,IAAc,QAAQ,QAAA,EAAU;AAC/D,MAAA,IAAI,CAAA,CAAE,OAAO,GAAA,IAAO,CAAA,CAAE,OAAO,GAAA,EAAK,MAAA,CAAO,EAAE,GAAG,CAAA;AAAA,WAAA,IACrC,CAAA,CAAE,GAAA,KAAQ,GAAA,EAAK,MAAA,CAAO,GAAG,CAAA;AAAA,WAAA,IACzB,CAAA,CAAE,GAAA,KAAQ,GAAA,EAAK,QAAA,CAAS,GAAG,CAAA;AAAA,WAAA,IAC3B,CAAA,CAAE,GAAA,KAAQ,GAAA,EAAK,QAAA,CAAS,GAAG,CAAA;AAAA,WAAA,IAC3B,CAAA,CAAE,GAAA,KAAQ,GAAA,EAAK,QAAA,CAAS,MAAG,CAAA;AAAA,WAAA,IAC3B,CAAA,CAAE,QAAQ,GAAA,EAAK;AAAE,QAAA,CAAA,CAAE,cAAA,EAAe;AAAG,QAAA,QAAA,CAAS,MAAG,CAAA;AAAA,MAAG,WACpD,CAAA,CAAE,GAAA,KAAQ,WAAW,CAAA,CAAE,GAAA,KAAQ,KAAK,MAAA,EAAO;AAAA,WAAA,IAC3C,CAAA,CAAE,GAAA,KAAQ,QAAA,EAAU,KAAA,EAAM;AAAA,WAAA,IAC1B,CAAA,CAAE,GAAA,KAAQ,WAAA,EAAa,UAAA,CAAW,CAAA,CAAA,KAAK,CAAA,CAAE,MAAA,GAAS,CAAA,GAAI,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,IAAI,GAAG,CAAA;AAAA,WAAA,IAC1E,CAAA,CAAE,GAAA,KAAQ,GAAA,EAAK,OAAA,EAAQ;AAAA,IAClC,CAAA;AACA,IAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,OAAO,CAAA;AAC1C,IAAA,OAAO,MAAM,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,OAAO,CAAA;AAAA,EAC5D,GAAG,CAAC,MAAA,EAAQ,UAAU,MAAA,EAAQ,KAAA,EAAO,OAAO,CAAC,CAAA;AAE7C,EAAA,MAAM,GAAA,GAAM,mFAAA;AACZ,EAAA,MAAM,MAAA,GAAS,GAAG,GAAG,CAAA,kFAAA,CAAA;AACrB,EAAA,MAAM,KAAA,GAAQ,GAAG,GAAG,CAAA,qFAAA,CAAA;AACpB,EAAA,MAAM,KAAA,GAAQ,GAAG,GAAG,CAAA,sFAAA,CAAA;AACpB,EAAA,MAAM,KAAA,GAAQ,GAAG,GAAG,CAAA,4DAAA,CAAA;AAGpB,EAAA,MAAM,aAAA,GAAgB,CAAC,GAAA,KAAgB;AACrC,IAAA,MAAM,GAAA,GAAM,WAAW,GAAG,CAAA;AAC1B,IAAA,IAAI,KAAA,CAAM,GAAG,CAAA,EAAG,OAAO,GAAA;AACvB,IAAA,IAAI,GAAA,CAAI,SAAS,GAAG,CAAA,IAAK,IAAI,QAAA,CAAS,IAAI,GAAG,OAAO,GAAA;AACpD,IAAA,IAAI,IAAA,CAAK,IAAI,GAAG,CAAA,GAAI,QAAQ,GAAA,CAAI,MAAA,GAAS,IAAI,OAAO,GAAA;AACpD,IAAA,OAAO,GAAA,CAAI,cAAc,CAAC,CAAA;AAAA,EAC5B,CAAA;AAEA,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACA,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sBAAA,EAAuB,KAAA,EAAO;AAAA,MAC3C,OAAA,EAAS,WAAW,aAAA,GAAgB,GAAA;AAAA,MACpC,gBAAgB,UAAA,CAAW,UAAA,GAAa,IAAI,CAAA,KAAA,EAAQ,UAAA,CAAW,UAAU,CAAA,GAAA,CAAA,GAAQ;AAAA,KACnF,EAEE,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,8HAAA,EAEb,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,WAAU,kDAAA,EACZ,QAAA,EAAA,OAAA,CAAQ,MAAM,CAAA,EAAG,CAAC,EAAE,OAAA,EAAQ,CAAE,IAAI,CAAC,CAAA,EAAG,sBACrC,GAAA,CAAC,KAAA,EAAA,EAAY,WAAU,0DAAA,EAA4D,QAAA,EAAA,CAAA,EAAA,EAAzE,CAA2E,CACtF,CAAA,EACH,CAAA;AAAA,QAAA,CAEE,YAAa,EAAA,IAAM,IAAA,KAAS,yBAC5B,GAAA,CAAC,KAAA,EAAA,EAAI,WAAU,+CAAA,EACZ,QAAA,EAAA,QAAA,IAAY,CAAA,EAAG,IAAI,IAAI,EAAE,CAAA,CAAA,EAAI,CAAC,SAAA,GAAY,OAAA,GAAU,EAAE,CAAA,CAAA,EACzD,CAAA;AAAA,wBAGF,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACb,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cAAO,SAAS,MAAM;AAAE,gBAAA,SAAA,CAAU,SAAA,CAAU,UAAU,OAAO,CAAA;AAAG,gBAAA,SAAA,CAAU,IAAI,CAAA;AAAG,gBAAA,UAAA,CAAW,MAAM,SAAA,CAAU,KAAK,CAAA,EAAG,IAAI,CAAA;AAAA,cAAG,CAAA;AAAA,cAC1H,KAAA,EAAM,aAAA;AAAA,cACN,SAAA,EAAU,0GAAA;AAAA,cACT,mCACG,GAAA,CAAC,KAAA,EAAA,EAAI,WAAU,wBAAA,EAAyB,IAAA,EAAK,QAAO,OAAA,EAAQ,WAAA,EAAY,QAAO,cAAA,EAAe,WAAA,EAAa,GAAG,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,eAAc,OAAA,EAAQ,cAAA,EAAe,SAAQ,CAAA,EAAE,gBAAA,EAAiB,GAAE,CAAA,mBACtL,GAAA,CAAC,SAAI,SAAA,EAAU,SAAA,EAAU,MAAK,MAAA,EAAO,OAAA,EAAQ,aAAY,MAAA,EAAO,cAAA,EAAe,aAAa,CAAA,EAAG,QAAA,kBAAA,GAAA,CAAC,UAAK,aAAA,EAAc,OAAA,EAAQ,gBAAe,OAAA,EAAQ,CAAA,EAAE,yHAAwH,CAAA,EAAE;AAAA;AAAA,WAEpR;AAAA,8BACC,KAAA,EAAA,EAAI,SAAA,EAAU,wEAAA,EACZ,QAAA,EAAA,aAAA,CAAc,OAAO,CAAA,EACxB;AAAA,SAAA,EACF;AAAA,OAAA,EACF,CAAA;AAAA,sBAGA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yDAAA,EACb,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,QAAA,EAAA,EAAO,OAAA,EAAS,KAAA,EAAO,SAAA,EAAW,OAAO,QAAA,EAAA,IAAA,EAAE,CAAA;AAAA,4BAC3C,QAAA,EAAA,EAAO,OAAA,EAAS,MAAA,EAAQ,SAAA,EAAW,OAAO,QAAA,EAAA,UAAA,EAAG,CAAA;AAAA,4BAC7C,QAAA,EAAA,EAAO,OAAA,EAAS,OAAA,EAAS,SAAA,EAAW,OAAO,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,4BAC5C,QAAA,EAAA,EAAO,OAAA,EAAS,MAAM,QAAA,CAAS,MAAG,CAAA,EAAG,SAAA,EAAW,CAAA,EAAG,KAAK,IAAI,EAAA,KAAO,MAAA,GAAM,sBAAA,GAAyB,EAAE,IAAI,QAAA,EAAA,MAAA,EAAC,CAAA;AAAA,wBAE1G,GAAA,CAAC,YAAO,OAAA,EAAS,MAAM,OAAO,GAAG,CAAA,EAAG,SAAA,EAAW,MAAA,EAAQ,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,wBACxD,GAAA,CAAC,YAAO,OAAA,EAAS,MAAM,OAAO,GAAG,CAAA,EAAG,SAAA,EAAW,MAAA,EAAQ,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,wBACxD,GAAA,CAAC,YAAO,OAAA,EAAS,MAAM,OAAO,GAAG,CAAA,EAAG,SAAA,EAAW,MAAA,EAAQ,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,4BACvD,QAAA,EAAA,EAAO,OAAA,EAAS,MAAM,QAAA,CAAS,MAAG,CAAA,EAAG,SAAA,EAAW,CAAA,EAAG,KAAK,IAAI,EAAA,KAAO,MAAA,GAAM,sBAAA,GAAyB,EAAE,IAAI,QAAA,EAAA,MAAA,EAAC,CAAA;AAAA,wBAE1G,GAAA,CAAC,YAAO,OAAA,EAAS,MAAM,OAAO,GAAG,CAAA,EAAG,SAAA,EAAW,MAAA,EAAQ,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,wBACxD,GAAA,CAAC,YAAO,OAAA,EAAS,MAAM,OAAO,GAAG,CAAA,EAAG,SAAA,EAAW,MAAA,EAAQ,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,wBACxD,GAAA,CAAC,YAAO,OAAA,EAAS,MAAM,OAAO,GAAG,CAAA,EAAG,SAAA,EAAW,MAAA,EAAQ,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,4BACvD,QAAA,EAAA,EAAO,OAAA,EAAS,MAAM,QAAA,CAAS,GAAG,CAAA,EAAG,SAAA,EAAW,CAAA,EAAG,KAAK,IAAI,EAAA,KAAO,GAAA,GAAM,sBAAA,GAAyB,EAAE,IAAI,QAAA,EAAA,QAAA,EAAC,CAAA;AAAA,wBAE1G,GAAA,CAAC,YAAO,OAAA,EAAS,MAAM,OAAO,GAAG,CAAA,EAAG,SAAA,EAAW,MAAA,EAAQ,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,wBACxD,GAAA,CAAC,YAAO,OAAA,EAAS,MAAM,OAAO,GAAG,CAAA,EAAG,SAAA,EAAW,MAAA,EAAQ,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,wBACxD,GAAA,CAAC,YAAO,OAAA,EAAS,MAAM,OAAO,GAAG,CAAA,EAAG,SAAA,EAAW,MAAA,EAAQ,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,4BACvD,QAAA,EAAA,EAAO,OAAA,EAAS,MAAM,QAAA,CAAS,GAAG,CAAA,EAAG,SAAA,EAAW,CAAA,EAAG,KAAK,IAAI,EAAA,KAAO,GAAA,GAAM,sBAAA,GAAyB,EAAE,IAAI,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,wBAE1G,GAAA,CAAC,QAAA,EAAA,EAAO,OAAA,EAAS,MAAM,MAAA,CAAO,GAAG,CAAA,EAAG,SAAA,EAAW,CAAA,EAAG,MAAM,CAAA,WAAA,CAAA,EAAe,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,wBACxE,GAAA,CAAC,YAAO,OAAA,EAAS,MAAM,OAAO,GAAG,CAAA,EAAG,SAAA,EAAW,MAAA,EAAQ,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,4BACvD,QAAA,EAAA,EAAO,OAAA,EAAS,MAAA,EAAQ,SAAA,EAAW,OAAO,QAAA,EAAA,GAAA,EAAC;AAAA,OAAA,EAC9C;AAAA,KAAA,EAEF,CAAA;AAAA,oBACA,GAAA;AAAA,MAAC,mBAAA;AAAA,MAAA;AAAA,QAAoB,IAAA,EAAM,YAAA;AAAA,QAAc,OAAA,EAAS,MAAM,eAAA,CAAgB,KAAK,CAAA;AAAA,QAAG,KAAA,EAAM,qBAAA;AAAA,QACpF,UAAA,EAAY,gBAAA;AAAA,QAAkB,kBAAA,EAAoB,mBAAA;AAAA,QAClD,QAAQ,MAAM;AAAE,UAAA,aAAA,CAAc,gBAAgB,CAAA;AAAG,UAAA,YAAA,CAAa,OAAA,CAAQ,iBAAA,EAAmB,IAAA,CAAK,SAAA,CAAU,gBAAgB,CAAC,CAAA;AAAG,UAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,QAAG;AAAA;AAAA;AAAG,GAAA,EACzJ,CAAA;AAEJ","file":"Calculator-LGYXEZTY.js","sourcesContent":["import { useState, useCallback, useEffect } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\n\ntype Op = '+' | '-' | '×' | '÷' | null;\nconst CALC_SETTINGS_KEY = 'calc_appearance';\n\nexport default function Calculator() {\n const [display, setDisplay] = useState('0');\n const [prev, setPrev] = useState<number | null>(null);\n const [op, setOp] = useState<Op>(null);\n const [resetNext, setResetNext] = useState(false);\n const [lastExpr, setLastExpr] = useState('');\n const [history, setHistory] = useState<string[]>([]);\n const [copied, setCopied] = useState(false);\n const [appearance, setAppearance] = useState(() => loadAppearance(CALC_SETTINGS_KEY));\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n\n useWidgetSettings(useCallback(() => {\n setConfigAppearance({ ...appearance });\n setSettingsOpen(true);\n }, [appearance]));\n\n const append = useCallback((ch: string) => {\n setLastExpr('');\n setDisplay(d => {\n if (resetNext || d === '0') {\n setResetNext(false);\n return ch === '.' ? '0.' : ch;\n }\n if (ch === '.' && d.includes('.')) return d;\n return d + ch;\n });\n }, [resetNext]);\n\n const clear = useCallback(() => {\n setDisplay('0');\n setPrev(null);\n setOp(null);\n setResetNext(false);\n }, []);\n\n const compute = useCallback((a: number, b: number, operator: Op): number => {\n switch (operator) {\n case '+': return a + b;\n case '-': return a - b;\n case '×': return a * b;\n case '÷': return b === 0 ? 0 : a / b;\n default: return b;\n }\n }, []);\n\n const handleOp = useCallback((nextOp: Op) => {\n const current = parseFloat(display);\n if (prev !== null && op && !resetNext) {\n const result = compute(prev, current, op);\n setDisplay(String(result));\n setPrev(result);\n setHistory(h => [`${prev} ${op} ${current} = ${result}`, ...h].slice(0, 20));\n } else {\n setPrev(current);\n }\n setOp(nextOp);\n setResetNext(true);\n }, [display, prev, op, resetNext, compute]);\n\n const equals = useCallback(() => {\n if (prev === null || !op) return;\n const current = parseFloat(display);\n const result = compute(prev, current, op);\n const expr = `${prev} ${op} ${current} =`;\n setHistory(h => [`${expr} ${result}`, ...h].slice(0, 20));\n setLastExpr(expr);\n setDisplay(String(result));\n setPrev(null);\n setOp(null);\n setResetNext(true);\n }, [display, prev, op, compute]);\n\n const percent = useCallback(() => {\n setDisplay(d => String(parseFloat(d) / 100));\n }, []);\n\n const negate = useCallback(() => {\n setDisplay(d => d.startsWith('-') ? d.slice(1) : d === '0' ? d : '-' + d);\n }, []);\n\n // Keyboard support\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n const tag = (e.target as HTMLElement).tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return;\n if (e.key >= '0' && e.key <= '9') append(e.key);\n else if (e.key === '.') append('.');\n else if (e.key === '+') handleOp('+');\n else if (e.key === '-') handleOp('-');\n else if (e.key === '*') handleOp('×');\n else if (e.key === '/') { e.preventDefault(); handleOp('÷'); }\n else if (e.key === 'Enter' || e.key === '=') equals();\n else if (e.key === 'Escape') clear();\n else if (e.key === 'Backspace') setDisplay(d => d.length > 1 ? d.slice(0, -1) : '0');\n else if (e.key === '%') percent();\n };\n window.addEventListener('keydown', handler);\n return () => window.removeEventListener('keydown', handler);\n }, [append, handleOp, equals, clear, percent]);\n\n const btn = 'flex items-center justify-center rounded-lg text-sm font-medium transition-colors';\n const numBtn = `${btn} bg-white border border-gray-200 text-gray-900 hover:bg-gray-50 active:bg-gray-100`;\n const opBtn = `${btn} bg-blue-50 border border-blue-200 text-blue-700 hover:bg-blue-100 active:bg-blue-200`;\n const fnBtn = `${btn} bg-gray-100 border border-gray-200 text-gray-600 hover:bg-gray-200 active:bg-gray-300`;\n const eqBtn = `${btn} bg-blue-600 text-white hover:bg-blue-700 active:bg-blue-800`;\n\n // Format display for readability\n const formatDisplay = (val: string) => {\n const num = parseFloat(val);\n if (isNaN(num)) return val;\n if (val.endsWith('.') || val.endsWith('.0')) return val;\n if (Math.abs(num) < 1e15 && val.length < 16) return val;\n return num.toExponential(6);\n };\n\n return (\n <>\n <div className=\"flex flex-col h-full\" style={{\n opacity: appearance.activeOpacity / 100,\n backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined,\n }}>\n {/* Display — 5-line area with history + current value */}\n <div className=\"bg-slate-200 rounded-t-lg px-4 py-2 group/display relative flex flex-col justify-end min-h-[120px] border-b border-slate-300\">\n {/* History lines (most recent at bottom, above current) */}\n <div className=\"flex flex-col justify-end flex-1 overflow-hidden\">\n {history.slice(0, 3).reverse().map((h, i) => (\n <div key={i} className=\"text-[11px] text-slate-400 text-right font-mono truncate\">{h}</div>\n ))}\n </div>\n {/* Current expression */}\n {(lastExpr || (op && prev !== null)) && (\n <div className=\"text-base text-slate-600 text-right font-mono\">\n {lastExpr || `${prev} ${op} ${!resetNext ? display : ''}`}\n </div>\n )}\n {/* Current value */}\n <div className=\"flex items-center gap-2\">\n <button onClick={() => { navigator.clipboard.writeText(display); setCopied(true); setTimeout(() => setCopied(false), 1200); }}\n title=\"Copy result\"\n className=\"shrink-0 text-slate-300 hover:text-slate-500 transition-colors opacity-0 group-hover/display:opacity-100\">\n {copied\n ? <svg className=\"h-5 w-5 text-green-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 13l4 4L19 7\" /></svg>\n : <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" /></svg>\n }\n </button>\n <div className=\"text-right text-4xl font-mono font-bold text-slate-800 truncate flex-1\">\n {formatDisplay(display)}\n </div>\n </div>\n </div>\n\n {/* Buttons */}\n <div className=\"grid grid-cols-4 grid-rows-5 gap-1.5 flex-1 min-h-0 p-2\">\n <button onClick={clear} className={fnBtn}>AC</button>\n <button onClick={negate} className={fnBtn}>+/−</button>\n <button onClick={percent} className={fnBtn}>%</button>\n <button onClick={() => handleOp('÷')} className={`${opBtn} ${op === '÷' ? 'ring-2 ring-blue-400' : ''}`}>÷</button>\n\n <button onClick={() => append('7')} className={numBtn}>7</button>\n <button onClick={() => append('8')} className={numBtn}>8</button>\n <button onClick={() => append('9')} className={numBtn}>9</button>\n <button onClick={() => handleOp('×')} className={`${opBtn} ${op === '×' ? 'ring-2 ring-blue-400' : ''}`}>×</button>\n\n <button onClick={() => append('4')} className={numBtn}>4</button>\n <button onClick={() => append('5')} className={numBtn}>5</button>\n <button onClick={() => append('6')} className={numBtn}>6</button>\n <button onClick={() => handleOp('-')} className={`${opBtn} ${op === '-' ? 'ring-2 ring-blue-400' : ''}`}>−</button>\n\n <button onClick={() => append('1')} className={numBtn}>1</button>\n <button onClick={() => append('2')} className={numBtn}>2</button>\n <button onClick={() => append('3')} className={numBtn}>3</button>\n <button onClick={() => handleOp('+')} className={`${opBtn} ${op === '+' ? 'ring-2 ring-blue-400' : ''}`}>+</button>\n\n <button onClick={() => append('0')} className={`${numBtn} col-span-2`}>0</button>\n <button onClick={() => append('.')} className={numBtn}>.</button>\n <button onClick={equals} className={eqBtn}>=</button>\n </div>\n\n </div>\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"Calculator Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance}\n onSave={() => { setAppearance(configAppearance); localStorage.setItem(CALC_SETTINGS_KEY, JSON.stringify(configAppearance)); setSettingsOpen(false); }} />\n </>\n );\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { loadAppearance, WidgetSettingsModal } from './chunk-
|
|
2
|
-
import { useWidgetSettings } from './chunk-
|
|
1
|
+
import { loadAppearance, WidgetSettingsModal } from './chunk-XRBSB7FX.js';
|
|
2
|
+
import { useWidgetSettings } from './chunk-6OWYD4O6.js';
|
|
3
3
|
import './chunk-UBN4IUDE.js';
|
|
4
4
|
import './chunk-ZF6AYO4G.js';
|
|
5
5
|
import { useState, useCallback, useEffect } from 'react';
|
|
@@ -225,5 +225,5 @@ function CurrencyConverter() {
|
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
export { CurrencyConverter as default };
|
|
228
|
-
//# sourceMappingURL=CurrencyConverter-
|
|
229
|
-
//# sourceMappingURL=CurrencyConverter-
|
|
228
|
+
//# sourceMappingURL=CurrencyConverter-JI5ECSQA.js.map
|
|
229
|
+
//# sourceMappingURL=CurrencyConverter-JI5ECSQA.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/apps/CurrencyConverter.tsx"],"names":[],"mappings":"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","file":"CurrencyConverter-TVSLZLYL.js","sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\n\nconst ALL_CURRENCIES = ['USD', 'CNY', 'AUD', 'GBP', 'EUR', 'JPY', 'CAD', 'THB', 'NZD', 'SGD', 'HKD', 'CHF', 'KRW', 'INR', 'MXN', 'BRL'];\n\n/** Cap the rate list at 4 — keeps the widget compact and avoids\n * overwhelming the user with currencies they don't actually track. */\nconst MAX_PAIRS = 4;\n\nconst DEFAULT_PAIRS: [string, string][] = [\n ['USD', 'CNY'], ['USD', 'AUD'], ['GBP', 'USD'], ['USD', 'JPY'],\n];\n\nconst PAIRS_KEY = 'currency_pairs';\nconst SETTINGS_KEY = 'currency_appearance';\nconst CACHE_KEY = 'currency_rates_cache';\nconst CACHE_TTL = 3600000;\n\ntype CacheEntry = { rates: Record<string, number>; timestamp: number };\n\nfunction getCached(base: string): Record<string, number> | null {\n try { const c: Record<string, CacheEntry> = JSON.parse(localStorage.getItem(CACHE_KEY) || '{}'); const e = c[base]; if (e && Date.now() - e.timestamp < CACHE_TTL) return e.rates; } catch {} return null;\n}\nfunction setCache(base: string, rates: Record<string, number>) {\n try { const c = JSON.parse(localStorage.getItem(CACHE_KEY) || '{}'); c[base] = { rates, timestamp: Date.now() }; localStorage.setItem(CACHE_KEY, JSON.stringify(c)); } catch {}\n}\nfunction loadPairs(): [string, string][] {\n try {\n const s = JSON.parse(localStorage.getItem(PAIRS_KEY) || '');\n if (Array.isArray(s) && s.length) return s.slice(0, MAX_PAIRS);\n } catch {}\n return DEFAULT_PAIRS;\n}\n\nconst FLAG: Record<string, string> = {\n USD: '\\u{1F1FA}\\u{1F1F8}', CNY: '\\u{1F1E8}\\u{1F1F3}', AUD: '\\u{1F1E6}\\u{1F1FA}',\n GBP: '\\u{1F1EC}\\u{1F1E7}', JPY: '\\u{1F1EF}\\u{1F1F5}', CAD: '\\u{1F1E8}\\u{1F1E6}',\n EUR: '\\u{1F1EA}\\u{1F1FA}', THB: '\\u{1F1F9}\\u{1F1ED}', NZD: '\\u{1F1F3}\\u{1F1FF}',\n SGD: '\\u{1F1F8}\\u{1F1EC}', HKD: '\\u{1F1ED}\\u{1F1F0}', CHF: '\\u{1F1E8}\\u{1F1ED}',\n KRW: '\\u{1F1F0}\\u{1F1F7}', INR: '\\u{1F1EE}\\u{1F1F3}', MXN: '\\u{1F1F2}\\u{1F1FD}',\n BRL: '\\u{1F1E7}\\u{1F1F7}',\n};\n\nexport default function CurrencyConverter() {\n const [pairs, setPairs] = useState(loadPairs);\n const [appearance, setAppearance] = useState(() => loadAppearance(SETTINGS_KEY));\n const [allRates, setAllRates] = useState<Record<string, Record<string, number>>>({});\n const [loading, setLoading] = useState(false);\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configPairs, setConfigPairs] = useState<[string, string][]>([]);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n const [newFrom, setNewFrom] = useState('USD');\n const [newTo, setNewTo] = useState('CNY');\n\n useWidgetSettings(useCallback(() => {\n setConfigPairs([...pairs]);\n setConfigAppearance({ ...appearance });\n setSettingsOpen(true);\n }, [pairs, appearance]));\n\n useEffect(() => {\n const bases = [...new Set(pairs.map(([from]) => from))];\n let mounted = true;\n async function fetchAll() {\n setLoading(true);\n const result: Record<string, Record<string, number>> = {};\n for (const base of bases) {\n const cached = getCached(base);\n if (cached) { result[base] = cached; continue; }\n try { const res = await fetch(`https://open.er-api.com/v6/latest/${base}`); const data = await res.json(); if (data.rates) { result[base] = data.rates; setCache(base, data.rates); } } catch {}\n }\n if (mounted) { setAllRates(result); setLoading(false); }\n }\n fetchAll();\n return () => { mounted = false; };\n }, [pairs]);\n\n const saveSettings = () => {\n if (configPairs.length === 0) return;\n const capped = configPairs.slice(0, MAX_PAIRS);\n setPairs(capped); setAppearance(configAppearance);\n localStorage.setItem(PAIRS_KEY, JSON.stringify(capped));\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(configAppearance));\n setSettingsOpen(false);\n };\n\n return (\n <>\n {/* Theme-aware panel — pulls the same `--taskbar-bg-rgb` colour the\n * taskbar uses so the widget matches it across all themes\n * (gray-100-ish on light, Catppuccin mantle in dark). Tailwind\n * gray-* text/border classes auto-invert in dark via the existing\n * `[data-theme=\"dark\"]` overrides in styles.css.\n *\n * A plain naturally-flowing div — deliberately no `h-full`/`flex-1`, so\n * the window's `autoHeight` measurement hugs these rows instead of\n * reading the root as fill-height and pinning the window to its full\n * `dimensions` height (320×480) with empty space below the rows. */}\n <div\n style={{ backgroundColor: `rgb(var(--taskbar-bg-rgb, 243 244 246) / ${appearance.activeOpacity / 100})`, backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined }}>\n <div className=\"px-4 py-3 space-y-1\">\n {loading && <div className=\"text-xs text-gray-400 text-center py-4\">Loading rates...</div>}\n {pairs.map(([from, to], idx) => {\n const rate = allRates[from]?.[to];\n return (\n <button key={`${from}-${to}-${idx}`} onClick={() => {\n const swapped: [string, string][] = pairs.map((p, i) => i === idx ? [p[1], p[0]] : p);\n setPairs(swapped);\n localStorage.setItem(PAIRS_KEY, JSON.stringify(swapped));\n }}\n className=\"flex items-center justify-between px-2 py-2 border-b border-gray-200 last:border-0 w-full hover:bg-gray-100 rounded transition-colors cursor-pointer\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-base\">{FLAG[from] || ''}</span>\n <span className=\"text-sm font-semibold text-gray-700\">{from}</span>\n <svg className=\"h-3 w-3 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4\" /></svg>\n <span className=\"text-base\">{FLAG[to] || ''}</span>\n <span className=\"text-sm font-semibold text-gray-700\">{to}</span>\n </div>\n <div className=\"text-base font-mono font-semibold text-gray-900 tabular-nums\">\n {rate != null ? rate.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 4 }) : '—'}\n </div>\n </button>\n );\n })}\n </div>\n </div>\n\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"Currency Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance} onSave={saveSettings}>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Currency Pairs <span className=\"text-[11px] font-normal text-gray-400\">({configPairs.length}/{MAX_PAIRS})</span></h3>\n <div className=\"space-y-1 mb-2\">\n {configPairs.map(([f, t], i) => (\n <div key={i} className=\"flex items-center justify-between py-1 px-2 bg-gray-50 rounded\">\n <span className=\"text-sm\">{FLAG[f] || ''} {f} → {FLAG[t] || ''} {t}</span>\n <button onClick={() => setConfigPairs(p => p.filter((_, idx) => idx !== i))} className=\"text-red-400 hover:text-red-600\">×</button>\n </div>\n ))}\n </div>\n {configPairs.length < MAX_PAIRS ? (\n <div className=\"flex items-center gap-2\">\n <select value={newFrom} onChange={e => setNewFrom(e.target.value)}\n className=\"bg-gray-50 border border-gray-200 rounded px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500\">\n {ALL_CURRENCIES.map(c => <option key={c}>{c}</option>)}\n </select>\n <span className=\"text-gray-400\">→</span>\n <select value={newTo} onChange={e => setNewTo(e.target.value)}\n className=\"bg-gray-50 border border-gray-200 rounded px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500\">\n {ALL_CURRENCIES.map(c => <option key={c}>{c}</option>)}\n </select>\n <button onClick={() => { if (newFrom !== newTo && configPairs.length < MAX_PAIRS) setConfigPairs(p => [...p, [newFrom, newTo]]); }}\n className=\"text-sm font-medium text-blue-600 hover:text-blue-800 px-2\">+ Add</button>\n </div>\n ) : (\n <p className=\"text-[11px] text-gray-400 italic\">Max {MAX_PAIRS} pairs — remove one to add another.</p>\n )}\n </div>\n </WidgetSettingsModal>\n </>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/apps/CurrencyConverter.tsx"],"names":[],"mappings":"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","file":"CurrencyConverter-JI5ECSQA.js","sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\n\nconst ALL_CURRENCIES = ['USD', 'CNY', 'AUD', 'GBP', 'EUR', 'JPY', 'CAD', 'THB', 'NZD', 'SGD', 'HKD', 'CHF', 'KRW', 'INR', 'MXN', 'BRL'];\n\n/** Cap the rate list at 4 — keeps the widget compact and avoids\n * overwhelming the user with currencies they don't actually track. */\nconst MAX_PAIRS = 4;\n\nconst DEFAULT_PAIRS: [string, string][] = [\n ['USD', 'CNY'], ['USD', 'AUD'], ['GBP', 'USD'], ['USD', 'JPY'],\n];\n\nconst PAIRS_KEY = 'currency_pairs';\nconst SETTINGS_KEY = 'currency_appearance';\nconst CACHE_KEY = 'currency_rates_cache';\nconst CACHE_TTL = 3600000;\n\ntype CacheEntry = { rates: Record<string, number>; timestamp: number };\n\nfunction getCached(base: string): Record<string, number> | null {\n try { const c: Record<string, CacheEntry> = JSON.parse(localStorage.getItem(CACHE_KEY) || '{}'); const e = c[base]; if (e && Date.now() - e.timestamp < CACHE_TTL) return e.rates; } catch {} return null;\n}\nfunction setCache(base: string, rates: Record<string, number>) {\n try { const c = JSON.parse(localStorage.getItem(CACHE_KEY) || '{}'); c[base] = { rates, timestamp: Date.now() }; localStorage.setItem(CACHE_KEY, JSON.stringify(c)); } catch {}\n}\nfunction loadPairs(): [string, string][] {\n try {\n const s = JSON.parse(localStorage.getItem(PAIRS_KEY) || '');\n if (Array.isArray(s) && s.length) return s.slice(0, MAX_PAIRS);\n } catch {}\n return DEFAULT_PAIRS;\n}\n\nconst FLAG: Record<string, string> = {\n USD: '\\u{1F1FA}\\u{1F1F8}', CNY: '\\u{1F1E8}\\u{1F1F3}', AUD: '\\u{1F1E6}\\u{1F1FA}',\n GBP: '\\u{1F1EC}\\u{1F1E7}', JPY: '\\u{1F1EF}\\u{1F1F5}', CAD: '\\u{1F1E8}\\u{1F1E6}',\n EUR: '\\u{1F1EA}\\u{1F1FA}', THB: '\\u{1F1F9}\\u{1F1ED}', NZD: '\\u{1F1F3}\\u{1F1FF}',\n SGD: '\\u{1F1F8}\\u{1F1EC}', HKD: '\\u{1F1ED}\\u{1F1F0}', CHF: '\\u{1F1E8}\\u{1F1ED}',\n KRW: '\\u{1F1F0}\\u{1F1F7}', INR: '\\u{1F1EE}\\u{1F1F3}', MXN: '\\u{1F1F2}\\u{1F1FD}',\n BRL: '\\u{1F1E7}\\u{1F1F7}',\n};\n\nexport default function CurrencyConverter() {\n const [pairs, setPairs] = useState(loadPairs);\n const [appearance, setAppearance] = useState(() => loadAppearance(SETTINGS_KEY));\n const [allRates, setAllRates] = useState<Record<string, Record<string, number>>>({});\n const [loading, setLoading] = useState(false);\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configPairs, setConfigPairs] = useState<[string, string][]>([]);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n const [newFrom, setNewFrom] = useState('USD');\n const [newTo, setNewTo] = useState('CNY');\n\n useWidgetSettings(useCallback(() => {\n setConfigPairs([...pairs]);\n setConfigAppearance({ ...appearance });\n setSettingsOpen(true);\n }, [pairs, appearance]));\n\n useEffect(() => {\n const bases = [...new Set(pairs.map(([from]) => from))];\n let mounted = true;\n async function fetchAll() {\n setLoading(true);\n const result: Record<string, Record<string, number>> = {};\n for (const base of bases) {\n const cached = getCached(base);\n if (cached) { result[base] = cached; continue; }\n try { const res = await fetch(`https://open.er-api.com/v6/latest/${base}`); const data = await res.json(); if (data.rates) { result[base] = data.rates; setCache(base, data.rates); } } catch {}\n }\n if (mounted) { setAllRates(result); setLoading(false); }\n }\n fetchAll();\n return () => { mounted = false; };\n }, [pairs]);\n\n const saveSettings = () => {\n if (configPairs.length === 0) return;\n const capped = configPairs.slice(0, MAX_PAIRS);\n setPairs(capped); setAppearance(configAppearance);\n localStorage.setItem(PAIRS_KEY, JSON.stringify(capped));\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(configAppearance));\n setSettingsOpen(false);\n };\n\n return (\n <>\n {/* Theme-aware panel — pulls the same `--taskbar-bg-rgb` colour the\n * taskbar uses so the widget matches it across all themes\n * (gray-100-ish on light, Catppuccin mantle in dark). Tailwind\n * gray-* text/border classes auto-invert in dark via the existing\n * `[data-theme=\"dark\"]` overrides in styles.css.\n *\n * A plain naturally-flowing div — deliberately no `h-full`/`flex-1`, so\n * the window's `autoHeight` measurement hugs these rows instead of\n * reading the root as fill-height and pinning the window to its full\n * `dimensions` height (320×480) with empty space below the rows. */}\n <div\n style={{ backgroundColor: `rgb(var(--taskbar-bg-rgb, 243 244 246) / ${appearance.activeOpacity / 100})`, backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined }}>\n <div className=\"px-4 py-3 space-y-1\">\n {loading && <div className=\"text-xs text-gray-400 text-center py-4\">Loading rates...</div>}\n {pairs.map(([from, to], idx) => {\n const rate = allRates[from]?.[to];\n return (\n <button key={`${from}-${to}-${idx}`} onClick={() => {\n const swapped: [string, string][] = pairs.map((p, i) => i === idx ? [p[1], p[0]] : p);\n setPairs(swapped);\n localStorage.setItem(PAIRS_KEY, JSON.stringify(swapped));\n }}\n className=\"flex items-center justify-between px-2 py-2 border-b border-gray-200 last:border-0 w-full hover:bg-gray-100 rounded transition-colors cursor-pointer\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-base\">{FLAG[from] || ''}</span>\n <span className=\"text-sm font-semibold text-gray-700\">{from}</span>\n <svg className=\"h-3 w-3 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4\" /></svg>\n <span className=\"text-base\">{FLAG[to] || ''}</span>\n <span className=\"text-sm font-semibold text-gray-700\">{to}</span>\n </div>\n <div className=\"text-base font-mono font-semibold text-gray-900 tabular-nums\">\n {rate != null ? rate.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 4 }) : '—'}\n </div>\n </button>\n );\n })}\n </div>\n </div>\n\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"Currency Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance} onSave={saveSettings}>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Currency Pairs <span className=\"text-[11px] font-normal text-gray-400\">({configPairs.length}/{MAX_PAIRS})</span></h3>\n <div className=\"space-y-1 mb-2\">\n {configPairs.map(([f, t], i) => (\n <div key={i} className=\"flex items-center justify-between py-1 px-2 bg-gray-50 rounded\">\n <span className=\"text-sm\">{FLAG[f] || ''} {f} → {FLAG[t] || ''} {t}</span>\n <button onClick={() => setConfigPairs(p => p.filter((_, idx) => idx !== i))} className=\"text-red-400 hover:text-red-600\">×</button>\n </div>\n ))}\n </div>\n {configPairs.length < MAX_PAIRS ? (\n <div className=\"flex items-center gap-2\">\n <select value={newFrom} onChange={e => setNewFrom(e.target.value)}\n className=\"bg-gray-50 border border-gray-200 rounded px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500\">\n {ALL_CURRENCIES.map(c => <option key={c}>{c}</option>)}\n </select>\n <span className=\"text-gray-400\">→</span>\n <select value={newTo} onChange={e => setNewTo(e.target.value)}\n className=\"bg-gray-50 border border-gray-200 rounded px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500\">\n {ALL_CURRENCIES.map(c => <option key={c}>{c}</option>)}\n </select>\n <button onClick={() => { if (newFrom !== newTo && configPairs.length < MAX_PAIRS) setConfigPairs(p => [...p, [newFrom, newTo]]); }}\n className=\"text-sm font-medium text-blue-600 hover:text-blue-800 px-2\">+ Add</button>\n </div>\n ) : (\n <p className=\"text-[11px] text-gray-400 italic\">Max {MAX_PAIRS} pairs — remove one to add another.</p>\n )}\n </div>\n </WidgetSettingsModal>\n </>\n );\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { toast_default } from './chunk-VENYVK3L.js';
|
|
2
|
-
import { AboutApp } from './chunk-
|
|
3
|
-
import { WindowTitle, PopupMenu, PopupMenuLabel, PopupMenuItem, PopupMenuDivider } from './chunk-
|
|
2
|
+
import { AboutApp } from './chunk-XRCABX52.js';
|
|
3
|
+
import { WindowTitle, PopupMenu, PopupMenuLabel, PopupMenuItem, PopupMenuDivider } from './chunk-6OWYD4O6.js';
|
|
4
4
|
import './chunk-UBN4IUDE.js';
|
|
5
5
|
import './chunk-ZF6AYO4G.js';
|
|
6
6
|
import { useState, useRef } from 'react';
|
|
@@ -437,5 +437,5 @@ function Documents() {
|
|
|
437
437
|
}
|
|
438
438
|
|
|
439
439
|
export { Documents as default };
|
|
440
|
-
//# sourceMappingURL=Documents-
|
|
441
|
-
//# sourceMappingURL=Documents-
|
|
440
|
+
//# sourceMappingURL=Documents-HCHGAFPB.js.map
|
|
441
|
+
//# sourceMappingURL=Documents-HCHGAFPB.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/apps/Documents.tsx"],"names":[],"mappings":"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","file":"Documents-BGCOIW5E.js","sourcesContent":["/**\n * Documents — windowed viewer / editor for plain-text and Word documents.\n * TXT-family files (.txt, .md, .csv, .log, .json, .xml, .html, .css, .ts,\n * .tsx, .js, .jsx, .py, .yml, .yaml, .toml, .sh) open in a full-width\n * monospace editor. Word .docx files (and new blank documents) open on a\n * letter-size page (8.5 × 11 in) with rich formatting: bold/italic/…,\n * font size & color, bulleted / numbered lists, text alignment, and\n * images (toolbar button, paste, or drag-drop; click an image to resize\n * or remove it — images embed as data URLs so saved files stay\n * self-contained). .docx conversion uses mammoth (an optional peer dep).\n *\n * Open files via the toolbar's Open button or by dragging them onto\n * the window.\n */\nimport { useState, useRef, useEffect } from 'react';\nimport { WindowTitle } from '../shell/Modal';\nimport { PopupMenu, PopupMenuItem, PopupMenuDivider, PopupMenuLabel } from '../shell/PopupMenu';\nimport toast from '../shell/toast';\nimport AboutApp from './_about';\n\nconst TITLE_DISPLAY_MAX = 24;\nfunction truncateForTitle(s: string) {\n return s.length > TITLE_DISPLAY_MAX ? `${s.slice(0, TITLE_DISPLAY_MAX - 1)}…` : s;\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, c => ({\n '&': '&', '<': '<', '>': '>', '\"': '"', \"'\": ''',\n }[c] || c));\n}\n\nconst TEXT_EXTS = new Set([\n 'txt', 'md', 'markdown', 'csv', 'tsv', 'log', 'json', 'xml',\n 'html', 'htm', 'css', 'js', 'jsx', 'ts', 'tsx', 'py', 'rb',\n 'go', 'rs', 'java', 'c', 'h', 'cpp', 'hpp', 'sh', 'bash',\n 'yml', 'yaml', 'toml', 'ini', 'conf', 'env', 'sql',\n]);\nconst DOCX_EXTS = new Set(['docx']);\n\ninterface DocData {\n filename: string;\n kind: 'text' | 'docx';\n content: string;\n /** Original mime / extension hint for the download button. */\n ext: string;\n}\n\nconst BLANK_DOC: DocData = { filename: 'Untitled', kind: 'docx', content: '', ext: 'docx' };\n\nexport default function Documents() {\n // Documents is for editing — open with a blank paper-style canvas so the\n // user can start typing immediately. Loading a file replaces this state.\n const [data, setData] = useState<DocData>(BLANK_DOC);\n const [busy, setBusy] = useState(false);\n const [isDragging, setIsDragging] = useState(false);\n const [edited, setEdited] = useState(false);\n // Floating menu shown when an image in the document is clicked.\n const [imgMenu, setImgMenu] = useState<{ x: number; y: number; el: HTMLImageElement } | null>(null);\n const fileRef = useRef<HTMLInputElement>(null);\n const imgInputRef = useRef<HTMLInputElement>(null);\n const editorRef = useRef<HTMLDivElement>(null);\n\n // Apply a formatting command to the current selection in the editor.\n const exec = (cmd: string, value?: string) => {\n editorRef.current?.focus();\n document.execCommand(cmd, false, value);\n setEdited(true);\n };\n\n // ── Images ──\n // Inserted at the caret as data URLs, so the document needs no server-side\n // storage and a saved .html round-trips with its images embedded.\n const insertImageFiles = (files: File[]) => {\n for (const file of files) {\n if (!file.type.startsWith('image/')) continue;\n const reader = new FileReader();\n reader.onload = () => {\n editorRef.current?.focus();\n document.execCommand('insertImage', false, String(reader.result));\n setEdited(true);\n };\n reader.readAsDataURL(file);\n }\n };\n\n const handlePaste = (e: React.ClipboardEvent) => {\n const images = Array.from(e.clipboardData?.items ?? [])\n .filter(i => i.kind === 'file' && i.type.startsWith('image/'))\n .map(i => i.getAsFile())\n .filter((f): f is File => !!f);\n if (images.length) {\n e.preventDefault();\n insertImageFiles(images);\n }\n };\n\n // Click an image → floating resize / remove menu.\n const handleEditorClick = (e: React.MouseEvent) => {\n const target = e.target as HTMLElement;\n if (target.tagName === 'IMG') {\n e.preventDefault();\n setImgMenu({ x: e.clientX, y: e.clientY, el: target as HTMLImageElement });\n }\n };\n\n const setImageWidth = (width: string | null) => {\n if (!imgMenu) return;\n // Pixel width/height attributes (e.g. from pasted HTML) would fight the\n // percentage style — drop them and let height follow the aspect ratio.\n imgMenu.el.removeAttribute('width');\n imgMenu.el.removeAttribute('height');\n imgMenu.el.style.width = width ?? '';\n imgMenu.el.style.height = width ? 'auto' : '';\n setEdited(true);\n setImgMenu(null);\n };\n\n const removeImage = () => {\n imgMenu?.el.remove();\n setEdited(true);\n setImgMenu(null);\n };\n\n // Pull current HTML out of the editor (for save).\n const getEditorHtml = () => editorRef.current?.innerHTML ?? '';\n const getEditorText = () => editorRef.current?.innerText ?? '';\n\n const ingestFile = async (file: File) => {\n const ext = (file.name.split('.').pop() || '').toLowerCase();\n setBusy(true);\n try {\n if (TEXT_EXTS.has(ext) || (!DOCX_EXTS.has(ext) && file.type.startsWith('text/'))) {\n const text = await file.text();\n // Convert plain text → HTML so the contenteditable shows\n // line breaks correctly. Escape HTML special chars first.\n const html = escapeHtml(text).replace(/\\n/g, '<br>');\n setData({ filename: file.name, kind: 'text', content: html, ext });\n setEdited(false);\n } else if (DOCX_EXTS.has(ext)) {\n try {\n // mammoth is an optional peer dep — convert .docx → HTML.\n const mammoth = await import(/* @vite-ignore */ 'mammoth' as any);\n const buf = await file.arrayBuffer();\n const result = await mammoth.convertToHtml({ arrayBuffer: buf });\n setData({ filename: file.name, kind: 'docx', content: result.value || '<p><em>(empty document)</em></p>', ext });\n setEdited(false);\n } catch (err) {\n toast.error('Install the optional \"mammoth\" peer dep to read .docx files.');\n }\n } else if (ext === 'doc') {\n toast.error('.doc is the legacy Word binary format — convert to .docx first.');\n } else {\n toast.error(`Unsupported file type: .${ext || 'unknown'}`);\n }\n } finally {\n setBusy(false);\n }\n };\n\n const handlePick = () => fileRef.current?.click();\n const handleFile = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (file) ingestFile(file);\n if (fileRef.current) fileRef.current.value = '';\n };\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(false);\n const files = Array.from(e.dataTransfer.files ?? []);\n if (files.length === 0) return;\n // Dropped images go INTO the document; anything else opens as a document.\n if (files.every(f => f.type.startsWith('image/'))) {\n insertImageFiles(files);\n return;\n }\n ingestFile(files[0]);\n };\n\n const downloadCurrent = () => {\n if (!data) return;\n const html = getEditorHtml();\n if (data.kind === 'text') {\n // If the user added formatting, save as .html alongside; otherwise\n // strip back to plain text so the original .txt round-trips cleanly.\n // (`style=\"…text-align` only matches a real attribute — literal text\n // mentioning text-align gets its quotes escaped to " on load.)\n const hasFormatting = /<(b|strong|i|em|u|font|span style|ul|ol|img)|style=\"[^\"]*text-align/i.test(html);\n if (hasFormatting) {\n const blob = new Blob([`<!doctype html><meta charset=\"utf-8\"><title>${escapeHtml(data.filename)}</title><body style=\"font-family:ui-monospace,monospace;white-space:pre-wrap\">${html}`], { type: 'text/html' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a'); a.href = url; a.download = `${data.filename.replace(/\\.[^.]+$/, '')}.html`; a.click();\n URL.revokeObjectURL(url);\n } else {\n const text = getEditorText();\n const blob = new Blob([text], { type: 'text/plain' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a'); a.href = url; a.download = data.filename; a.click();\n URL.revokeObjectURL(url);\n }\n } else {\n const blob = new Blob([`<!doctype html><meta charset=\"utf-8\"><title>${escapeHtml(data.filename)}</title>${html}`], { type: 'text/html' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url; a.download = `${data.filename.replace(/\\.docx$/i, '')}.html`; a.click();\n URL.revokeObjectURL(url);\n }\n };\n\n const titleName = data?.filename ? truncateForTitle(data.filename) : 'Untitled';\n\n return (\n <div\n className=\"relative flex flex-col h-full\"\n onDragOver={(e) => { e.preventDefault(); if (!isDragging) setIsDragging(true); }}\n onDragLeave={(e) => { if (e.currentTarget === e.target) setIsDragging(false); }}\n onDrop={handleDrop}\n >\n <WindowTitle title={`${titleName}${edited ? ' •' : ''} - Documents`} />\n <AboutApp app=\"documents\" />\n\n {/* Toolbar */}\n <div className=\"flex items-center flex-wrap gap-x-2 gap-y-1 px-3 py-2 border-b border-gray-200 bg-gray-50 shrink-0\">\n <input\n ref={fileRef}\n type=\"file\"\n accept=\".txt,.md,.csv,.tsv,.log,.json,.xml,.html,.htm,.css,.js,.jsx,.ts,.tsx,.py,.rb,.go,.rs,.java,.c,.h,.cpp,.hpp,.sh,.bash,.yml,.yaml,.toml,.ini,.conf,.env,.sql,.docx,text/*\"\n onChange={handleFile}\n className=\"hidden\"\n />\n <button onClick={handlePick} className=\"text-xs text-gray-700 hover:text-gray-900 px-2 py-1 rounded hover:bg-gray-200 transition-colors flex items-center gap-1\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3.75 9.776c.112-.017.227-.026.344-.026h15.812c.117 0 .232.009.344.026m-16.5 0a2.25 2.25 0 00-1.883 2.542l.857 6a2.25 2.25 0 002.227 1.932H19.05a2.25 2.25 0 002.227-1.932l.857-6a2.25 2.25 0 00-1.883-2.542m-16.5 0V6A2.25 2.25 0 016 3.75h3.879a1.5 1.5 0 011.06.44l2.122 2.12a1.5 1.5 0 001.06.44H18A2.25 2.25 0 0120.25 9v.776\" />\n </svg>\n Open\n </button>\n <button onClick={downloadCurrent} className=\"text-xs text-gray-700 hover:text-gray-900 px-2 py-1 rounded hover:bg-gray-200 transition-colors\">\n Save\n </button>\n <span className=\"text-[10px] text-gray-400 ml-1\">TXT · DOCX · Code</span>\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <span className=\"text-xs font-medium text-gray-700 truncate max-w-[200px]\" title={data.filename}>\n {data.filename}{edited ? ' •' : ''}\n </span>\n\n {/* Formatting toolbar */}\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <div className=\"flex items-center gap-0.5\">\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('bold')}\n className=\"px-2 py-1 text-xs rounded font-bold text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Bold\">B</button>\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('italic')}\n className=\"px-2 py-1 text-xs rounded italic text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Italic\">I</button>\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('underline')}\n className=\"px-2 py-1 text-xs rounded underline text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Underline\">U</button>\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('strikeThrough')}\n className=\"px-2 py-1 text-xs rounded line-through text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Strikethrough\">S</button>\n </div>\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <select onMouseDown={e => e.preventDefault()} onChange={e => { exec('fontSize', e.target.value); e.currentTarget.value = ''; }}\n defaultValue=\"\" className=\"text-xs border border-gray-300 rounded px-1 py-0.5 bg-white\">\n <option value=\"\" disabled>Size</option>\n <option value=\"1\">XS</option>\n <option value=\"2\">S</option>\n <option value=\"3\">M</option>\n <option value=\"4\">L</option>\n <option value=\"5\">XL</option>\n <option value=\"6\">2XL</option>\n </select>\n <input type=\"color\" defaultValue=\"#000000\" onChange={e => exec('foreColor', e.target.value)}\n className=\"w-7 h-6 border border-gray-300 rounded cursor-pointer\" title=\"Text color\" />\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('insertUnorderedList')}\n className=\"px-2 py-1 text-xs rounded text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Bulleted list\">• List</button>\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('insertOrderedList')}\n className=\"px-2 py-1 text-xs rounded text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Numbered list\">1.</button>\n\n {/* Alignment */}\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <div className=\"flex items-center gap-0.5\">\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('justifyLeft')}\n className=\"px-2 py-1 rounded text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Align left\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.8}>\n <path strokeLinecap=\"round\" d=\"M3.75 6h16.5M3.75 12h9.75M3.75 18h14.25\" />\n </svg>\n </button>\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('justifyCenter')}\n className=\"px-2 py-1 rounded text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Align center\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.8}>\n <path strokeLinecap=\"round\" d=\"M3.75 6h16.5M7.125 12h9.75M4.875 18h14.25\" />\n </svg>\n </button>\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('justifyRight')}\n className=\"px-2 py-1 rounded text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Align right\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.8}>\n <path strokeLinecap=\"round\" d=\"M3.75 6h16.5M10.5 12h9.75M6 18h14.25\" />\n </svg>\n </button>\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('justifyFull')}\n className=\"px-2 py-1 rounded text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Justify\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.8}>\n <path strokeLinecap=\"round\" d=\"M3.75 6h16.5M3.75 12h16.5M3.75 18h16.5\" />\n </svg>\n </button>\n </div>\n\n {/* Image insert */}\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <input\n ref={imgInputRef}\n type=\"file\"\n accept=\"image/*\"\n multiple\n className=\"hidden\"\n onChange={e => {\n if (e.target.files?.length) insertImageFiles(Array.from(e.target.files));\n if (imgInputRef.current) imgInputRef.current.value = '';\n }}\n />\n <button onClick={() => imgInputRef.current?.click()}\n className=\"px-2 py-1 text-xs rounded text-gray-700 hover:bg-gray-200 transition-colors flex items-center gap-1\" title=\"Insert image (or paste / drop one)\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 001.5-1.5V6a1.5 1.5 0 00-1.5-1.5H3.75A1.5 1.5 0 002.25 6v12a1.5 1.5 0 001.5 1.5zm10.5-11.25h.008v.008h-.008V8.25zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z\" />\n </svg>\n Image\n </button>\n </div>\n\n {/* Body */}\n <div className=\"flex-1 min-h-0 overflow-hidden\">\n {busy ? (\n <div className=\"flex items-center justify-center h-full text-sm text-gray-400\">Loading…</div>\n ) : (\n <div className={`h-full overflow-auto ${data.kind === 'docx' ? 'bg-gray-100 px-6 py-8' : 'bg-white'}`}>\n {/* Word-style documents render on a US-letter page (8.5 × 11 in,\n 1 in margins) that grows past 11 in as content does; the gray\n \"desk\" scrolls when the window is narrower than the page. */}\n <div\n ref={editorRef}\n contentEditable\n suppressContentEditableWarning\n spellCheck={false}\n onInput={() => setEdited(true)}\n onPaste={handlePaste}\n onClick={handleEditorClick}\n dangerouslySetInnerHTML={{ __html: data.content }}\n className={\n data.kind === 'docx'\n ? 'docs-editor mx-auto w-[8.5in] min-h-[11in] bg-white p-[1in] shadow text-[14px] leading-relaxed text-gray-800 outline-none focus:ring-2 focus:ring-blue-400/40'\n : 'docs-editor block w-full min-h-full p-4 font-mono text-[13px] leading-relaxed text-gray-800 bg-white outline-none whitespace-pre-wrap'\n }\n />\n </div>\n )}\n </div>\n\n {isDragging && (\n <div className=\"absolute inset-0 bg-blue-500/15 border-4 border-dashed border-blue-500 pointer-events-none flex items-center justify-center z-20\">\n <div className=\"px-4 py-2 rounded-md bg-blue-600 text-white text-sm font-medium shadow-lg\">\n Drop a document to open · images insert into the page\n </div>\n </div>\n )}\n\n {/* Image menu — resize / remove the clicked image */}\n {imgMenu && (\n <PopupMenu\n minWidth={150}\n style={{ left: imgMenu.x, top: imgMenu.y }}\n onClose={() => setImgMenu(null)}\n >\n <PopupMenuLabel>Image width</PopupMenuLabel>\n <PopupMenuItem onClick={() => setImageWidth('25%')}>25%</PopupMenuItem>\n <PopupMenuItem onClick={() => setImageWidth('50%')}>50%</PopupMenuItem>\n <PopupMenuItem onClick={() => setImageWidth('75%')}>75%</PopupMenuItem>\n <PopupMenuItem onClick={() => setImageWidth('100%')}>100%</PopupMenuItem>\n <PopupMenuItem onClick={() => setImageWidth(null)}>Original size</PopupMenuItem>\n <PopupMenuDivider />\n <PopupMenuItem danger onClick={removeImage}>Remove image</PopupMenuItem>\n </PopupMenu>\n )}\n </div>\n );\n}\n\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/apps/Documents.tsx"],"names":[],"mappings":"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","file":"Documents-HCHGAFPB.js","sourcesContent":["/**\n * Documents — windowed viewer / editor for plain-text and Word documents.\n * TXT-family files (.txt, .md, .csv, .log, .json, .xml, .html, .css, .ts,\n * .tsx, .js, .jsx, .py, .yml, .yaml, .toml, .sh) open in a full-width\n * monospace editor. Word .docx files (and new blank documents) open on a\n * letter-size page (8.5 × 11 in) with rich formatting: bold/italic/…,\n * font size & color, bulleted / numbered lists, text alignment, and\n * images (toolbar button, paste, or drag-drop; click an image to resize\n * or remove it — images embed as data URLs so saved files stay\n * self-contained). .docx conversion uses mammoth (an optional peer dep).\n *\n * Open files via the toolbar's Open button or by dragging them onto\n * the window.\n */\nimport { useState, useRef, useEffect } from 'react';\nimport { WindowTitle } from '../shell/Modal';\nimport { PopupMenu, PopupMenuItem, PopupMenuDivider, PopupMenuLabel } from '../shell/PopupMenu';\nimport toast from '../shell/toast';\nimport AboutApp from './_about';\n\nconst TITLE_DISPLAY_MAX = 24;\nfunction truncateForTitle(s: string) {\n return s.length > TITLE_DISPLAY_MAX ? `${s.slice(0, TITLE_DISPLAY_MAX - 1)}…` : s;\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, c => ({\n '&': '&', '<': '<', '>': '>', '\"': '"', \"'\": ''',\n }[c] || c));\n}\n\nconst TEXT_EXTS = new Set([\n 'txt', 'md', 'markdown', 'csv', 'tsv', 'log', 'json', 'xml',\n 'html', 'htm', 'css', 'js', 'jsx', 'ts', 'tsx', 'py', 'rb',\n 'go', 'rs', 'java', 'c', 'h', 'cpp', 'hpp', 'sh', 'bash',\n 'yml', 'yaml', 'toml', 'ini', 'conf', 'env', 'sql',\n]);\nconst DOCX_EXTS = new Set(['docx']);\n\ninterface DocData {\n filename: string;\n kind: 'text' | 'docx';\n content: string;\n /** Original mime / extension hint for the download button. */\n ext: string;\n}\n\nconst BLANK_DOC: DocData = { filename: 'Untitled', kind: 'docx', content: '', ext: 'docx' };\n\nexport default function Documents() {\n // Documents is for editing — open with a blank paper-style canvas so the\n // user can start typing immediately. Loading a file replaces this state.\n const [data, setData] = useState<DocData>(BLANK_DOC);\n const [busy, setBusy] = useState(false);\n const [isDragging, setIsDragging] = useState(false);\n const [edited, setEdited] = useState(false);\n // Floating menu shown when an image in the document is clicked.\n const [imgMenu, setImgMenu] = useState<{ x: number; y: number; el: HTMLImageElement } | null>(null);\n const fileRef = useRef<HTMLInputElement>(null);\n const imgInputRef = useRef<HTMLInputElement>(null);\n const editorRef = useRef<HTMLDivElement>(null);\n\n // Apply a formatting command to the current selection in the editor.\n const exec = (cmd: string, value?: string) => {\n editorRef.current?.focus();\n document.execCommand(cmd, false, value);\n setEdited(true);\n };\n\n // ── Images ──\n // Inserted at the caret as data URLs, so the document needs no server-side\n // storage and a saved .html round-trips with its images embedded.\n const insertImageFiles = (files: File[]) => {\n for (const file of files) {\n if (!file.type.startsWith('image/')) continue;\n const reader = new FileReader();\n reader.onload = () => {\n editorRef.current?.focus();\n document.execCommand('insertImage', false, String(reader.result));\n setEdited(true);\n };\n reader.readAsDataURL(file);\n }\n };\n\n const handlePaste = (e: React.ClipboardEvent) => {\n const images = Array.from(e.clipboardData?.items ?? [])\n .filter(i => i.kind === 'file' && i.type.startsWith('image/'))\n .map(i => i.getAsFile())\n .filter((f): f is File => !!f);\n if (images.length) {\n e.preventDefault();\n insertImageFiles(images);\n }\n };\n\n // Click an image → floating resize / remove menu.\n const handleEditorClick = (e: React.MouseEvent) => {\n const target = e.target as HTMLElement;\n if (target.tagName === 'IMG') {\n e.preventDefault();\n setImgMenu({ x: e.clientX, y: e.clientY, el: target as HTMLImageElement });\n }\n };\n\n const setImageWidth = (width: string | null) => {\n if (!imgMenu) return;\n // Pixel width/height attributes (e.g. from pasted HTML) would fight the\n // percentage style — drop them and let height follow the aspect ratio.\n imgMenu.el.removeAttribute('width');\n imgMenu.el.removeAttribute('height');\n imgMenu.el.style.width = width ?? '';\n imgMenu.el.style.height = width ? 'auto' : '';\n setEdited(true);\n setImgMenu(null);\n };\n\n const removeImage = () => {\n imgMenu?.el.remove();\n setEdited(true);\n setImgMenu(null);\n };\n\n // Pull current HTML out of the editor (for save).\n const getEditorHtml = () => editorRef.current?.innerHTML ?? '';\n const getEditorText = () => editorRef.current?.innerText ?? '';\n\n const ingestFile = async (file: File) => {\n const ext = (file.name.split('.').pop() || '').toLowerCase();\n setBusy(true);\n try {\n if (TEXT_EXTS.has(ext) || (!DOCX_EXTS.has(ext) && file.type.startsWith('text/'))) {\n const text = await file.text();\n // Convert plain text → HTML so the contenteditable shows\n // line breaks correctly. Escape HTML special chars first.\n const html = escapeHtml(text).replace(/\\n/g, '<br>');\n setData({ filename: file.name, kind: 'text', content: html, ext });\n setEdited(false);\n } else if (DOCX_EXTS.has(ext)) {\n try {\n // mammoth is an optional peer dep — convert .docx → HTML.\n const mammoth = await import(/* @vite-ignore */ 'mammoth' as any);\n const buf = await file.arrayBuffer();\n const result = await mammoth.convertToHtml({ arrayBuffer: buf });\n setData({ filename: file.name, kind: 'docx', content: result.value || '<p><em>(empty document)</em></p>', ext });\n setEdited(false);\n } catch (err) {\n toast.error('Install the optional \"mammoth\" peer dep to read .docx files.');\n }\n } else if (ext === 'doc') {\n toast.error('.doc is the legacy Word binary format — convert to .docx first.');\n } else {\n toast.error(`Unsupported file type: .${ext || 'unknown'}`);\n }\n } finally {\n setBusy(false);\n }\n };\n\n const handlePick = () => fileRef.current?.click();\n const handleFile = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (file) ingestFile(file);\n if (fileRef.current) fileRef.current.value = '';\n };\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(false);\n const files = Array.from(e.dataTransfer.files ?? []);\n if (files.length === 0) return;\n // Dropped images go INTO the document; anything else opens as a document.\n if (files.every(f => f.type.startsWith('image/'))) {\n insertImageFiles(files);\n return;\n }\n ingestFile(files[0]);\n };\n\n const downloadCurrent = () => {\n if (!data) return;\n const html = getEditorHtml();\n if (data.kind === 'text') {\n // If the user added formatting, save as .html alongside; otherwise\n // strip back to plain text so the original .txt round-trips cleanly.\n // (`style=\"…text-align` only matches a real attribute — literal text\n // mentioning text-align gets its quotes escaped to " on load.)\n const hasFormatting = /<(b|strong|i|em|u|font|span style|ul|ol|img)|style=\"[^\"]*text-align/i.test(html);\n if (hasFormatting) {\n const blob = new Blob([`<!doctype html><meta charset=\"utf-8\"><title>${escapeHtml(data.filename)}</title><body style=\"font-family:ui-monospace,monospace;white-space:pre-wrap\">${html}`], { type: 'text/html' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a'); a.href = url; a.download = `${data.filename.replace(/\\.[^.]+$/, '')}.html`; a.click();\n URL.revokeObjectURL(url);\n } else {\n const text = getEditorText();\n const blob = new Blob([text], { type: 'text/plain' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a'); a.href = url; a.download = data.filename; a.click();\n URL.revokeObjectURL(url);\n }\n } else {\n const blob = new Blob([`<!doctype html><meta charset=\"utf-8\"><title>${escapeHtml(data.filename)}</title>${html}`], { type: 'text/html' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url; a.download = `${data.filename.replace(/\\.docx$/i, '')}.html`; a.click();\n URL.revokeObjectURL(url);\n }\n };\n\n const titleName = data?.filename ? truncateForTitle(data.filename) : 'Untitled';\n\n return (\n <div\n className=\"relative flex flex-col h-full\"\n onDragOver={(e) => { e.preventDefault(); if (!isDragging) setIsDragging(true); }}\n onDragLeave={(e) => { if (e.currentTarget === e.target) setIsDragging(false); }}\n onDrop={handleDrop}\n >\n <WindowTitle title={`${titleName}${edited ? ' •' : ''} - Documents`} />\n <AboutApp app=\"documents\" />\n\n {/* Toolbar */}\n <div className=\"flex items-center flex-wrap gap-x-2 gap-y-1 px-3 py-2 border-b border-gray-200 bg-gray-50 shrink-0\">\n <input\n ref={fileRef}\n type=\"file\"\n accept=\".txt,.md,.csv,.tsv,.log,.json,.xml,.html,.htm,.css,.js,.jsx,.ts,.tsx,.py,.rb,.go,.rs,.java,.c,.h,.cpp,.hpp,.sh,.bash,.yml,.yaml,.toml,.ini,.conf,.env,.sql,.docx,text/*\"\n onChange={handleFile}\n className=\"hidden\"\n />\n <button onClick={handlePick} className=\"text-xs text-gray-700 hover:text-gray-900 px-2 py-1 rounded hover:bg-gray-200 transition-colors flex items-center gap-1\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3.75 9.776c.112-.017.227-.026.344-.026h15.812c.117 0 .232.009.344.026m-16.5 0a2.25 2.25 0 00-1.883 2.542l.857 6a2.25 2.25 0 002.227 1.932H19.05a2.25 2.25 0 002.227-1.932l.857-6a2.25 2.25 0 00-1.883-2.542m-16.5 0V6A2.25 2.25 0 016 3.75h3.879a1.5 1.5 0 011.06.44l2.122 2.12a1.5 1.5 0 001.06.44H18A2.25 2.25 0 0120.25 9v.776\" />\n </svg>\n Open\n </button>\n <button onClick={downloadCurrent} className=\"text-xs text-gray-700 hover:text-gray-900 px-2 py-1 rounded hover:bg-gray-200 transition-colors\">\n Save\n </button>\n <span className=\"text-[10px] text-gray-400 ml-1\">TXT · DOCX · Code</span>\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <span className=\"text-xs font-medium text-gray-700 truncate max-w-[200px]\" title={data.filename}>\n {data.filename}{edited ? ' •' : ''}\n </span>\n\n {/* Formatting toolbar */}\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <div className=\"flex items-center gap-0.5\">\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('bold')}\n className=\"px-2 py-1 text-xs rounded font-bold text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Bold\">B</button>\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('italic')}\n className=\"px-2 py-1 text-xs rounded italic text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Italic\">I</button>\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('underline')}\n className=\"px-2 py-1 text-xs rounded underline text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Underline\">U</button>\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('strikeThrough')}\n className=\"px-2 py-1 text-xs rounded line-through text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Strikethrough\">S</button>\n </div>\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <select onMouseDown={e => e.preventDefault()} onChange={e => { exec('fontSize', e.target.value); e.currentTarget.value = ''; }}\n defaultValue=\"\" className=\"text-xs border border-gray-300 rounded px-1 py-0.5 bg-white\">\n <option value=\"\" disabled>Size</option>\n <option value=\"1\">XS</option>\n <option value=\"2\">S</option>\n <option value=\"3\">M</option>\n <option value=\"4\">L</option>\n <option value=\"5\">XL</option>\n <option value=\"6\">2XL</option>\n </select>\n <input type=\"color\" defaultValue=\"#000000\" onChange={e => exec('foreColor', e.target.value)}\n className=\"w-7 h-6 border border-gray-300 rounded cursor-pointer\" title=\"Text color\" />\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('insertUnorderedList')}\n className=\"px-2 py-1 text-xs rounded text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Bulleted list\">• List</button>\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('insertOrderedList')}\n className=\"px-2 py-1 text-xs rounded text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Numbered list\">1.</button>\n\n {/* Alignment */}\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <div className=\"flex items-center gap-0.5\">\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('justifyLeft')}\n className=\"px-2 py-1 rounded text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Align left\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.8}>\n <path strokeLinecap=\"round\" d=\"M3.75 6h16.5M3.75 12h9.75M3.75 18h14.25\" />\n </svg>\n </button>\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('justifyCenter')}\n className=\"px-2 py-1 rounded text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Align center\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.8}>\n <path strokeLinecap=\"round\" d=\"M3.75 6h16.5M7.125 12h9.75M4.875 18h14.25\" />\n </svg>\n </button>\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('justifyRight')}\n className=\"px-2 py-1 rounded text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Align right\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.8}>\n <path strokeLinecap=\"round\" d=\"M3.75 6h16.5M10.5 12h9.75M6 18h14.25\" />\n </svg>\n </button>\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('justifyFull')}\n className=\"px-2 py-1 rounded text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Justify\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.8}>\n <path strokeLinecap=\"round\" d=\"M3.75 6h16.5M3.75 12h16.5M3.75 18h16.5\" />\n </svg>\n </button>\n </div>\n\n {/* Image insert */}\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <input\n ref={imgInputRef}\n type=\"file\"\n accept=\"image/*\"\n multiple\n className=\"hidden\"\n onChange={e => {\n if (e.target.files?.length) insertImageFiles(Array.from(e.target.files));\n if (imgInputRef.current) imgInputRef.current.value = '';\n }}\n />\n <button onClick={() => imgInputRef.current?.click()}\n className=\"px-2 py-1 text-xs rounded text-gray-700 hover:bg-gray-200 transition-colors flex items-center gap-1\" title=\"Insert image (or paste / drop one)\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 001.5-1.5V6a1.5 1.5 0 00-1.5-1.5H3.75A1.5 1.5 0 002.25 6v12a1.5 1.5 0 001.5 1.5zm10.5-11.25h.008v.008h-.008V8.25zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z\" />\n </svg>\n Image\n </button>\n </div>\n\n {/* Body */}\n <div className=\"flex-1 min-h-0 overflow-hidden\">\n {busy ? (\n <div className=\"flex items-center justify-center h-full text-sm text-gray-400\">Loading…</div>\n ) : (\n <div className={`h-full overflow-auto ${data.kind === 'docx' ? 'bg-gray-100 px-6 py-8' : 'bg-white'}`}>\n {/* Word-style documents render on a US-letter page (8.5 × 11 in,\n 1 in margins) that grows past 11 in as content does; the gray\n \"desk\" scrolls when the window is narrower than the page. */}\n <div\n ref={editorRef}\n contentEditable\n suppressContentEditableWarning\n spellCheck={false}\n onInput={() => setEdited(true)}\n onPaste={handlePaste}\n onClick={handleEditorClick}\n dangerouslySetInnerHTML={{ __html: data.content }}\n className={\n data.kind === 'docx'\n ? 'docs-editor mx-auto w-[8.5in] min-h-[11in] bg-white p-[1in] shadow text-[14px] leading-relaxed text-gray-800 outline-none focus:ring-2 focus:ring-blue-400/40'\n : 'docs-editor block w-full min-h-full p-4 font-mono text-[13px] leading-relaxed text-gray-800 bg-white outline-none whitespace-pre-wrap'\n }\n />\n </div>\n )}\n </div>\n\n {isDragging && (\n <div className=\"absolute inset-0 bg-blue-500/15 border-4 border-dashed border-blue-500 pointer-events-none flex items-center justify-center z-20\">\n <div className=\"px-4 py-2 rounded-md bg-blue-600 text-white text-sm font-medium shadow-lg\">\n Drop a document to open · images insert into the page\n </div>\n </div>\n )}\n\n {/* Image menu — resize / remove the clicked image */}\n {imgMenu && (\n <PopupMenu\n minWidth={150}\n style={{ left: imgMenu.x, top: imgMenu.y }}\n onClose={() => setImgMenu(null)}\n >\n <PopupMenuLabel>Image width</PopupMenuLabel>\n <PopupMenuItem onClick={() => setImageWidth('25%')}>25%</PopupMenuItem>\n <PopupMenuItem onClick={() => setImageWidth('50%')}>50%</PopupMenuItem>\n <PopupMenuItem onClick={() => setImageWidth('75%')}>75%</PopupMenuItem>\n <PopupMenuItem onClick={() => setImageWidth('100%')}>100%</PopupMenuItem>\n <PopupMenuItem onClick={() => setImageWidth(null)}>Original size</PopupMenuItem>\n <PopupMenuDivider />\n <PopupMenuItem danger onClick={removeImage}>Remove image</PopupMenuItem>\n </PopupMenu>\n )}\n </div>\n );\n}\n\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { Files as default, openFilesInTrashMode, setFilesDemoTree } from './chunk-QS2MEW6R.js';
|
|
2
|
+
import './chunk-X4MB43G2.js';
|
|
3
|
+
import './chunk-VGTEM5RZ.js';
|
|
4
|
+
import './chunk-SKNOGIDC.js';
|
|
5
|
+
import './chunk-VENYVK3L.js';
|
|
6
|
+
import './chunk-XVCEFF6M.js';
|
|
7
|
+
import './chunk-XRCABX52.js';
|
|
8
|
+
import './chunk-6OWYD4O6.js';
|
|
9
|
+
import './chunk-UBN4IUDE.js';
|
|
10
|
+
import './chunk-ZF6AYO4G.js';
|
|
11
|
+
//# sourceMappingURL=Files-FYWUNLBY.js.map
|
|
12
|
+
//# sourceMappingURL=Files-FYWUNLBY.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"Files-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"Files-FYWUNLBY.js"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SidebarLayout } from './chunk-VGTEM5RZ.js';
|
|
2
2
|
import { toast_default } from './chunk-VENYVK3L.js';
|
|
3
|
-
import { AboutApp } from './chunk-
|
|
4
|
-
import { useWindowManager, useShellPrefs, client_default } from './chunk-
|
|
3
|
+
import { AboutApp } from './chunk-XRCABX52.js';
|
|
4
|
+
import { useWindowManager, useShellPrefs, client_default } from './chunk-6OWYD4O6.js';
|
|
5
5
|
import './chunk-UBN4IUDE.js';
|
|
6
6
|
import './chunk-ZF6AYO4G.js';
|
|
7
7
|
import { useRef, useEffect, useState, useCallback } from 'react';
|
|
@@ -398,5 +398,5 @@ Tips:
|
|
|
398
398
|
}
|
|
399
399
|
|
|
400
400
|
export { Notepad as default };
|
|
401
|
-
//# sourceMappingURL=Notepad-
|
|
402
|
-
//# sourceMappingURL=Notepad-
|
|
401
|
+
//# sourceMappingURL=Notepad-WRS7EMCK.js.map
|
|
402
|
+
//# sourceMappingURL=Notepad-WRS7EMCK.js.map
|