efficient-shell 4.168.0 → 4.171.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +151 -1
  2. package/dist/{Browser-PZPREN6H.js → Browser-BW3EZ7B2.js} +14 -14
  3. package/dist/Calculator-VBK5NSMU.js +29 -0
  4. package/dist/ConfirmDialog-YRCG3W2T.js +1 -0
  5. package/dist/{CurrencyConverter-3BTIZ2LT.js → CurrencyConverter-IW6F7HW4.js} +6 -6
  6. package/dist/{Documents-YAOM3L47.js → Documents-VH3JXSSJ.js} +5 -5
  7. package/dist/{Files-2UHYDMLL.js → Files-R4ZA5MXU.js} +30 -30
  8. package/dist/{Notepad-OWL75AYX.js → Notepad-FOITSJJA.js} +10 -10
  9. package/dist/{PomodoroTimer-SCPEOG6W.js → PomodoroTimer-C4SVIFC6.js} +31 -31
  10. package/dist/{Preview-5R3QZSJU.js → Preview-5K6LK6WZ.js} +21 -21
  11. package/dist/{Sidebar-C5RXL72L.js → Sidebar-FDFNRXJU.js} +20 -20
  12. package/dist/Spreadsheet-CZC3QU2G.js +37 -0
  13. package/dist/{Stock-UGDIALNB.js → Stock-B4WWEBZH.js} +6 -6
  14. package/dist/{Weather-CR2MN5XF.js → Weather-TDB5AY23.js} +15 -15
  15. package/dist/{WorldClock-JBNJ7C7J.js → WorldClock-HYHDVPBV.js} +7 -7
  16. package/dist/apps/index.js +1 -1
  17. package/dist/bin/ui-check.js +1 -1
  18. package/dist/brand.css +1 -1
  19. package/dist/{chunk-JLPJBO7K.js → chunk-2UIKLYAI.js} +1 -1
  20. package/dist/{chunk-6MBERZOS.js → chunk-36QX6LOQ.js} +3 -3
  21. package/dist/{chunk-SOI4LR67.js → chunk-5G4QMZGJ.js} +3 -3
  22. package/dist/chunk-67ZUPDWG.js +1 -0
  23. package/dist/{chunk-PLX2N4N6.js → chunk-7YFAFXQG.js} +2 -2
  24. package/dist/{chunk-FVXBJGY5.js → chunk-AUKURHBZ.js} +3 -3
  25. package/dist/{chunk-A7Q4BCPI.js → chunk-CRI4UFBU.js} +5 -5
  26. package/dist/{chunk-M4DB7UBZ.js → chunk-ECFMRDUP.js} +1 -1
  27. package/dist/chunk-EXXHI5DO.js +12 -0
  28. package/dist/chunk-FWOPZB6I.js +1 -0
  29. package/dist/chunk-FWZUTHP5.js +112 -0
  30. package/dist/chunk-GKLJ2SYS.js +995 -0
  31. package/dist/{chunk-YWXYBJ5Y.js → chunk-HA2WG27U.js} +2 -2
  32. package/dist/{chunk-CUX4XGLS.js → chunk-HNXPIYRS.js} +1 -1
  33. package/dist/{chunk-QZG72OVX.js → chunk-NTCAZ6Y3.js} +1 -1
  34. package/dist/{chunk-N3ZXQE4M.js → chunk-PGVUO7GB.js} +5 -5
  35. package/dist/{chunk-XKHAP6N2.js → chunk-Y3UKUB7V.js} +8 -8
  36. package/dist/chunk-YKZHOXI4.js +2 -0
  37. package/dist/icons/efficient.d.ts +355 -0
  38. package/dist/icons/efficient.js +470 -0
  39. package/dist/icons/heroicons.d.ts +6 -0
  40. package/dist/icons/heroicons.js +1 -0
  41. package/dist/icons/index.d.ts +64 -0
  42. package/dist/icons/index.js +2 -0
  43. package/dist/icons/lucide.d.ts +6 -0
  44. package/dist/icons/lucide.js +1 -0
  45. package/dist/{index-CbLbd__n.d.ts → index-Dq20bi8D.d.ts} +125 -1
  46. package/dist/index.d.ts +4 -2
  47. package/dist/index.js +650 -645
  48. package/dist/map/index.js +3 -3
  49. package/dist/page-tabs/index.js +5 -5
  50. package/dist/registry-FHdUeVww.d.ts +71 -0
  51. package/dist/ui/index.d.ts +3 -1
  52. package/dist/ui/index.js +1 -1
  53. package/dist/ui.css +81 -0
  54. package/package.json +27 -1
  55. package/dist/Calculator-NXMUEH5D.js +0 -29
  56. package/dist/ConfirmDialog-ZDVMT74Y.js +0 -1
  57. package/dist/Spreadsheet-XT4HF7MQ.js +0 -37
  58. package/dist/chunk-7U3F53IG.js +0 -1
  59. package/dist/chunk-GVZLCY3B.js +0 -994
  60. package/dist/chunk-JYLI2WXW.js +0 -12
  61. package/dist/chunk-LW27IM3S.js +0 -112
package/README.md CHANGED
@@ -965,6 +965,7 @@ All exports are named — `import { Modal, ... } from 'efficient-shell'`.
965
965
  | `<ShellAuthProvider value={{ hasAnyPerm }}>` | Permission-filter nav items. |
966
966
  | `<ShellPrefsProvider value={{ prefs, save }}>` | Where the shell reads/writes user prefs (theme, taskbar pos, sticky notes, …). Use `useLocalStoragePrefs(key)` for a backend-less default. Since 4.92.0 it is also how `<EntityList>` / `<ResizableTable>` column config and sort persist: with no provider mounted, `useShellPrefs()` reads empty and drops saves, so both silently degrade to localStorage-only and never reach the user's profile. Session restore reads `session_windows` once, at mount: hand the provider prefs that are already loaded by then (an adapter whose prefs arrive later misses that load's replay, though the saved set is kept). |
967
967
  | `<ShellStringsProvider value={{ … }} locale?>` | Translates every word the shell and the kit draw on their own account — window controls, taskbar hints, dialogs, pickers, pagers, list footers, upload zones, charts, timelines. English works with NO provider; the override is a typed partial merged per section, so an incomplete catalog falls back rather than breaking. Prop-level text (`emptyText`, placeholders) always wins over the catalog. `locale` (a BCP 47 tag) writes dates and numbers that locale's way; without one nothing moves. See [Languages, dates and numbers](#languages-dates-and-numbers--shellstringsprovider) for the full catalog. |
968
+ | `<ShellLanguageProvider languages language strings? onChange? reload?>` | Which interface language is in force. Takes the tag `resolveShellLanguage` chose before mount and that language's shell catalog, mounts `ShellStringsProvider` with both, stamps `<html lang>`, and gives `useShellLanguage()` its `setLanguage`, which saves the choice and reloads. See [Choosing the language](#choosing-the-language--shelllanguageprovider). |
968
969
  | `<ShellEntityFetcherProvider value={(endpoint, id) => …}>` | How the modal stack fetches entity data. |
969
970
  | `<BugReportConfigProvider value={{ submit, list?, resolve? }}>` | Wire the bug-report flow to your backend. |
970
971
  | `<DesktopHostProvider value={{ stickyResolver?, saveShortcuts?, … }}>` | Sticky-note ref resolver + persistence callbacks. |
@@ -995,6 +996,7 @@ All exports are named — `import { Modal, ... } from 'efficient-shell'`.
995
996
  | `useUndoCanEdit(canEdit)` | A form's own word on whether the record may be edited right now — `useUndoCanEdit(!isLocked)`. While false the stack records nothing, ⌘Z is left alone and the footer shows no controls. A nested `<UndoProvider canEdit={false}>` in the form's JSX says the same thing: it shadows the stack for its children AND forwards the read-only claim to the window's stack, which is where the form's own `useUndoableState` calls (made above it in the tree) register. Either form of the claim makes the whole window read-only. The positive claim, `useUndoCanEdit(true)`, is how a window that edits in place outside Edit mode — a detail with inline cells behind a permission — asks the footer for the pair. |
996
997
  | `useMultiModal()` | Manages multi-window stacking + activate/blur. |
997
998
  | `useShellAuth() / useShellPrefs() / useShellEntityFetcher() / useBugReport() / useDesktopHost()` | Context readers — the shell uses these internally; consumers may also call them. |
999
+ | `useShellLanguage()` | `{ language, languages, setLanguage }` — the active language's tag, the ones on offer, and the switch. English with nothing to switch to when no `ShellLanguageProvider` is mounted. |
998
1000
  | `useShellStrings() / useShellLocale()` | The active catalog, and the provider's `locale` (`undefined` without one) — for a host cell that should write a date or a number the way the kit does. |
999
1001
 
1000
1002
  ### Apps barrel — `efficient-shell/apps`
@@ -1475,6 +1477,35 @@ classes in `ui.css` (the timeline card's) carry pixel radii of their own.
1475
1477
  }
1476
1478
  ```
1477
1479
 
1480
+ **Corners.** A component does not pick a step of the scale for itself; it asks
1481
+ for the radius of what it is. Four role tokens, each defaulting to the step that
1482
+ role has always drawn, so they change nothing until you set one:
1483
+
1484
+ | Token | Default | Drawn by |
1485
+ |---|---|---|
1486
+ | `--radius-control` | `--radius-md` (6px) | buttons, fields, a segmented control's options |
1487
+ | `--radius-card` | `--radius-lg` (8px) | `Card`, `Dialog`, a segmented control's track |
1488
+ | `--radius-popup` | `--radius-2xl` (16px) | menus, select lists, the start menu, the search palette |
1489
+ | `--radius-window` | `--radius-2xl` (16px) | windows and their title bars |
1490
+
1491
+ They are plain custom properties: `:root { --radius-control: 2px; }` restyles
1492
+ one role and leaves the rest. Pills (switches, status badges, avatars) are round
1493
+ at every setting. Popovers, tooltips, drawers and menu rows still sit on their
1494
+ own scale steps, because each draws a different radius today and moving them
1495
+ onto a role would change how they look.
1496
+
1497
+ **Corners is also a setting of the theme.** The `corners` preference
1498
+ (`'square' | 'soft' | 'round'`, in Customization beside the colour theme) is
1499
+ stamped on `<html>` as `data-corners` by `useTheme` and
1500
+ `applyThemePrefs({ corners })`; a host with its own switcher calls
1501
+ `applyCorners(value)`. It rescales the whole radius scale, so the roles follow
1502
+ it and so does every scale utility in your own markup, and it remaps bare
1503
+ `rounded`, which the scale cannot reach. `soft` is the absence of the attribute:
1504
+ no rule applies and your own `@theme` radii still decide. `square` and `round`
1505
+ are a person's own choice, so they win over the host's theme, the way a chosen
1506
+ colour theme does. Do not write literal radii (an arbitrary-value radius class,
1507
+ an inline `borderRadius`): they are the one thing the setting cannot reach.
1508
+
1478
1509
  **Glass.** Menus, popups, listboxes and tooltips are frosted glass
1479
1510
  (`glassStyle()`). `--menu-opacity` (0–1, default `0.95`) sets how much shows
1480
1511
  through. `rosh-reduce-transparency` on `<html>` makes every popup one solid
@@ -1595,6 +1626,62 @@ the field, because what is typed there is parsed back.
1595
1626
  `formatDate(value, { locale, style })` or `fmtSliderDate(ms, locale)`, or hand it
1596
1627
  to `Intl` directly — so a host's dates and numbers read like the kit's.
1597
1628
 
1629
+ #### Choosing the language — `ShellLanguageProvider`
1630
+
1631
+ `ShellStringsProvider` can speak another language; `ShellLanguageProvider` is
1632
+ what decides which. It holds the languages you offer, the one in force and the
1633
+ reader's saved choice, stamps `<html lang>`, and mounts `ShellStringsProvider`
1634
+ for you with that language's catalog and locale.
1635
+
1636
+ A language is fixed for the life of a page. Resolve it before you mount, load
1637
+ its copy, and hand both over; `setLanguage` saves the choice and reloads. That
1638
+ is deliberate: column sets, navigation and status buckets usually read their
1639
+ copy when they are imported, a list snapshots its columns when it mounts, and
1640
+ a reload is the one switch that leaves none of them in the old language.
1641
+
1642
+ ```tsx
1643
+ import {
1644
+ ENGLISH, ShellLanguageProvider, resolveShellLanguage, useShellLanguage,
1645
+ type ShellLanguage,
1646
+ } from 'efficient-shell/ui';
1647
+
1648
+ const LANGUAGES: ShellLanguage[] = [ENGLISH, { tag: 'zh-Hans', name: '简体中文' }];
1649
+
1650
+ // Before React mounts: the saved choice, then the browser's list, then the first offered.
1651
+ const language = resolveShellLanguage({ offered: LANGUAGES });
1652
+
1653
+ <ShellLanguageProvider
1654
+ languages={LANGUAGES}
1655
+ language={language}
1656
+ strings={shellCatalogForThatLanguage} // omit for English
1657
+ onChange={tag => saveToTheAccount(tag)} // awaited, then the page reloads
1658
+ >
1659
+ <App />
1660
+ </ShellLanguageProvider>
1661
+
1662
+ const { language, languages, setLanguage } = useShellLanguage();
1663
+ ```
1664
+
1665
+ - **Resolution.** `resolveShellLanguage` reads the choice saved on the device
1666
+ (`SHELL_LANGUAGE_STORAGE_KEY`, `react-os-shell:language`), then
1667
+ `navigator.languages`, then falls back to the first language offered. A
1668
+ browser asking for `zh-CN` or `zh-SG` gets `zh-Hans`; with both Chineses on
1669
+ offer `zh-TW` gets `zh-Hant`, and with only Simplified it gets that rather
1670
+ than English. A saved choice that is no longer offered is skipped.
1671
+ `matchShellLanguage(wanted, offered)` is the matching on its own.
1672
+ - **English keeps its dates and numbers.** A language's `locale` defaults to
1673
+ its tag. `ENGLISH` carries `locale: null`, so mounting the provider for
1674
+ English moves no date and no number: the kit writes them as it does with no
1675
+ provider at all.
1676
+ - **The account.** `onChange` is where a host with accounts keeps the choice.
1677
+ It is awaited before the reload, and a failure does not stop the switch: the
1678
+ device has the choice. `saveShellLanguage(tag)` returns `true` only when the
1679
+ write reads back, for a sign-in sync that would otherwise reload on a write
1680
+ that never landed.
1681
+ - **`reload={false}`** leaves the switch to you: the choice is saved and
1682
+ `onChange` runs, and you re-render the provider with the new `language` and
1683
+ `strings`.
1684
+
1598
1685
  **What is not in the catalog, on purpose:** month and weekday names (the
1599
1686
  `locale` supplies them); file-format names in `BrandAssetEditor`'s default
1600
1687
  `acceptHint` and the `20ft`/`40ft` container codes (notation, not language); the
@@ -2581,6 +2668,68 @@ missing or cannot be read. All of them are also exported from
2581
2668
  | `dismissPopups()`, `OVERLAY_OPEN_EVENT` | An overlay calls `dismissPopups()` as it opens; every open kit popup (`Select`, `SearchableSelect`, `TagInput`, `DatePicker`, `DateRangePicker`, `PopupMenu` via its `onClose`, `ServerStatusIndicator`) closes rather than floating over the overlay. The kit's own overlays already call it. A consumer's own popup listens for `OVERLAY_OPEN_EVENT` on `window` while open. |
2582
2669
  | `Kbd` constants — `MOD`, `ALT`, `SHIFT`, `ENTER`, `ALT_SHIFT_E`, `CMD_K`, … | Symbol constants for rendering keyboard shortcuts. |
2583
2670
 
2671
+ ### Icons — `efficient-shell/icons`
2672
+
2673
+ Every icon comes through this package (harness UI-24). A component asks for an
2674
+ icon by what it **means**, and the set the theme chose draws it:
2675
+
2676
+ ```tsx
2677
+ import { Icon, registerIconSet } from 'efficient-shell/icons';
2678
+ import { heroicons } from 'efficient-shell/icons/heroicons';
2679
+
2680
+ registerIconSet(heroicons); // once, at startup, in client code
2681
+
2682
+ <Icon name="trash" /> // 1em square, the text's colour
2683
+ <Icon name="search" size={20} tone="muted" />
2684
+ <Icon name="warning" title="Overdue" /> // named: an image, not decoration
2685
+ ```
2686
+
2687
+ `Icon` and the registry are also exported from `efficient-shell/ui` and the
2688
+ root entry. They import React and nothing else.
2689
+
2690
+ **The catalogue.** `IconName` is 197 meanings (`add`, `close`, `edit`, `trash`,
2691
+ `search`, `download`, `chevron-down`, `warning`, …), built from the icons the
2692
+ EFFICIENT frontends import today. `<Icon name>` is typed to it, so a misspelt
2693
+ meaning does not compile. To add one, add it to `src/icons/catalogue.json` with
2694
+ its icon in every package and run `npm run icons`.
2695
+
2696
+ **The sets.** Each is its own subpath, so a host bundles only what it
2697
+ registers, and the icon package behind it is an optional peer:
2698
+
2699
+ | Import | Set | Draws | Needs |
2700
+ |---|---|---|---|
2701
+ | `efficient-shell/icons/heroicons` | `heroicons` | the whole catalogue | `@heroicons/react` |
2702
+ | `efficient-shell/icons/lucide` | `lucide` | the whole catalogue | `lucide-react` (0.577 or later) |
2703
+ | `efficient-shell/icons/efficient` | `efficient` | the 165 house glyphs, which draw 58 of the catalogue meanings | nothing |
2704
+
2705
+ The first set registered is the default (`setDefaultIconSet(name)` changes
2706
+ that). A meaning the chosen set does not draw falls back to the default set, so
2707
+ a partial set never leaves a hole.
2708
+
2709
+ **Part of the theme.** The `icon_set` preference sits beside the colour theme
2710
+ and the corners: `useTheme` and `applyThemePrefs({ icon_set })` choose the set
2711
+ and stamp `data-icon-set` on `<html>`, and every `<Icon>` on the page redraws.
2712
+ A host with its own switcher calls `applyIconSet(name)` or `setIconSet(name)`;
2713
+ `iconSets()` lists what is registered. Like `corners`, a call without the key
2714
+ leaves the choice alone.
2715
+
2716
+ **A product's own glyphs.** An editor's block types and settings rows are not
2717
+ in the catalogue. Register them and draw them by `glyph`, with no icon package
2718
+ imported:
2719
+
2720
+ ```tsx
2721
+ registerIcons('editor', { 'block-product': BlockProductGlyph });
2722
+ <Icon glyph="block-product" />
2723
+ ```
2724
+
2725
+ They are found under any theme. `efficient-shell/icons/efficient` also exports
2726
+ each house glyph as a component (`TrashIcon`, `StylesIcon`, `PaddingTopIcon`,
2727
+ …, `size` 18 by default) for code that wants one drawing whatever the theme.
2728
+
2729
+ With no set registered, `<Icon>` draws nothing and warns once per meaning. The
2730
+ kit's own components (a window's close button, a filter chip) keep drawing
2731
+ through a built-in fallback, so a host that registers nothing sees no change.
2732
+
2584
2733
  ### The UI kit check — `efficient-shell-ui-check`
2585
2734
 
2586
2735
  Every surface a person operates takes its UI from this package (harness
@@ -2616,8 +2765,9 @@ itself where the kit has an answer:
2616
2765
  | `native` | `window.confirm` / `alert` / `prompt`, or a bare call nothing in the file binds | `confirm`, `confirmDestructive`, `prompt`, `toast` |
2617
2766
  | `dark` | a `dark:` variant in a class string | the light class alone; the kit remaps it |
2618
2767
  | `hex` | a hex colour in a `.tsx` string (not in `href`, `to`, `id`, `key`, `htmlFor`) | a token or a palette class |
2768
+ | `radius` | a literal corner radius: an arbitrary-value radius class (`rounded-[4px]`) or an inline `borderRadius` number or length (not `inherit`, `var(…)`, `50%` or `9999`) | a scale utility or a role token; the theme's Corners setting shapes them |
2619
2769
  | `kit` | an import of a second UI kit (`@headlessui`, `@radix-ui`, `@mui`, `antd`, `sonner`, …) | the kit's component |
2620
- | `icon` | an import of an icon package (`@heroicons`, `lucide-react`, `@tabler/icons`, …) | the icon through this package |
2770
+ | `icon` | an import of an icon package (`@heroicons`, `lucide-react`, `@tabler/icons`, …) | `<Icon name>` from `efficient-shell/icons` |
2621
2771
  | `kit-dep` | one of those packages declared in `package.json` (not `devDependencies`) | remove it |
2622
2772
 
2623
2773
  Known gaps: `rgb()` / `hsl()` colours, colours in `.ts` maps, and
@@ -1,29 +1,29 @@
1
- import{peekBrowserStartUrl as e,claimBrowserStartUrl as t}from"./chunk-LWLCNQY7.js";import{AboutApp as o}from"./chunk-6MBERZOS.js";import"./chunk-7U3F53IG.js";import{WindowTitle as r}from"./chunk-LW27IM3S.js";import"./chunk-A7Q4BCPI.js";import"./chunk-DSSLOQDW.js";import"./chunk-5A7MWTXX.js";import"./chunk-JYLI2WXW.js";import"./chunk-6KO2U66R.js";import{confirm as n}from"./chunk-M4DB7UBZ.js";import"./chunk-N3ZXQE4M.js";import"./chunk-AFYQTVZO.js";import"./chunk-HZZNJHRH.js";import"./chunk-X4FJ54PP.js";import"./chunk-NCQLGQYR.js";import"./chunk-D65T4H6J.js";import{useRef as a,useEffect as i,useState as s}from"react";import{jsxs as l,jsx as c,Fragment as m}from"react/jsx-runtime";var d="react-os-shell:browser-bookmarks",u="react-os-shell:browser-homepage",h="https://en.wikipedia.org/wiki/Main_Page",p=[{label:"Wikipedia",url:"https://en.wikipedia.org/wiki/Main_Page"},{label:"DevDocs",url:"https://devdocs.io"},{label:"Example",url:"https://example.com"}],g=new Set(["ac ad ae af ag ai al am ao aq ar as at au aw ax az ba bb bd be bf bg bh bi","bj bm bn bo br bs bt bw by bz ca cc cd cf cg ch ci ck cl cm cn co cr cu cv","cw cx cy cz de dj dk dm do dz ec ee eg er es et eu fi fj fk fm fo fr ga gd","ge gf gg gh gi gl gm gn gp gq gr gs gt gu gw gy hk hm hn hr ht hu id ie il","im in io iq ir is it je jm jo jp ke kg kh ki km kn kp kr kw ky kz la lb lc","li lk lr ls lt lu lv ly ma mc md me mg mh mk ml mm mn mo mp mq mr ms mt mu","mv mw mx my mz na nc ne nf ng ni nl no np nr nu nz om pa pe pf pg ph pk pl","pm pn pr ps pt pw py qa re ro rs ru rw sa sb sc sd se sg sh si sk sl sm sn","so sr ss st su sv sx sy sz tc td tf tg th tj tk tl tm tn to tr tt tv tw tz","ua ug uk us uy uz va vc ve vg vi vn vu wf ws ye yt za zm zw","com net org edu gov mil int info biz name pro app dev xyz online site tech","store shop cloud design digital agency studio media news blog live life","world today email systems solutions services software page link space host","press wiki team group works careers finance capital energy academy"].join(" ").split(" "));function b(e){let t=e.trim();return t?/^[a-z][a-z0-9+.-]*:\/\//i.test(t)?t:function(e){const t=/^([\w-]+\.)+([a-z]{2,})(\/.*)?$/i.exec(e);return null!==t&&g.has(t[2].toLowerCase())}(t)?"https://"+t:"https://duckduckgo.com/?q="+encodeURIComponent(t):""}var k=["duckduckgo.com","developer.mozilla.org","google.com","gmail.com","youtube.com","facebook.com","instagram.com","whatsapp.com","twitter.com","x.com","github.com","gitlab.com","linkedin.com","reddit.com","pinterest.com","amazon.com","amazon.ca","amazon.co.uk","apple.com","icloud.com","microsoft.com","outlook.com","live.com","office.com","netflix.com","spotify.com","paypal.com","stripe.com","chat.openai.com","chatgpt.com","claude.ai"];function f(){if("undefined"==typeof window)return p;try{const e=localStorage.getItem(d);if(!e)return p;const t=JSON.parse(e);if(Array.isArray(t)&&t.every(e=>"string"==typeof e?.url))return t}catch{}return p}function x(){return"undefined"==typeof window?h:localStorage.getItem(u)||h}function w(){const m=a(void 0);void 0===m.current&&(m.current=e()),i(()=>{null!=m.current&&t(m.current)},[]);const h=m.current?b(m.current.url):"",[p,g]=s(x),[k,w]=s(h||p),[N,L]=s(k),[j,C]=s([k]),[z,M]=s(0),[W,S]=s(0),[R,B]=s(f),[H,A]=s(!1),[E,D]=s(null),I=a(null),O=a(null);i(()=>{try{localStorage.setItem(d,JSON.stringify(R))}catch{}},[R]);const T=e=>{const t=b(e);t&&(w(t),L(t),C(e=>{const o=e.slice(0,z+1);return o.push(t),o}),M(e=>e+1),A(!1))},U=()=>{"undefined"!=typeof window&&window.open(k,"_blank","noopener,noreferrer")},P=()=>{const e=E?.trim();e?(B(t=>[...t,{label:e,url:k}]),D(null)):D(null)};i(()=>{if(null===E)return;I.current?.focus(),I.current?.select();const e=e=>{const t=e.target;t?.closest("[data-bookmark-popover]")||D(null)},t=setTimeout(()=>document.addEventListener("mousedown",e),0);return()=>{clearTimeout(t),document.removeEventListener("mousedown",e)}},[null!==E]);const F=e=>{B(t=>t.filter((t,o)=>o!==e))},Q=z>0,X=z<j.length-1,q=R.some(e=>e.url===k),J="p-1.5 rounded hover:bg-gray-200 transition-colors text-gray-600 disabled:opacity-30";/* @__PURE__ */
1
+ import{peekBrowserStartUrl as e,claimBrowserStartUrl as t}from"./chunk-LWLCNQY7.js";import{AboutApp as o}from"./chunk-36QX6LOQ.js";import{WindowTitle as r}from"./chunk-FWZUTHP5.js";import"./chunk-DSSLOQDW.js";import"./chunk-6KO2U66R.js";import"./chunk-67ZUPDWG.js";import"./chunk-CRI4UFBU.js";import"./chunk-5A7MWTXX.js";import"./chunk-EXXHI5DO.js";import"./chunk-PGVUO7GB.js";import"./chunk-HZZNJHRH.js";import"./chunk-D65T4H6J.js";import{confirm as n}from"./chunk-ECFMRDUP.js";import"./chunk-AFYQTVZO.js";import"./chunk-X4FJ54PP.js";import"./chunk-NCQLGQYR.js";import"./chunk-YKZHOXI4.js";import{useRef as a,useEffect as i,useState as s}from"react";import{jsxs as l,jsx as c,Fragment as m}from"react/jsx-runtime";var d="react-os-shell:browser-bookmarks",u="react-os-shell:browser-homepage",h="https://en.wikipedia.org/wiki/Main_Page",p=[{label:"Wikipedia",url:"https://en.wikipedia.org/wiki/Main_Page"},{label:"DevDocs",url:"https://devdocs.io"},{label:"Example",url:"https://example.com"}],g=new Set(["ac ad ae af ag ai al am ao aq ar as at au aw ax az ba bb bd be bf bg bh bi","bj bm bn bo br bs bt bw by bz ca cc cd cf cg ch ci ck cl cm cn co cr cu cv","cw cx cy cz de dj dk dm do dz ec ee eg er es et eu fi fj fk fm fo fr ga gd","ge gf gg gh gi gl gm gn gp gq gr gs gt gu gw gy hk hm hn hr ht hu id ie il","im in io iq ir is it je jm jo jp ke kg kh ki km kn kp kr kw ky kz la lb lc","li lk lr ls lt lu lv ly ma mc md me mg mh mk ml mm mn mo mp mq mr ms mt mu","mv mw mx my mz na nc ne nf ng ni nl no np nr nu nz om pa pe pf pg ph pk pl","pm pn pr ps pt pw py qa re ro rs ru rw sa sb sc sd se sg sh si sk sl sm sn","so sr ss st su sv sx sy sz tc td tf tg th tj tk tl tm tn to tr tt tv tw tz","ua ug uk us uy uz va vc ve vg vi vn vu wf ws ye yt za zm zw","com net org edu gov mil int info biz name pro app dev xyz online site tech","store shop cloud design digital agency studio media news blog live life","world today email systems solutions services software page link space host","press wiki team group works careers finance capital energy academy"].join(" ").split(" "));function b(e){let t=e.trim();return t?/^[a-z][a-z0-9+.-]*:\/\//i.test(t)?t:function(e){const t=/^([\w-]+\.)+([a-z]{2,})(\/.*)?$/i.exec(e);return null!==t&&g.has(t[2].toLowerCase())}(t)?"https://"+t:"https://duckduckgo.com/?q="+encodeURIComponent(t):""}var k=["duckduckgo.com","developer.mozilla.org","google.com","gmail.com","youtube.com","facebook.com","instagram.com","whatsapp.com","twitter.com","x.com","github.com","gitlab.com","linkedin.com","reddit.com","pinterest.com","amazon.com","amazon.ca","amazon.co.uk","apple.com","icloud.com","microsoft.com","outlook.com","live.com","office.com","netflix.com","spotify.com","paypal.com","stripe.com","chat.openai.com","chatgpt.com","claude.ai"];function f(){if("undefined"==typeof window)return p;try{const e=localStorage.getItem(d);if(!e)return p;const t=JSON.parse(e);if(Array.isArray(t)&&t.every(e=>"string"==typeof e?.url))return t}catch{}return p}function x(){return"undefined"==typeof window?h:localStorage.getItem(u)||h}function w(){const m=a(void 0);void 0===m.current&&(m.current=e()),i(()=>{null!=m.current&&t(m.current)},[]);const h=m.current?b(m.current.url):"",[p,g]=s(x),[k,w]=s(h||p),[N,L]=s(k),[j,C]=s([k]),[z,M]=s(0),[W,H]=s(0),[R,S]=s(f),[B,D]=s(!1),[O,U]=s(null),A=a(null),E=a(null);i(()=>{try{localStorage.setItem(d,JSON.stringify(R))}catch{}},[R]);const P=e=>{const t=b(e);t&&(w(t),L(t),C(e=>{const o=e.slice(0,z+1);return o.push(t),o}),M(e=>e+1),D(!1))},T=()=>{"undefined"!=typeof window&&window.open(k,"_blank","noopener,noreferrer")},F=()=>{const e=O?.trim();e?(S(t=>[...t,{label:e,url:k}]),U(null)):U(null)};i(()=>{if(null===O)return;A.current?.focus(),A.current?.select();const e=e=>{const t=e.target;t?.closest("[data-bookmark-popover]")||U(null)},t=setTimeout(()=>document.addEventListener("mousedown",e),0);return()=>{clearTimeout(t),document.removeEventListener("mousedown",e)}},[null!==O]);const I=e=>{S(t=>t.filter((t,o)=>o!==e))},X=z>0,G=z<j.length-1,Q=R.some(e=>e.url===k),V="p-1.5 rounded hover:bg-gray-200 transition-colors text-gray-600 disabled:opacity-30";/* @__PURE__ */
2
2
  return l("div",{className:"relative flex flex-col h-full bg-white",children:[
3
3
  /* @__PURE__ */c(r,{title:`Browser - ${v(k)}`}),
4
4
  /* @__PURE__ */c(o,{app:"browser"}),
5
5
  /* @__PURE__ */l("div",{className:"flex items-center gap-1 px-2 py-1.5 border-b border-gray-200 bg-gray-50 shrink-0",children:[
6
- /* @__PURE__ */c("button",{onClick:()=>{if(z>0){const e=z-1;M(e),w(j[e]),L(j[e]),A(!1)}},disabled:!Q,className:J,title:"Back",children:/* @__PURE__ */c("svg",{className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:/* @__PURE__ */c("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15.75 19.5L8.25 12l7.5-7.5"})})}),
7
- /* @__PURE__ */c("button",{onClick:()=>{if(z<j.length-1){const e=z+1;M(e),w(j[e]),L(j[e]),A(!1)}},disabled:!X,className:J,title:"Forward",children:/* @__PURE__ */c("svg",{className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:/* @__PURE__ */c("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8.25 4.5l7.5 7.5-7.5 7.5"})})}),
8
- /* @__PURE__ */c("button",{onClick:()=>S(e=>e+1),className:J,title:"Refresh",children:/* @__PURE__ */c("svg",{className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.8,children:/* @__PURE__ */c("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M16.023 9.348h4.992V4.356M2.985 19.644v-4.992h4.992M3.05 9.348a9 9 0 0114.85-3.36L21.015 9.348m0 5.304a9 9 0 01-14.85 3.36l-3.115-3.36"})})}),
9
- /* @__PURE__ */c("button",{onClick:()=>T(p),className:J,title:"Home",children:/* @__PURE__ */c("svg",{className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.8,children:/* @__PURE__ */c("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M2.25 12l8.954-8.955a1.5 1.5 0 012.122 0l8.954 8.955M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25"})})}),
10
- /* @__PURE__ */c("form",{onSubmit:e=>{e.preventDefault(),T(N)},className:"flex-1 flex items-center mx-1",children:/* @__PURE__ */l("div",{className:"flex items-center w-full bg-white border border-gray-300 rounded focus-within:border-blue-400 focus-within:ring-1 focus-within:ring-blue-200",children:[
6
+ /* @__PURE__ */c("button",{onClick:()=>{if(z>0){const e=z-1;M(e),w(j[e]),L(j[e]),D(!1)}},disabled:!X,className:V,title:"Back",children:/* @__PURE__ */c("svg",{className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:/* @__PURE__ */c("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15.75 19.5L8.25 12l7.5-7.5"})})}),
7
+ /* @__PURE__ */c("button",{onClick:()=>{if(z<j.length-1){const e=z+1;M(e),w(j[e]),L(j[e]),D(!1)}},disabled:!G,className:V,title:"Forward",children:/* @__PURE__ */c("svg",{className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:/* @__PURE__ */c("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8.25 4.5l7.5 7.5-7.5 7.5"})})}),
8
+ /* @__PURE__ */c("button",{onClick:()=>H(e=>e+1),className:V,title:"Refresh",children:/* @__PURE__ */c("svg",{className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.8,children:/* @__PURE__ */c("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M16.023 9.348h4.992V4.356M2.985 19.644v-4.992h4.992M3.05 9.348a9 9 0 0114.85-3.36L21.015 9.348m0 5.304a9 9 0 01-14.85 3.36l-3.115-3.36"})})}),
9
+ /* @__PURE__ */c("button",{onClick:()=>P(p),className:V,title:"Home",children:/* @__PURE__ */c("svg",{className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.8,children:/* @__PURE__ */c("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M2.25 12l8.954-8.955a1.5 1.5 0 012.122 0l8.954 8.955M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25"})})}),
10
+ /* @__PURE__ */c("form",{onSubmit:e=>{e.preventDefault(),P(N)},className:"flex-1 flex items-center mx-1",children:/* @__PURE__ */l("div",{className:"flex items-center w-full bg-white border border-gray-300 rounded focus-within:border-blue-400 focus-within:ring-1 focus-within:ring-blue-200",children:[
11
11
  /* @__PURE__ */c("span",{className:"px-2 text-gray-400 text-xs",children:k.startsWith("https://")?"🔒":"⚠️"}),
12
12
  /* @__PURE__ */c("input",{type:"text",value:N,onChange:e=>L(e.target.value),onFocus:e=>e.target.select(),className:"flex-1 px-1 py-1 text-sm bg-transparent outline-none font-mono",spellCheck:!1,placeholder:"Enter URL or search…"}),k!==N&&/* @__PURE__ */c("button",{type:"button",onClick:()=>L(k),className:"px-1.5 text-[10px] text-gray-400 hover:text-gray-700",title:"Reset to current URL",children:"×"})]})}),
13
- /* @__PURE__ */c("button",{"data-bookmark-popover":!0,onClick:()=>q?F(R.findIndex(e=>e.url===k)):void D(v(k)),className:J+" "+(q?"text-yellow-500":""),title:q?"Remove bookmark":"Add bookmark",children:/* @__PURE__ */c("svg",{className:"h-4 w-4",fill:q?"currentColor":"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.5,children:/* @__PURE__ */c("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z"})})}),
14
- /* @__PURE__ */c("button",{onClick:U,className:J,title:"Open in new tab",children:/* @__PURE__ */c("svg",{className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.5,children:/* @__PURE__ */c("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-7.5-9L21 3m0 0v6m0-6L9.75 14.25"})})}),
15
- /* @__PURE__ */c("button",{onClick:()=>A(e=>!e),className:J,title:"Embedding help",children:/* @__PURE__ */c("svg",{className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.5,children:/* @__PURE__ */c("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9 5.25h.008v.008H12v-.008z"})})})]}),null!==E&&/* @__PURE__ */l("div",{"data-bookmark-popover":!0,className:"absolute right-3 top-12 z-30 w-72 bg-white border border-gray-200 rounded-md shadow-lg p-3",children:[
13
+ /* @__PURE__ */c("button",{"data-bookmark-popover":!0,onClick:()=>Q?I(R.findIndex(e=>e.url===k)):void U(v(k)),className:V+" "+(Q?"text-yellow-500":""),title:Q?"Remove bookmark":"Add bookmark",children:/* @__PURE__ */c("svg",{className:"h-4 w-4",fill:Q?"currentColor":"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.5,children:/* @__PURE__ */c("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z"})})}),
14
+ /* @__PURE__ */c("button",{onClick:T,className:V,title:"Open in new tab",children:/* @__PURE__ */c("svg",{className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.5,children:/* @__PURE__ */c("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-7.5-9L21 3m0 0v6m0-6L9.75 14.25"})})}),
15
+ /* @__PURE__ */c("button",{onClick:()=>D(e=>!e),className:V,title:"Embedding help",children:/* @__PURE__ */c("svg",{className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.5,children:/* @__PURE__ */c("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9 5.25h.008v.008H12v-.008z"})})})]}),null!==O&&/* @__PURE__ */l("div",{"data-bookmark-popover":!0,className:"absolute right-3 top-12 z-30 w-72 bg-white border border-gray-200 rounded-md shadow-lg p-3",children:[
16
16
  /* @__PURE__ */c("div",{className:"text-[11px] font-semibold uppercase tracking-wide text-gray-500 mb-1",children:"Bookmark this page"}),
17
17
  /* @__PURE__ */c("div",{className:"text-[11px] text-gray-400 truncate mb-2 font-mono",title:k,children:k}),
18
- /* @__PURE__ */c("input",{ref:I,type:"text",value:E,onChange:e=>D(e.target.value),onKeyDown:e=>{"Enter"===e.key?P():"Escape"===e.key&&D(null)},placeholder:"Name",className:"w-full text-sm px-2 py-1.5 border border-gray-300 rounded focus:outline-none focus:border-blue-400 focus:ring-1 focus:ring-blue-200"}),
18
+ /* @__PURE__ */c("input",{ref:A,type:"text",value:O,onChange:e=>U(e.target.value),onKeyDown:e=>{"Enter"===e.key?F():"Escape"===e.key&&U(null)},placeholder:"Name",className:"w-full text-sm px-2 py-1.5 border border-gray-300 rounded focus:outline-none focus:border-blue-400 focus:ring-1 focus:ring-blue-200"}),
19
19
  /* @__PURE__ */l("div",{className:"flex justify-end gap-1 mt-2",children:[
20
- /* @__PURE__ */c("button",{onClick:()=>D(null),className:"px-2 py-1 text-xs text-gray-600 hover:bg-gray-100 rounded",children:"Cancel"}),
21
- /* @__PURE__ */c("button",{onClick:P,disabled:!E.trim(),className:"px-2 py-1 text-xs bg-blue-500 text-white rounded hover:bg-blue-600 disabled:opacity-40",children:"Save"})]})]}),
22
- /* @__PURE__ */l("div",{className:"flex items-center gap-0.5 px-2 py-1 border-b border-gray-200 bg-white shrink-0 overflow-x-auto",children:[0===R.length&&/* @__PURE__ */c("span",{className:"text-[11px] text-gray-400 italic px-2",children:"No bookmarks yet — star the address bar to add one."}),R.map((e,t)=>/* @__PURE__ */l("button",{onClick:()=>T(e.url),onContextMenu:async o=>{o.preventDefault();await n({title:"Remove bookmark",message:`"${e.label}" will be removed from your bookmarks.`,confirmLabel:"Remove",variant:"danger"})&&F(t)},className:"flex items-center gap-1.5 px-2 py-0.5 rounded text-[12px] text-gray-700 hover:bg-gray-100 whitespace-nowrap",title:`${e.url}\n(right-click to remove)`,children:[
20
+ /* @__PURE__ */c("button",{onClick:()=>U(null),className:"px-2 py-1 text-xs text-gray-600 hover:bg-gray-100 rounded",children:"Cancel"}),
21
+ /* @__PURE__ */c("button",{onClick:F,disabled:!O.trim(),className:"px-2 py-1 text-xs bg-blue-500 text-white rounded hover:bg-blue-600 disabled:opacity-40",children:"Save"})]})]}),
22
+ /* @__PURE__ */l("div",{className:"flex items-center gap-0.5 px-2 py-1 border-b border-gray-200 bg-white shrink-0 overflow-x-auto",children:[0===R.length&&/* @__PURE__ */c("span",{className:"text-[11px] text-gray-400 italic px-2",children:"No bookmarks yet — star the address bar to add one."}),R.map((e,t)=>/* @__PURE__ */l("button",{onClick:()=>P(e.url),onContextMenu:async o=>{o.preventDefault();await n({title:"Remove bookmark",message:`"${e.label}" will be removed from your bookmarks.`,confirmLabel:"Remove",variant:"danger"})&&I(t)},className:"flex items-center gap-1.5 px-2 py-0.5 rounded text-[12px] text-gray-700 hover:bg-gray-100 whitespace-nowrap",title:`${e.url}\n(right-click to remove)`,children:[
23
23
  /* @__PURE__ */c("img",{src:`https://icons.duckduckgo.com/ip3/${new URL(e.url).hostname}.ico`,alt:"",className:"h-3.5 w-3.5",onError:e=>{e.target.style.visibility="hidden"}}),e.label]},t)),
24
24
  /* @__PURE__ */c("div",{className:"flex-1"}),
25
25
  /* @__PURE__ */c("button",{onClick:()=>{g(k);try{localStorage.setItem(u,k)}catch{}},className:"px-2 py-0.5 text-[11px] text-gray-500 hover:text-gray-800",title:"Set current page as homepage",children:"Set as home"})]}),
26
- /* @__PURE__ */c("div",{className:"flex-1 relative min-h-0 bg-gray-50",children:/* @__PURE__ */c(y,{url:k,iframeKey:W,iframeRef:O,openExternal:U,showHelp:H,dismissHelp:()=>A(!1)})})]})}function v(e){try{return new URL(e).hostname.replace(/^www\./,"")}catch{return e}}function y({url:e,iframeKey:t,iframeRef:o,openExternal:r,showHelp:n,dismissHelp:a}){const[d,u]=s(!1);i(()=>{u(!1)},[e]);return function(e){try{const t=new URL(e).hostname.toLowerCase();return k.some(e=>t===e||t.endsWith("."+e))}catch{return!1}}(e)&&!d?/* @__PURE__ */c("div",{className:"absolute inset-0 flex items-center justify-center bg-white p-8",children:/* @__PURE__ */l("div",{className:"max-w-md text-center",children:[
26
+ /* @__PURE__ */c("div",{className:"flex-1 relative min-h-0 bg-gray-50",children:/* @__PURE__ */c(y,{url:k,iframeKey:W,iframeRef:E,openExternal:T,showHelp:B,dismissHelp:()=>D(!1)})})]})}function v(e){try{return new URL(e).hostname.replace(/^www\./,"")}catch{return e}}function y({url:e,iframeKey:t,iframeRef:o,openExternal:r,showHelp:n,dismissHelp:a}){const[d,u]=s(!1);i(()=>{u(!1)},[e]);return function(e){try{const t=new URL(e).hostname.toLowerCase();return k.some(e=>t===e||t.endsWith("."+e))}catch{return!1}}(e)&&!d?/* @__PURE__ */c("div",{className:"absolute inset-0 flex items-center justify-center bg-white p-8",children:/* @__PURE__ */l("div",{className:"max-w-md text-center",children:[
27
27
  /* @__PURE__ */c("svg",{className:"h-14 w-14 mx-auto text-gray-300 mb-3",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.2,children:/* @__PURE__ */c("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728L5.636 5.636m12.728 12.728L21 21M5.636 5.636L3 3m9 9a9 9 0 110-18 9 9 0 010 18z"})}),
28
28
  /* @__PURE__ */l("h3",{className:"text-base font-semibold text-gray-800 mb-1",children:[v(e)," can't be embedded"]}),
29
29
  /* @__PURE__ */l("p",{className:"text-sm text-gray-500 mb-4",children:["This site sends an ",
@@ -0,0 +1,29 @@
1
+ import{loadAppearance as e,WidgetSettingsModal as t}from"./chunk-2UIKLYAI.js";import{useWidgetSettings as n}from"./chunk-FWZUTHP5.js";import"./chunk-DSSLOQDW.js";import"./chunk-6KO2U66R.js";import"./chunk-CRI4UFBU.js";import"./chunk-5A7MWTXX.js";import"./chunk-EXXHI5DO.js";import"./chunk-PGVUO7GB.js";import"./chunk-HZZNJHRH.js";import"./chunk-D65T4H6J.js";import"./chunk-ECFMRDUP.js";import"./chunk-AFYQTVZO.js";import"./chunk-X4FJ54PP.js";import"./chunk-NCQLGQYR.js";import"./chunk-YKZHOXI4.js";import{useState as r,useRef as l,useCallback as o,useEffect as i}from"react";import{jsxs as a,Fragment as c,jsx as s}from"react/jsx-runtime";var u="calc_appearance";function d(){const[d,h]=r("0"),[m,k]=r(null),[b,p]=r(null),[g,v]=r(!1),[x,y]=r(""),[N,f]=r([]),[C,$]=r(!1),[j,w]=r(()=>e(u)),[E,L]=r(!1),[F,S]=r(j),T=l(null);n(o(()=>{S({...j}),L(!0)},[j]));const H=o(e=>{y(""),h(t=>g||"0"===t?(v(!1),"."===e?"0.":e):"."===e&&t.includes(".")?t:t+e)},[g]),O=o(()=>{h("0"),k(null),p(null),v(!1)},[]),U=o((e,t,n)=>{switch(n){case"+":return e+t;case"-":return e-t;case"×":return e*t;case"÷":return 0===t?0:e/t;default:return t}},[]),W=o(e=>{const t=parseFloat(d);if(null!==m&&b&&!g){const e=U(m,t,b);h(String(e)),k(e),f(n=>[`${m} ${b} ${t} = ${e}`,...n].slice(0,20))}else k(t);p(e),v(!0)},[d,m,b,g,U]),A=o(()=>{if(null===m||!b)return;const e=parseFloat(d),t=U(m,e,b),n=`${m} ${b} ${e} =`;f(e=>[`${n} ${t}`,...e].slice(0,20)),y(n),h(String(t)),k(null),p(null),v(!0)},[d,m,b,U]),B=o(()=>{h(e=>String(parseFloat(e)/100))},[]),D=o(()=>{h(e=>e.startsWith("-")?e.slice(1):"0"===e?e:"-"+e)},[]);i(()=>{const e=e=>{const t=e.target.tagName;"INPUT"!==t&&"TEXTAREA"!==t&&"SELECT"!==t&&(e.key>="0"&&e.key<="9"?H(e.key):"."===e.key?H("."):"+"===e.key?W("+"):"-"===e.key?W("-"):"*"===e.key?W("×"):"/"===e.key?(e.preventDefault(),W("÷")):"Enter"===e.key||"="===e.key?("Enter"===e.key&&e.target instanceof Node&&T.current?.contains(e.target)&&e.preventDefault(),A()):"Escape"===e.key?O():"Backspace"===e.key?h(e=>e.length>1?e.slice(0,-1):"0"):"%"===e.key&&B())};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[H,W,A,O,B]);const I="flex items-center justify-center rounded-lg text-sm font-medium transition-colors",X=`${I} bg-white border border-gray-200 text-gray-900 hover:bg-gray-50 active:bg-gray-100`,P=`${I} bg-blue-50 border border-blue-200 text-blue-700 hover:bg-blue-100 active:bg-blue-200`,R=`${I} bg-gray-100 border border-gray-200 text-gray-600 hover:bg-gray-200 active:bg-gray-300`,M=`${I} bg-blue-600 text-white hover:bg-blue-700 active:bg-blue-800`;/* @__PURE__ */
2
+ return a(c,{children:[
3
+ /* @__PURE__ */a("div",{ref:T,className:"flex flex-col h-full",style:{opacity:j.activeOpacity/100,backdropFilter:j.activeBlur>0?`blur(${j.activeBlur}px)`:void 0},children:[
4
+ /* @__PURE__ */a("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",children:[
5
+ /* @__PURE__ */s("div",{className:"flex flex-col justify-end flex-1 overflow-hidden",children:N.slice(0,3).reverse().map((e,t)=>/* @__PURE__ */s("div",{className:"text-[11px] text-slate-400 text-right font-mono truncate",children:e},t))}),(x||b&&null!==m)&&/* @__PURE__ */s("div",{className:"text-base text-slate-600 text-right font-mono",children:x||`${m} ${b} ${g?"":d}`}),
6
+ /* @__PURE__ */a("div",{className:"flex items-center gap-2",children:[
7
+ /* @__PURE__ */s("button",{onClick:()=>{navigator.clipboard.writeText(d),$(!0),setTimeout(()=>$(!1),1200)},title:"Copy result",className:"shrink-0 text-slate-300 hover:text-slate-500 transition-colors opacity-0 group-hover/display:opacity-100",children:/* @__PURE__ */s("svg",C?{className:"h-5 w-5 text-green-500",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:/* @__PURE__ */s("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 13l4 4L19 7"})}:{className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:/* @__PURE__ */s("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"})})}),
8
+ /* @__PURE__ */s("div",{className:"text-right text-4xl font-mono font-bold text-slate-800 truncate flex-1",children:(e=>{const t=parseFloat(e);return isNaN(t)||e.endsWith(".")||e.endsWith(".0")||Math.abs(t)<1e15&&e.length<16?e:t.toExponential(6)})(d)})]})]}),
9
+ /* @__PURE__ */a("div",{className:"grid grid-cols-4 grid-rows-5 gap-1.5 flex-1 min-h-0 p-2",children:[
10
+ /* @__PURE__ */s("button",{onClick:O,className:R,children:"AC"}),
11
+ /* @__PURE__ */s("button",{onClick:D,className:R,children:"+/−"}),
12
+ /* @__PURE__ */s("button",{onClick:B,className:R,children:"%"}),
13
+ /* @__PURE__ */s("button",{onClick:()=>W("÷"),className:`${P} ${"÷"===b?"ring-2 ring-blue-400":""}`,children:"÷"}),
14
+ /* @__PURE__ */s("button",{onClick:()=>H("7"),className:X,children:"7"}),
15
+ /* @__PURE__ */s("button",{onClick:()=>H("8"),className:X,children:"8"}),
16
+ /* @__PURE__ */s("button",{onClick:()=>H("9"),className:X,children:"9"}),
17
+ /* @__PURE__ */s("button",{onClick:()=>W("×"),className:`${P} ${"×"===b?"ring-2 ring-blue-400":""}`,children:"×"}),
18
+ /* @__PURE__ */s("button",{onClick:()=>H("4"),className:X,children:"4"}),
19
+ /* @__PURE__ */s("button",{onClick:()=>H("5"),className:X,children:"5"}),
20
+ /* @__PURE__ */s("button",{onClick:()=>H("6"),className:X,children:"6"}),
21
+ /* @__PURE__ */s("button",{onClick:()=>W("-"),className:`${P} ${"-"===b?"ring-2 ring-blue-400":""}`,children:"−"}),
22
+ /* @__PURE__ */s("button",{onClick:()=>H("1"),className:X,children:"1"}),
23
+ /* @__PURE__ */s("button",{onClick:()=>H("2"),className:X,children:"2"}),
24
+ /* @__PURE__ */s("button",{onClick:()=>H("3"),className:X,children:"3"}),
25
+ /* @__PURE__ */s("button",{onClick:()=>W("+"),className:`${P} ${"+"===b?"ring-2 ring-blue-400":""}`,children:"+"}),
26
+ /* @__PURE__ */s("button",{onClick:()=>H("0"),className:`${X} col-span-2`,children:"0"}),
27
+ /* @__PURE__ */s("button",{onClick:()=>H("."),className:X,children:"."}),
28
+ /* @__PURE__ */s("button",{onClick:A,className:M,children:"="})]})]}),
29
+ /* @__PURE__ */s(t,{open:E,onClose:()=>L(!1),title:"Calculator Settings",appearance:F,onAppearanceChange:S,onSave:()=>{w(F),localStorage.setItem(u,JSON.stringify(F)),L(!1)}})]})}export{d as default};
@@ -0,0 +1 @@
1
+ export{ConfirmProvider,confirm,confirmDestructive,prompt,useConfirm}from"./chunk-ECFMRDUP.js";import"./chunk-AFYQTVZO.js";import"./chunk-X4FJ54PP.js";import"./chunk-NCQLGQYR.js";
@@ -1,4 +1,4 @@
1
- import{loadAppearance as e,WidgetSettingsModal as t}from"./chunk-JLPJBO7K.js";import{useWidgetSettings as r}from"./chunk-LW27IM3S.js";import"./chunk-A7Q4BCPI.js";import"./chunk-DSSLOQDW.js";import"./chunk-5A7MWTXX.js";import"./chunk-JYLI2WXW.js";import"./chunk-6KO2U66R.js";import"./chunk-M4DB7UBZ.js";import"./chunk-N3ZXQE4M.js";import"./chunk-AFYQTVZO.js";import"./chunk-HZZNJHRH.js";import"./chunk-X4FJ54PP.js";import"./chunk-NCQLGQYR.js";import"./chunk-D65T4H6J.js";import{useState as a,useCallback as n,useEffect as s}from"react";import{jsxs as c,Fragment as o,jsx as i}from"react/jsx-runtime";var l=["USD","CNY","AUD","GBP","EUR","JPY","CAD","THB","NZD","SGD","HKD","CHF","KRW","INR","MXN","BRL"],m=[["USD","CNY"],["USD","AUD"],["GBP","USD"],["USD","JPY"]],u="currency_pairs",p="currency_appearance",d="currency_rates_cache";function h(e){try{const t=JSON.parse(localStorage.getItem(d)||"{}")[e];if(t&&Date.now()-t.timestamp<36e5)return t.rates}catch{}return null}function g(e,t){try{const r=JSON.parse(localStorage.getItem(d)||"{}");r[e]={rates:t,timestamp:Date.now()},localStorage.setItem(d,JSON.stringify(r))}catch{}}function x(){try{const e=JSON.parse(localStorage.getItem(u)||"");if(Array.isArray(e)&&e.length)return e.slice(0,4)}catch{}return m}var y={USD:"🇺🇸",CNY:"🇨🇳",AUD:"🇦🇺",GBP:"🇬🇧",JPY:"🇯🇵",CAD:"🇨🇦",EUR:"🇪🇺",THB:"🇹🇭",NZD:"🇳🇿",SGD:"🇸🇬",HKD:"🇭🇰",CHF:"🇨🇭",KRW:"🇰🇷",INR:"🇮🇳",MXN:"🇲🇽",BRL:"🇧🇷"};function f(){const[m,d]=a(x),[f,N]=a(()=>e(p)),[b,v]=a({}),[S,D]=a(!1),[k,C]=a(!1),[j,J]=a([]),[B,U]=a(f),[A,I]=a("USD"),[L,O]=a("CNY");r(n(()=>{J([...m]),U({...f}),C(!0)},[m,f])),s(()=>{const e=[...new Set(m.map(([e])=>e))];let t=!0;return async function(){D(!0);const r={};for(const t of e){const e=h(t);if(e)r[t]=e;else try{const e=await fetch(`https://open.er-api.com/v6/latest/${t}`),a=await e.json();a.rates&&(r[t]=a.rates,g(t,a.rates))}catch{}}t&&(v(r),D(!1))}(),()=>{t=!1}},[m]);/* @__PURE__ */
1
+ import{loadAppearance as e,WidgetSettingsModal as t}from"./chunk-2UIKLYAI.js";import{useWidgetSettings as r}from"./chunk-FWZUTHP5.js";import"./chunk-DSSLOQDW.js";import"./chunk-6KO2U66R.js";import"./chunk-CRI4UFBU.js";import"./chunk-5A7MWTXX.js";import"./chunk-EXXHI5DO.js";import"./chunk-PGVUO7GB.js";import"./chunk-HZZNJHRH.js";import"./chunk-D65T4H6J.js";import"./chunk-ECFMRDUP.js";import"./chunk-AFYQTVZO.js";import"./chunk-X4FJ54PP.js";import"./chunk-NCQLGQYR.js";import"./chunk-YKZHOXI4.js";import{useState as a,useCallback as n,useEffect as s}from"react";import{jsxs as c,Fragment as o,jsx as i}from"react/jsx-runtime";var l=["USD","CNY","AUD","GBP","EUR","JPY","CAD","THB","NZD","SGD","HKD","CHF","KRW","INR","MXN","BRL"],m=[["USD","CNY"],["USD","AUD"],["GBP","USD"],["USD","JPY"]],u="currency_pairs",p="currency_appearance",d="currency_rates_cache";function h(e){try{const t=JSON.parse(localStorage.getItem(d)||"{}")[e];if(t&&Date.now()-t.timestamp<36e5)return t.rates}catch{}return null}function g(e,t){try{const r=JSON.parse(localStorage.getItem(d)||"{}");r[e]={rates:t,timestamp:Date.now()},localStorage.setItem(d,JSON.stringify(r))}catch{}}function x(){try{const e=JSON.parse(localStorage.getItem(u)||"");if(Array.isArray(e)&&e.length)return e.slice(0,4)}catch{}return m}var y={USD:"🇺🇸",CNY:"🇨🇳",AUD:"🇦🇺",GBP:"🇬🇧",JPY:"🇯🇵",CAD:"🇨🇦",EUR:"🇪🇺",THB:"🇹🇭",NZD:"🇳🇿",SGD:"🇸🇬",HKD:"🇭🇰",CHF:"🇨🇭",KRW:"🇰🇷",INR:"🇮🇳",MXN:"🇲🇽",BRL:"🇧🇷"};function f(){const[m,d]=a(x),[f,N]=a(()=>e(p)),[b,v]=a({}),[S,D]=a(!1),[k,C]=a(!1),[j,U]=a([]),[I,O]=a(f),[H,J]=a("USD"),[R,A]=a("CNY");r(n(()=>{U([...m]),O({...f}),C(!0)},[m,f])),s(()=>{const e=[...new Set(m.map(([e])=>e))];let t=!0;return async function(){D(!0);const r={};for(const t of e){const e=h(t);if(e)r[t]=e;else try{const e=await fetch(`https://open.er-api.com/v6/latest/${t}`),a=await e.json();a.rates&&(r[t]=a.rates,g(t,a.rates))}catch{}}t&&(v(r),D(!1))}(),()=>{t=!1}},[m]);/* @__PURE__ */
2
2
  return c(o,{children:[
3
3
  /* @__PURE__ */i("div",{style:{backgroundColor:`rgb(var(--taskbar-bg-rgb, 243 244 246) / ${f.activeOpacity/100})`,backdropFilter:f.activeBlur>0?`blur(${f.activeBlur}px)`:void 0},children:/* @__PURE__ */c("div",{className:"px-4 py-3 space-y-1",children:[S&&/* @__PURE__ */i("div",{className:"text-xs text-gray-400 text-center py-4",children:"Loading rates..."}),m.map(([e,t],r)=>{const a=b[e]?.[t];/* @__PURE__ */
4
4
  return c("button",{onClick:()=>{const e=m.map((e,t)=>t===r?[e[1],e[0]]:e);d(e),localStorage.setItem(u,JSON.stringify(e))},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",children:[
@@ -9,13 +9,13 @@ return c("button",{onClick:()=>{const e=m.map((e,t)=>t===r?[e[1],e[0]]:e);d(e),l
9
9
  /* @__PURE__ */i("span",{className:"text-base",children:y[t]||""}),
10
10
  /* @__PURE__ */i("span",{className:"text-sm font-semibold text-gray-700",children:t})]}),
11
11
  /* @__PURE__ */i("div",{className:"text-base font-mono font-semibold text-gray-900 tabular-nums",children:null!=a?a.toLocaleString(void 0,{minimumFractionDigits:2,maximumFractionDigits:4}):"—"})]},`${e}-${t}-${r}`)})]})}),
12
- /* @__PURE__ */i(t,{open:k,onClose:()=>C(!1),title:"Currency Settings",appearance:B,onAppearanceChange:U,onSave:()=>{if(0===j.length)return;const e=j.slice(0,4);d(e),N(B),localStorage.setItem(u,JSON.stringify(e)),localStorage.setItem(p,JSON.stringify(B)),C(!1)},children:/* @__PURE__ */c("div",{children:[
12
+ /* @__PURE__ */i(t,{open:k,onClose:()=>C(!1),title:"Currency Settings",appearance:I,onAppearanceChange:O,onSave:()=>{if(0===j.length)return;const e=j.slice(0,4);d(e),N(I),localStorage.setItem(u,JSON.stringify(e)),localStorage.setItem(p,JSON.stringify(I)),C(!1)},children:/* @__PURE__ */c("div",{children:[
13
13
  /* @__PURE__ */c("h3",{className:"text-sm font-semibold text-gray-700 mb-2",children:["Currency Pairs ",
14
14
  /* @__PURE__ */c("span",{className:"text-[11px] font-normal text-gray-400",children:["(",j.length,"/",4,")"]})]}),
15
15
  /* @__PURE__ */i("div",{className:"space-y-1 mb-2",children:j.map(([e,t],r)=>/* @__PURE__ */c("div",{className:"flex items-center justify-between py-1 px-2 bg-gray-50 rounded",children:[
16
16
  /* @__PURE__ */c("span",{className:"text-sm",children:[y[e]||""," ",e," → ",y[t]||""," ",t]}),
17
- /* @__PURE__ */i("button",{onClick:()=>J(e=>e.filter((e,t)=>t!==r)),className:"text-red-400 hover:text-red-600",children:"×"})]},r))}),j.length<4?/* @__PURE__ */c("div",{className:"flex items-center gap-2",children:[
18
- /* @__PURE__ */i("select",{value:A,onChange:e=>I(e.target.value),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",children:l.map(e=>/* @__PURE__ */i("option",{children:e},e))}),
17
+ /* @__PURE__ */i("button",{onClick:()=>U(e=>e.filter((e,t)=>t!==r)),className:"text-red-400 hover:text-red-600",children:"×"})]},r))}),j.length<4?/* @__PURE__ */c("div",{className:"flex items-center gap-2",children:[
18
+ /* @__PURE__ */i("select",{value:H,onChange:e=>J(e.target.value),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",children:l.map(e=>/* @__PURE__ */i("option",{children:e},e))}),
19
19
  /* @__PURE__ */i("span",{className:"text-gray-400",children:"→"}),
20
- /* @__PURE__ */i("select",{value:L,onChange:e=>O(e.target.value),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",children:l.map(e=>/* @__PURE__ */i("option",{children:e},e))}),
21
- /* @__PURE__ */i("button",{onClick:()=>{A!==L&&j.length<4&&J(e=>[...e,[A,L]])},className:"text-sm font-medium text-blue-600 hover:text-blue-800 px-2",children:"+ Add"})]}):/* @__PURE__ */c("p",{className:"text-[11px] text-gray-400 italic",children:["Max ",4," pairs — remove one to add another."]})]})})]})}export{f as default};
20
+ /* @__PURE__ */i("select",{value:R,onChange:e=>A(e.target.value),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",children:l.map(e=>/* @__PURE__ */i("option",{children:e},e))}),
21
+ /* @__PURE__ */i("button",{onClick:()=>{H!==R&&j.length<4&&U(e=>[...e,[H,R]])},className:"text-sm font-medium text-blue-600 hover:text-blue-800 px-2",children:"+ Add"})]}):/* @__PURE__ */c("p",{className:"text-[11px] text-gray-400 italic",children:["Max ",4," pairs — remove one to add another."]})]})})]})}export{f as default};
@@ -1,11 +1,11 @@
1
- import{escapeHtml as e}from"./chunk-BR22X7E5.js";import{AboutApp as t}from"./chunk-6MBERZOS.js";import{toast_default as n}from"./chunk-KSSAVLO7.js";import"./chunk-7U3F53IG.js";import{WindowTitle as r}from"./chunk-LW27IM3S.js";import"./chunk-A7Q4BCPI.js";import"./chunk-DSSLOQDW.js";import"./chunk-5A7MWTXX.js";import"./chunk-JYLI2WXW.js";import"./chunk-6KO2U66R.js";import"./chunk-M4DB7UBZ.js";import{PopupMenu as o,PopupMenuLabel as l,PopupMenuItem as a,PopupMenuDivider as i}from"./chunk-N3ZXQE4M.js";import"./chunk-AFYQTVZO.js";import"./chunk-HZZNJHRH.js";import"./chunk-X4FJ54PP.js";import"./chunk-NCQLGQYR.js";import"./chunk-D65T4H6J.js";import{useState as s,useRef as c}from"react";import{jsxs as d,jsx as h}from"react/jsx-runtime";var m=/* @__PURE__ */new Set(["txt","md","markdown","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"]),u=/* @__PURE__ */new Set(["docx"]),p={filename:"Untitled",kind:"docx",content:"",ext:"docx"};function g(){const[g,x]=s(p),[f,y]=s(!1),[v,b]=s(!1),[k,w]=s(!1),[N,C]=s(null),j=c(null),D=c(null),L=c(null),M=(e,t)=>{L.current?.focus(),document.execCommand(e,!1,t),w(!0)},U=e=>{for(const t of e){if(!t.type.startsWith("image/"))continue;const e=new FileReader;e.onload=()=>{L.current?.focus(),document.execCommand("insertImage",!1,String(e.result)),w(!0)},e.readAsDataURL(t)}},R=e=>{N&&(N.el.removeAttribute("width"),N.el.removeAttribute("height"),N.el.style.width=e??"",N.el.style.height=e?"auto":"",w(!0),C(null))},B=async t=>{const r=(t.name.split(".").pop()||"").toLowerCase();y(!0);try{if(m.has(r)||!u.has(r)&&t.type.startsWith("text/")){const n=await t.text(),o=e(n).replace(/\n/g,"<br>");x({filename:t.name,kind:"text",content:o,ext:r}),w(!1)}else if(u.has(r))try{const e=await(import(
1
+ import{escapeHtml as e}from"./chunk-BR22X7E5.js";import{AboutApp as t}from"./chunk-36QX6LOQ.js";import{WindowTitle as n}from"./chunk-FWZUTHP5.js";import"./chunk-DSSLOQDW.js";import"./chunk-6KO2U66R.js";import"./chunk-67ZUPDWG.js";import{toast_default as r}from"./chunk-KSSAVLO7.js";import"./chunk-CRI4UFBU.js";import"./chunk-5A7MWTXX.js";import"./chunk-EXXHI5DO.js";import{PopupMenu as o,PopupMenuLabel as l,PopupMenuItem as a,PopupMenuDivider as i}from"./chunk-PGVUO7GB.js";import"./chunk-HZZNJHRH.js";import"./chunk-D65T4H6J.js";import"./chunk-ECFMRDUP.js";import"./chunk-AFYQTVZO.js";import"./chunk-X4FJ54PP.js";import"./chunk-NCQLGQYR.js";import"./chunk-YKZHOXI4.js";import{useState as s,useRef as c}from"react";import{jsxs as d,jsx as h}from"react/jsx-runtime";var m=/* @__PURE__ */new Set(["txt","md","markdown","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"]),u=/* @__PURE__ */new Set(["docx"]),p={filename:"Untitled",kind:"docx",content:"",ext:"docx"};function g(){const[g,x]=s(p),[f,y]=s(!1),[v,b]=s(!1),[k,w]=s(!1),[N,C]=s(null),j=c(null),D=c(null),L=c(null),M=(e,t)=>{L.current?.focus(),document.execCommand(e,!1,t),w(!0)},U=e=>{for(const t of e){if(!t.type.startsWith("image/"))continue;const e=new FileReader;e.onload=()=>{L.current?.focus(),document.execCommand("insertImage",!1,String(e.result)),w(!0)},e.readAsDataURL(t)}},R=e=>{N&&(N.el.removeAttribute("width"),N.el.removeAttribute("height"),N.el.style.width=e??"",N.el.style.height=e?"auto":"",w(!0),C(null))},O=async t=>{const n=(t.name.split(".").pop()||"").toLowerCase();y(!0);try{if(m.has(n)||!u.has(n)&&t.type.startsWith("text/")){const r=await t.text(),o=e(r).replace(/\n/g,"<br>");x({filename:t.name,kind:"text",content:o,ext:n}),w(!1)}else if(u.has(n))try{const e=await(import(
2
2
  /* @vite-ignore */
3
- "mammoth")),n=await t.arrayBuffer(),o=await e.convertToHtml({arrayBuffer:n});x({filename:t.name,kind:"docx",content:o.value||"<p><em>(empty document)</em></p>",ext:r}),w(!1)}catch(e){n.error('Install the optional "mammoth" peer dep to read .docx files.')}else"doc"===r?n.error(".doc is the legacy Word binary format — convert to .docx first."):n.error(`Unsupported file type: .${r||"unknown"}`)}finally{y(!1)}},W=g?.filename?(A=g.filename).length>24?`${A.slice(0,23)}…`:A:"Untitled";var A;/* @__PURE__ */
4
- return d("div",{className:"relative flex flex-col h-full",onDragOver:e=>{e.preventDefault(),v||b(!0)},onDragLeave:e=>{e.currentTarget===e.target&&b(!1)},onDrop:e=>{e.preventDefault(),b(!1);const t=Array.from(e.dataTransfer.files??[]);0!==t.length&&(t.every(e=>e.type.startsWith("image/"))?U(t):B(t[0]))},children:[
5
- /* @__PURE__ */h(r,{title:`${W}${k?" •":""} - Documents`}),
3
+ "mammoth")),r=await t.arrayBuffer(),o=await e.convertToHtml({arrayBuffer:r});x({filename:t.name,kind:"docx",content:o.value||"<p><em>(empty document)</em></p>",ext:n}),w(!1)}catch(e){r.error('Install the optional "mammoth" peer dep to read .docx files.')}else"doc"===n?r.error(".doc is the legacy Word binary format — convert to .docx first."):r.error(`Unsupported file type: .${n||"unknown"}`)}finally{y(!1)}},B=g?.filename?(W=g.filename).length>24?`${W.slice(0,23)}…`:W:"Untitled";var W;/* @__PURE__ */
4
+ return d("div",{className:"relative flex flex-col h-full",onDragOver:e=>{e.preventDefault(),v||b(!0)},onDragLeave:e=>{e.currentTarget===e.target&&b(!1)},onDrop:e=>{e.preventDefault(),b(!1);const t=Array.from(e.dataTransfer.files??[]);0!==t.length&&(t.every(e=>e.type.startsWith("image/"))?U(t):O(t[0]))},children:[
5
+ /* @__PURE__ */h(n,{title:`${B}${k?" •":""} - Documents`}),
6
6
  /* @__PURE__ */h(t,{app:"documents"}),
7
7
  /* @__PURE__ */d("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",children:[
8
- /* @__PURE__ */h("input",{ref:j,type:"file",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/*",onChange:e=>{const t=e.target.files?.[0];t&&B(t),j.current&&(j.current.value="")},className:"hidden"}),
8
+ /* @__PURE__ */h("input",{ref:j,type:"file",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/*",onChange:e=>{const t=e.target.files?.[0];t&&O(t),j.current&&(j.current.value="")},className:"hidden"}),
9
9
  /* @__PURE__ */d("button",{onClick:()=>j.current?.click(),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",children:[
10
10
  /* @__PURE__ */h("svg",{className:"h-3.5 w-3.5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.5,children:/* @__PURE__ */h("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"})}),"Open"]}),
11
11
  /* @__PURE__ */h("button",{onClick:()=>{if(!g)return;const t=L.current?.innerHTML??"";if("text"===g.kind){if(/<(b|strong|i|em|u|font|span style|ul|ol|img)|style="[^"]*text-align/i.test(t)){const n=new Blob([`<!doctype html><meta charset="utf-8"><title>${e(g.filename)}</title><body style="font-family:ui-monospace,monospace;white-space:pre-wrap">${t}`],{type:"text/html"}),r=URL.createObjectURL(n),o=document.createElement("a");o.href=r,o.download=`${g.filename.replace(/\.[^.]+$/,"")}.html`,o.click(),URL.revokeObjectURL(r)}else{const e=L.current?.innerText??"",t=new Blob([e],{type:"text/plain"}),n=URL.createObjectURL(t),r=document.createElement("a");r.href=n,r.download=g.filename,r.click(),URL.revokeObjectURL(n)}}else{const n=new Blob([`<!doctype html><meta charset="utf-8"><title>${e(g.filename)}</title>${t}`],{type:"text/html"}),r=URL.createObjectURL(n),o=document.createElement("a");o.href=r,o.download=`${g.filename.replace(/\.docx$/i,"")}.html`,o.click(),URL.revokeObjectURL(r)}},className:"text-xs text-gray-700 hover:text-gray-900 px-2 py-1 rounded hover:bg-gray-200 transition-colors",children:"Save"}),