Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@openparachute/notes

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@openparachute/notes - npm Package Compare versions

Comparing version
0.3.16-rc.6
to
0.3.17-rc.2
+811
CHANGELOG.md
# Changelog
## [0.3.17-rc.2] - 2026-05-22 — DEPRECATION RELEASE
This is the deprecation release. notes-daemon is no longer the recommended way to ship Notes.
- **DEPRECATED**: see [DEPRECATED.md](./DEPRECATED.md) for migration to parachute-app + @openparachute/notes-ui
- **No functional changes**: this release ships the same dist/ as 0.3.17-rc.1, just with the deprecation banner + DEPRECATED.md
- **Hub redirect**: hub#316 adds `/notes/*` → `/app/notes/*` redirect for transparent migration
Migrate at your own pace. notes-daemon will continue to serve until Phase 3 retirement (~Q3 2026).
## [0.3.17-rc.1] - 2026-05-21
- **feat(notes): Phase 1 migration — monorepo restructure, dual-publish
`@openparachute/notes-ui` alongside this package.** The parachute-notes
repo is now a bun workspace with two publish targets:
- `@openparachute/notes-ui` (new at `0.1.0-rc.1`) — UI bundle only,
no daemon, no `.parachute/module.json`. Installed under
[parachute-app][app] as the canonical first app per the [notes
migration arc Section 16][s16].
- `@openparachute/notes` (this package, bumped to `0.3.17-rc.1`) —
unchanged daemon shape. Hub continues to install via
`parachute install notes`; `dist/` continues to land at the same
resolved path; `.parachute/module.json` continues to declare port
1942 + the `/notes` mount.
Restructure mechanics:
- All source moves from repo-root `src/`, `scripts/`, `public/`,
`index.html`, `vite.config.ts`, etc. into `packages/notes-ui/`.
No source code changes — only path changes.
- `.parachute/module.json` and the (now lean) CHANGELOG + README
move into `packages/notes-daemon/`. This package's publish payload
(`files: ["dist", ".parachute/module.json", "README.md", ...]`)
is unchanged in shape.
- `packages/notes-daemon` declares `@openparachute/notes-ui` as a
workspace devDependency. The build step (`scripts/build.mjs`)
copies notes-ui's `dist/` into this package's `dist/`. Both
packages ship byte-identical bundles.
- Root `package.json` becomes a workspace root (`workspaces:
["packages/*"]`); `bun run build` runs notes-ui's build then
this package's copy step.
Two new direct deps surface on notes-ui that were previously
unhoisted transitives: `@lezer/highlight` (used in
`CodeMirrorEditor.tsx`) and `@types/mdast` (used in remark-wikilinks
types). The flat-layout was hiding the latent missing-declaration;
bun's workspace isolated layout surfaced it. Declaring them
directly is the correct fix regardless of layout.
Phase 2 (deprecate the daemon form) and Phase 3 (retire the daemon
+ reclaim port 1942) happen in later PRs. This PR is additive.
[s16]: https://github.com/ParachuteComputer/parachute.computer/blob/main/design/2026-05-21-parachute-apps-design.md#16-notes-migration-to-app
[app]: https://github.com/ParachuteComputer/parachute-app
## [0.3.16-rc.6] - 2026-05-21
- **fix(notes): SW update reload + OAuth reconnect 401 clearing (#148).**
Two blocking bugs Aaron hit while smoke-testing rc.5. Both shipped
with regression + structural-contract tests.
- *SW update banner — clicking "Reload" did nothing.* The banner
relies on `vite-plugin-pwa`'s `useRegisterSW`, which arms its own
`controlling` listener inside `showSkipWaitingPrompt` to refresh
the page once the new SW takes over. In real PWAs (especially iOS
standalone, BFCache restores, and races where the listener gets
attached after the activation already fired) that event can be
silently missed and the click visibly does nothing. The banner
now wires its own `controllerchange` listener via
`reloadAfterServiceWorkerUpdate` in `src/lib/pwa.ts` **before**
sending `skipWaiting`, plus a 2.5s fallback `setTimeout` — whichever
signal lands first forces `window.location.reload()` exactly once.
Idempotent under double-clicks via a module-level "reload armed"
guard. Five unit tests pin the controllerchange path, the timeout
path, the both-fire-once contract, idempotency, and the
no-serviceWorker-container fallback; the UpdateBanner component
test pins that the click flow attaches the listener BEFORE asking
workbox to skipWaiting.
- *Vault 401 banner — reconnect completes but banner stays.* When
a vault was added standalone (e.g. `localhost:1940`) and the user
later reconnects via a hub-fronted issuer, the hub's token catalog
can resolve the vault to a different URL (`hub.example/vault/default`).
`addVault` then registers a NEW vault entry under a different id
via `vaultIdFromUrl`, switches `activeVaultId` to it, and clears
the halt for the new id — which was never halted in the first
place. The halt entry on the OLD vault id stayed in `localStorage`
forever, re-surfacing the banner on the next activeVault switch
or page reload. Fix: the reconnect button now threads the
currently-halted vault id through OAuth via
`PendingOAuthState.priorHaltedVaultId` (sessionStorage), and
`OAuthCallback` clears the halt for BOTH the new id AND the
originally-halted id on success. Three OAuthCallback tests pin
the same-URL baseline, the different-URL reconnect, and the
persistent-storage-survives-reload contract; one
VaultStatusBanner test pins that the reconnect button passes the
active vault id to `beginOAuth`; two `beginOAuth` tests pin the
sessionStorage round-trip on both code paths.
## [0.3.16-rc.5] - 2026-05-21
- **fix(notes): header responsive under text-size scaling (#136).**
Surfaced during Aaron's testing of the global-zoom text-size landed in
0.3.15-rc.10/rc.11. At `larger`/`largest` the html root scales to
18–22px and every rem-based Tailwind size (gaps, padding, `text-sm`)
grows in lockstep — the 11-control inline cluster at `md:flex` (768px)
overflowed `max-w-5xl` and clipped controls. Two changes:
- *Cluster breakpoint moved from `md` (768px) to `lg` (1024px)*, so
tablet and narrow-desktop widths use the existing hamburger menu
(which lays out vertically and never clips). The cluster also gains
`flex-wrap` + `gap-y-2` so at lg+ a still-overflowing row wraps to a
second line rather than truncating.
- *Vault popover trigger gains a rem-based width cap* (`max-w-[12rem]`
+ `truncate`). Long vault names now compress with ellipsis instead
of pushing chrome buttons off-screen. The cap is in rem so it
scales proportionally with text-size — a "12rem" label at `largest`
is still ~12rem visually, not a fixed-px shrinking target.
Mobile menu also gains `flex-wrap` on its chrome-buttons row so the
Install/TextSize/Theme triplet wraps cleanly on narrow phones at
largest text-size. Three new Header regression tests pin the `lg:`
breakpoint, the `flex-wrap` class, and the rem-based label cap.
## [0.3.16-rc.4] - 2026-05-21
- **fix(notes): capture race + draft-saved indicator staleness (#135).**
Two small follow-ups from the #134 review on the rc.10 draft-save
redesign:
- *Race window in `draftSave`*: the ref was set to `{ localId,
hasEnqueuedCreate: false }` BEFORE awaiting the create-note
enqueue and flipped to `true` after. During that sub-millisecond
window, a manual Capture click (or unmount-flush) read
`hasEnqueuedCreate === false`, fell into the fresh-create branch,
and enqueued a SECOND `create-note` row with the same localId.
Fix: flip the committed flag SYNCHRONOUSLY before the await —
renamed to `createCommitted` for clarity. IndexedDB's
autoincrement `seq` orders the create's `db.add()` before any
racing update by call order, so FIFO drain processes
create-then-update correctly regardless of which await resolves
first. If the create enqueue itself throws, the catch block now
resets the ref back to null so the next attempt creates fresh
(update-note failures leave the ref alone — the create already
shipped). Three new regression tests cover (a) manual Capture
racing the autosave, (b) unmount racing the autosave, (c)
create-failure roll-back so the next autosave creates fresh.
- *Draft-saved indicator staleness*: the "Draft saved · just now"
label was computed at render time from `draftSavedAt`, but nothing
else in the component changed while the user idled — so the label
could stay at "just now" for the full 5s autosave window (and
longer if the user idled after a finalized draft) even though
wall-clock had moved on. Fix: a 15s `setInterval` bumps a tick
state while `draftSavedAt !== null` so `relativeTime()` keeps
tracking. One new test confirms the label transitions from "just
now" to "1m ago" after 70s without user interaction.
## [0.3.16-rc.3] - 2026-05-21
- **test(notes): component-level insecure-context tests for VaultPopover
+ VaultStatusBanner (#143 follow-up).** The rc.2 refactor pointed both
components at the relocated `InsecureContextBanner` but the only
insecure-context coverage lived in `AddVault.test.tsx`. Extends each
consumer's test file with focused tests pinned at the right
boundary: spy on `beginOAuth` and reject with `InsecureContextError`
to verify the dedicated banner renders, plus a negative test that a
generic `Error` falls through to the regular error UI (and not the
insecure-context banner). Catches future refactors that would
silently break the wiring.
## 0.3.16-rc.2 (2026-05-21)
- **refactor(notes): move `InsecureContextBanner` to `src/components/`.**
The banner was originally defined and exported from
`src/app/routes/AddVault.tsx` (where it was first used) and imported
from there by `VaultPopover.tsx` and `VaultStatusBanner.tsx`. That's
a components-importing-from-routes dependency inversion — routes
should be leaves. Relocated to
`src/components/InsecureContextBanner.tsx` with no behavior change;
three import sites updated. Closes #143.
## 0.3.16-rc.1 (2026-05-20)
- **fix(notes): clear error message when OAuth attempted from insecure
context.** Aaron hit `Cannot read properties of undefined (reading
'digest')` on fresh-install testing when connecting Notes (served
from a non-loopback HTTP origin) to a vault. Root cause: Web Crypto
(`crypto.subtle`) is only exposed in W3C secure contexts — HTTPS,
`http://localhost`, or `http://127.0.0.1` — and Aaron's hub URL was
`http://192.168.1.10:1939`. There is no polyfill: the gating is
deliberate, and PKCE genuinely can't run there.
- `src/lib/vault/pkce.ts`: introduce `InsecureContextError` and
assert `crypto.subtle?.digest` is present at the top of
`deriveCodeChallenge` (and `crypto.getRandomValues` in
`generateCodeVerifier` / `generateState`). Throws an
operator-facing message that names the cause and lists both
remediations (HTTPS via Tailscale Serve / Cloudflare Tunnel /
reverse proxy, or switch to the `http://localhost` form).
- `src/app/routes/AddVault.tsx`: catch `InsecureContextError`
distinctly in the connect handler and render a new
`InsecureContextBanner` — amber palette + structured list of
remediations, deliberately different from the red "Connection
failed" strip so the operator can tell at a glance this is a
browser-policy failure, not a "hub is down" failure. Banner
shows the exact `window.location.origin` so there's no doubt
which URL the browser flagged.
- `src/components/VaultPopover.tsx`,
`src/components/VaultStatusBanner.tsx`: same catch + banner in
the other two OAuth-initiating call sites so the messaging is
consistent wherever PKCE can fail.
Does **not** make PKCE work in insecure contexts (it can't); makes
the failure mode obvious and points the operator at the two fixes.
## 0.3.15 (2026-05-20)
Stable release. Cumulative changes since `0.3.14`:
- **Format-aware rendering Phase 2** (#139): native rendering for CSV (table), JSON (pretty-print), YAML (formatted), code (syntax-highlighted) note bodies. Auto-detected by content type.
- **Hierarchical capture** (#134, others): autosave draft model + text-size global zoom + capture-flow polish across multiple rc.10-rc.13 iterations.
- **Cross-tab sync** (#131, others): notes edited in one tab reflect in others within seconds.
- **Schema-audit UI** (#136): surface vault schema state from the notes UI.
- **Pending-approval render polish** (#140): dropped the CLI alternative from the OAuth pending-approval screen — the web-based approval path is now the only displayed path. Added "Retry now" button that navigates back to `/add` (works correctly with single-use OAuth codes).
See individual rc entries below for full detail.
## Unreleased
### OAuth pending-approval polish
- **polish(oauth): drop CLI alternative from pending-approval render +
add retry button (0.3.15-rc.14).** The web-approval path is the path
now; the `parachute auth approve-client <id>` fallback alongside the
"Open approval page" button made operators think they still needed
terminal access, contradicting the hub#266 wizard goal of
"everything from a browser."
- `OAuthCallback.tsx`: drop the `<code>parachute auth …</code>`
block from the pending-approval screen; drop `cliAlternative` from
the `Status` discriminated union and the `setStatus` call in the
catch branch.
- `OAuthCallback.tsx`: add a "Retry now" button alongside "Open
approval page" so operators can re-attempt OAuth completion after
approving in the new tab without restarting the connect flow.
Implementation uses `window.location.reload()` — re-runs the
`OAuthCallback` effect with the same code/state params.
- `oauth.ts`: drop `cliAlternative` from `PendingApprovalError`
(field, constructor, doc-comment) and from `parsePendingApproval`.
Without an `approve_url`, we now fall through to the generic
token-exchange-failed error rather than rendering an empty
"Waiting for hub approval" screen with nothing to click.
- Hub still emits `cli_alternative` in its `invalid_client` JSON;
Notes simply ignores it. Pre-#240 hubs that only emit
`cli_alternative` (no `approve_url`) get the generic error UI.
### Phase 2 polish
- **chore(render): fold reviewer polish nits (0.3.15-rc.13).**
`escapeHtml` in `src/lib/render/highlight.ts` now escapes `"` (→
`&quot;`) and `'` (→ `&#x27;`) in addition to `&` / `<` / `>` — current
callers only use content context, but the generic name invites future
attribute-context use, so close the hole up front. Added two test
cases in `format.test.ts` pinning `formatForPath` hidden-file behavior
(`.gitignore` → `"plain"`, `.ts` → `"code"`) — falls out of the
extension-driven model, but worth pinning since it was unspecified.
### Phase 2 format-aware rendering
- **feat(render): NoteRenderer dispatches CSV / JSON / YAML / code to
format-specific renderers (0.3.15-rc.12).** Closes #138. Phase 1
(parachute-vault) added file-extension support so non-markdown notes can
be stored; Phase 2 (this) renders them appropriately on the read path.
A new `NoteRenderer` dispatcher in `src/components/NoteRenderer.tsx`
examines the note's path extension and routes to one of six renderers:
- `MarkdownView` (unchanged) — `.md`, `.mdx`, `.markdown`, no extension
- `CsvRenderer` — `.csv` rendered as an HTML table (first row =
headers); inline RFC-4180 parser handles quoted cells, escaped
quotes, newlines-in-cells, CRLF, missing trailing newline
- `JsonRenderer` — `.json` pretty-printed + syntax-highlighted; invalid
JSON falls back to the plain monospace block
- `YamlRenderer` — `.yaml` / `.yml` syntax-highlighted (no re-emit;
bytes render as authored)
- `CodeRenderer` — `.ts` / `.tsx` / `.js` / `.jsx` / `.py` / `.rs` /
`.go` / `.sh` syntax-highlighted via `highlight.js/lib/core` with
explicit per-language registration (avoids the `/common` bundle's
~35 KB of unused languages)
- `PlainRenderer` — fallback for unknown extensions and parse failures
All three existing call sites (`NoteView`, `NoteEditor` preview,
`NoteNew` preview) now go through `NoteRenderer`. The editor preview
reads `draft.path` so renaming a draft to `.csv` switches the preview
live.
No new dependencies — `highlight.js` was already a dep (used by
rehype-highlight for fenced code in markdown notes); the new renderers
reuse it directly. The hljs github theme already imported in
`styles/index.css` styles both code paths uniformly.
Bundle: `NoteRenderer` chunk 340.80 kB / 103.55 kB gzip (was
`MarkdownView` 337.29 kB / 102.30 kB gzip) — delta **+3.51 kB raw /
+1.25 kB gzip**. Total PWA precache 1578.53 KiB (was 1574.85 KiB).
Deferred (out of scope for #138): MDX with custom React components in
the markdown body, image-format thumbnails in non-markdown notes, and
CodeMirror language-aware editing (the editor still uses markdown
grammar for every note — Phase 3).
### Text-size ramp retune
- **tune(ui): widen text-size ramp + bump default (0.3.15-rc.11).**
Aaron's testing of rc.10 surfaced two complaints: default felt small
for a reading-first app (16px root × 1rem prose = 16px reader), and
largest was a modest ceiling. Retune to a wider ramp Aaron picked
from a three-option comparison. Rendered px per step:
| step | root | `.prose-note` | CodeMirror editor |
|-----------|-------|---------------|-------------------|
| default | 16px | 18px | 15px |
| larger | 18px | 22px | 18px |
| largest | 22px | 26px | 22px |
Default `--font-size-prose` bumped from `1rem` → `18px` (absolute, so
the rendered target is unambiguous). Defaults for editor 14 → 15.
Larger / largest blocks retuned to hit the px targets via absolute
values on prose + editor (no rem×root math to verify). rc.10's CSS
architecture (root font-size scales chrome via rem cascade, prose +
editor scale independently) is unchanged — only the rendered ramp
moves.
No test changes — `TextSizeControl.test.tsx` asserts attribute
manipulation, not px values, so it passes unchanged. Intentional:
pinning px would lock the implementation to numbers Aaron will
likely keep iterating.
### Capture draft-save + global text-size zoom
- **fix(capture): autosave is now a background draft, not a finalize-and-
clear (0.3.15-rc.10).** P0 bug from Aaron's morning report: typing
"hello world" in Capture and waiting 5s wiped the textarea. Root
cause: `save()`'s success path called `reset()` (clears content +
path) AND never set `phase: "idle"` back, so `canSubmit` stayed
false and the textarea (`disabled={phase === "saving"}`) stayed
locked.
- The redesign: a new `draftSave()` writes a partial as a background
draft. First fire enqueues `create-note` with a fresh localId;
subsequent fires on the same mount enqueue `update-note` for the
same localId (no duplicate notes). Never touches `phase`, never
clears `content`. A `draftRef.current` carries
`{ localId, hasEnqueuedCreate }` across the mount.
- The manual Capture click (and ⌘↵) is the finalize action — if a
draft is in flight, it enqueues `update-note` (the create already
shipped) and clears `draftRef` via `reset()`. Phase explicitly
resets to `idle` after success so the textarea unlocks for the
next capture on the same mount.
- Unmount-flush mirrors the same shape: enqueues `update-note` if
a draft is in flight (otherwise `create-note`). Nav-away no longer
duplicates the draft.
- Subtle "Draft saved · <relative time>" indicator below the
textarea (right-aligned, `text-fg-dim` micro size). Only renders
after the first successful draft save.
- Audio captures still finalize-and-clear via the manual Capture
click — autosave stays suppressed when `phase === "have-audio"`.
- **fix(ui): text-size knob now scales the whole app, not just `.prose-
note` + CodeMirror (0.3.15-rc.10).** Aaron reported the Larger /
Largest radios "appeared to do nothing" on Settings. rc.6's scope
was too narrow: only `.prose-note` and CodeMirror consumed the
`--font-size-*` variables, so headers, lists, capture, Settings,
bottom-tab — none scaled. Added `font-size` on the html root inside
the `:root[data-text-size="larger"]` (17.5px) and `"largest"` (19px)
blocks. Tailwind sizes are rem-based, so every chrome element scales
proportionally. The prose / editor variables stay so the reader
remains slightly larger than the chrome (read-content > navigation
feels right).
- **Tests.** 4 existing autosave tests rewritten for draft-save
semantics — assert queue rows directly instead of "Captured." toast,
assert content is preserved across autosaves (the bug), assert
update-note enqueues on the second draft fire and on unmount-flush
after a draft. Test names renamed to reflect the new model.
### Schema-ensure audit UI — Settings panel + connect-time banner
- **feat(schema): audit UI for the required Notes schema (0.3.15-rc.9).**
Closes notes#129. Builds directly on rc.8's `NOTES_REQUIRED_SCHEMA` +
`ensureNotesSchema`. Until now schema-ensure was first-capture-driven
(idempotent, silent). This PR adds the operator-facing audit: a
Settings panel that shows expected-vs-actual for each declared tag, a
connect-time banner that surfaces when the active vault is missing or
has misaligned tags, and a one-click "Set up missing tags" action.
- **`auditSchema(client)`** (`src/lib/vault/schema-audit.ts`) calls
`GET /api/tags?include_schema=true` and diffs each declared tag
against the vault row. Returns `{ ok, missing, misaligned, rows }`
with per-tag `differences: ("description" | "parent_names")[]`.
Treats null and empty-array `parent_names` as equivalent.
- **`VaultClient.listTagsWithSchema()`** wraps the schema-detail
variant of `GET /api/tags`. Narrow return type — only the fields
audit reads.
- **`fixSchema(vaultId, client)`** in `schema-ensure.ts` is the
user-driven entry point. Bypasses the per-session ensure guard
(user explicitly asked to write), rethrows on failure so UI can
show "fix failed" toast / banner error, and marks the vault as
ensured on success so subsequent first-captures don't redo work.
- **`useSchemaAuditStore`** (volatile, not persisted) holds per-vault
audit results with `ensure(vaultId, client)` (cache-respecting,
5min TTL) + `refresh()` (force-refetch) + `set()` (post-fix update
without refetch). Mirrors `auth-halt-store` shape.
- **`useSchemaBannerStore`** (persisted) tracks per-vault banner
dismissal under `notes:schema-banner-dismissed:<vaultId>` so
dismissal survives reloads. Mirrors `auth-halt-store` cross-tab
pattern.
- **`SchemaAuditRunnerMount`** at the App root auto-fires `ensure`
when the active vault or its client changes. No DOM, only effect.
- **`SchemaAuditBanner`** (`src/components/`) renders below
`VaultStatusBanner` — amber/yellow, less urgent than auth-halt or
unreachable. Two affordances: "Set up" → calls `fixSchema` then
marks the cached audit ok; "Dismiss" → persists per-vault. Uses
`<output role="status" aria-live="polite">` rather than `<div
role="status">` per Biome's a11y rule.
- **Settings "Vault schema" section** (top of the Settings page —
above Text size). Status pill (ok = emerald, !ok = amber), per-tag
rows showing expected description + parent_names, a "Refresh" link
and a "Set up missing tags" button. "Schema updated." toast on
success.
- **Tests.** 7 new in `schema-audit.test.ts` (ok / missing / desc
misalignment / parent_names misalignment / null-vs-empty
equivalence / row completeness / extra-tags-don't-flag). 3 new in
`schema-ensure.test.ts` (fixSchema bypasses session guard /
rethrows on failure / marks ensured after success). 4 new in
`schema-banner-store.test.ts` (dismiss + clear + multi-vault +
cross-tab reload). 6 new in `SchemaAuditBanner.test.tsx` (renders
nothing pre-audit / nothing on ok / renders on misalign / hides
when dismissed / Dismiss persists / Set up calls updateTag for
each + marks ok).
### Capture reshape — hierarchical capture/* tags + schema-ensure + option (d) + path-collision fix
- **feat(capture): hierarchical capture tags + schema-ensure + option (d) +
path-collision fix (0.3.15-rc.8).** Closes notes#126 (reshaped scope).
Builds on rc.7's `quickPath()` pre-fill with Aaron's confirmed `capture/*`
classification model + several reviewer follow-ups bundled.
- **`NOTES_REQUIRED_SCHEMA` in `src/lib/vault/schema.ts`** declares the
`capture` parent + `capture/text` + `capture/voice` children with
`parent_names: ["capture"]`. First instance of patterns#57 (surface-
declares-required-schema). Future extensions (`capture/photo`,
`capture/web-clip`) slot in without rename.
- **Tag Role defaults rename**: `DEFAULT_TAG_ROLES.captureText` →
`"capture/text"`, `DEFAULT_TAG_ROLES.captureVoice` → `"capture/voice"`.
**Existing vaults preserve their stored values** — if a user has
`captureText = "quick"` from rc.6, that stays. Only fresh-vault
inheritance changes.
- **`update-tag` client method + idempotent `ensureNotesSchema()` hook**
in `src/lib/vault/schema-ensure.ts`. PUTs each declared tag against
`/api/tags/:name` (field-merged vault-side; no-op when already-correct).
Per-vault per-session ref guard so repeated captures don't hammer the
vault. Failure rolls back the guard so the next capture retries.
Captures-side wiring is fire-and-forget — schema setup doesn't block
the user's save.
- **Option (d) bundled** (was the closed PR #131): clearing the path
input reverts to the mount-time generated value, never vault-picks.
Resolution becomes `pathOverride.trim() || generatedPathRef.current`.
The rc.6 `memoPath()` audio-only fallback is dropped — unreachable
under option (d). One canonical Notes-side rule, no phase-dependent
forks. Aaron's framing: don't re-introduce hidden vault-picks magic
via the cleared-input path.
- **Path-collision fix** (raised in #130 review): `quickPath()` is
second-granularity, so two captures within the same wall-clock second
would land at the same path. `reset()` after successful save now
regenerates `quickPath()` AND updates the input — but only when the
operator hasn't manually edited. A user typing an explicit path
(e.g. `Daily/2026-05-12`) is capturing into a deliberate location;
don't fight them. `pathEditedRef` tracks edit intent; restoring the
generated value clears the flag.
- **Placeholder text** updated: `"(blank → vault picks)"` →
`"(blank → uses generated path)"` so the UI itself describes the
option-(d) rule.
- **Tests.** 6 new in `schema-ensure.test.ts` (declaration-order PUTs,
parent-before-children, per-session per-vault idempotence, multi-vault
independence, retry-on-failure, swallow-failure-doesn't-throw). 2 new
in `Capture.test.tsx` (regen-on-reset when unedited; preserve user
edit across reset). 4 existing tests flipped where defaults changed
(captureText → `capture/text`, captureVoice → `capture/voice`,
text+voice combined now both hierarchical) or option (d) changed
semantics ("empty path reverts to generated", "audio-only cleared
path reverts to generated"). `Capture.test.tsx` adds a `vi.mock` for
`@/lib/vault/schema-ensure` so capture tests don't hit the real PUT
(covered by schema-ensure.test.ts).
### Not in scope (deferred)
- Full Settings audit UI + connect-time banner → notes#129.
- Per-vault customization of path templates → notes#128.
### Text-size shortcuts + header control; Capture path pre-fill
- **feat(ui): accessible text-size (shortcuts + header) + locally-generated
capture path (0.3.15-rc.7).** Two follow-ups to rc.6 bundled because
they touch the same chrome / Capture surfaces. Closes notes#127 + #126.
- **Text-size keyboard shortcuts (notes#127).** Cmd+= / Cmd+Plus steps
up the ramp (default → larger → largest → default); Cmd+- /
Cmd+Underscore steps down; Cmd+0 resets to default. Bound at the
app root via `TextSizeShortcutsMount` so the listener lives in one
place — the visible `TextSizeControl` in the Header would otherwise
register twice (desktop + mobile menu). Ignored when Shift, Alt, or
neither modifier is held.
- **Header chrome control (notes#127).** Adds `TextSizeControl` — a
small "Aa" button next to the existing chrome (Install / Theme).
Click opens a 3-option popover (Default / Larger / Largest) with a
✓ on the active row. Same persist + apply path as the Settings
dropdown via `lib/text-size.ts`. A same-tab `CustomEvent` keeps the
popover's active indicator in sync when a shortcut or sibling
control changes the size (the `storage` event only fires
cross-tab). Lives on both desktop and mobile menu so phones (no
keyboard) keep the path.
- **`nextTextSize` / `previousTextSize` helpers.** Added to
`lib/text-size.ts` for the shortcut handlers; mirror `nextTheme`
in `theme.ts` shape. Each direction is explicit so the call site
doesn't have to think about wrap-around arithmetic.
- **Capture path pre-fill (notes#126).** Adds `quickPath()` helper
next to `memoPath()` in `lib/capture/recorder.ts`. Same
`<root>/YYYY/MM-DD/HH-MM-SS` shape under `Notes/`. Capture's
`pathOverride` state is now seeded with `quickPath()` on mount so
the operator sees the generated path the moment they expand More
fields — no more invisible "vault auto-assigns" magic.
- **Audio-only memos.** With the pre-fill non-empty, audio captures
also land under `Notes/` by default (parallel to the text case).
Operators who want the old `Memos/` rule can clear the path input
— the existing rc.6 fallback to `memoPath()` for audio-only with
no override is preserved as the escape valve. New test pins this.
- **Tests.** 2 new in `text-size.test.ts` (cycle direction helpers).
12 new in `TextSizeControl.test.tsx` (button + popover behavior,
keyboard handlers, same-tab sync). 1 new in `recorder.test.ts`
(quickPath shape). 2 new in `Capture.test.tsx` (pre-fill is
editable + saved; audio-only fallback to `memoPath` when path is
cleared). Existing tests updated where pre-fill changed observable
behavior (text-only payload now carries `Notes/...`, combined
text+voice payload now carries `Notes/...` instead of vault-picks).
### Capture polish + view-level text-size
- **feat(ui): unified capture surface refinements + view-level text-size
control (0.3.15-rc.6).** Two items from `design/2026-05-12-notes-ui-audit.md`
§3 (north-star "Apple-Notes-grade ease"): #12 (unified capture) and
#11 (text-size knob). Both behind one PR per the audit's sequencing.
- **More fields panel (audit §3 #12).** Adds a collapsible
`<details>` to `Capture` exposing a path override + summary input —
the audit's "structured form when wanted, hidden when not". Defaults
to closed so the textarea stays the unfocused-friction default;
operators who need to set an explicit path (e.g. capturing into
`Daily/2026-05-12`) get the form without leaving Capture. Empty
path means "let the vault auto-assign"; empty summary means "no
metadata.summary". Path override wins over the audio-only memo
auto-path.
- **Inactivity autosave (audit §3 #12).** Capture now flushes
save() after 5 seconds of editing inactivity in addition to the
existing unmount-flush — protects against browser crashes and
accidental closes. Skipped while audio is staged (manual Capture
click only), while recording/saving, and while body is empty.
- **Escape hatch to NoteNew.** A "Need to attach a file? Open the
full editor" link in the More-fields panel points at `/new`, which
still renders `NoteNew` for the file-drop / file-picker /
`link-on-create` flow. Capture is canonical for the 95% quick path;
the heavy editor stays available for the 5% that needs attachments.
Cmd+K keeps both entries for discoverability.
- **View-level text-size knob (audit §3 #11).** New `lib/text-size.ts`
mirrors `lib/theme.ts` shape — three steps (Default / Larger /
Largest), per-device localStorage at `notes:textSize`, applied via
a `data-text-size` attribute on `<html>`. `styles/index.css`
defines `--font-size-prose` + `--font-size-editor` CSS variables;
`.prose-note` reads the prose one (markdown reader), `CodeMirror`
reads the editor one. Settings gains a `TextSizeSection` with
three radio buttons that apply + persist in one motion. Markdown
on disk is unaffected — pure view preference.
- **Tests.** 4 new in `text-size.test.ts` (round-trip, default
handling, data-attribute application, labels). 8 new in
`Capture.test.tsx` covering disclosure default-closed, path/summary
override payload shape, empty-path fallback, path-override winning
over memo auto-path, autosave-after-5s, edit-resets-timer,
empty-content-no-autosave, audio-staged-suppresses-autosave.
- **Unmount-flush hardening.** The unmount enqueue now swallows IDB
teardown rejections (SyncProvider closing its handle in the same
tick is a known race documented in `SyncProvider.tsx:60`). No
user-visible surface to report failures during nav-away anyway.
### Multi-vault hubs — consume per-vault services keys
- **feat(oauth): prefer `services["vault:<name>"].url` in OAuthCallback
(0.3.15-rc.5).** Companion consumer for the hub-side change in
hub#247/#248. Hub now emits per-vault entries in the OAuth services
catalog alongside the legacy collapsed `vault` key; OAuthCallback
picks the entry matching the token's `vault` claim. Before this PR,
every vault on a multi-vault hub (boulder, gitcoin, techne) would
resolve to the collapsed-first-vault URL, so VaultRecords collided
on URL and only one entry survived in Manage Vaults. Fallback chain
is per-vault key → collapsed `vault` → `pending.issuerUrl`, so
pre-#247 hubs and standalone vaults keep working unchanged. Tests
cover all three fallback rungs. Closes notes#121.
### Retry-now integration test
- **test(ui): integration coverage for Retry-now → real client → store flush
(0.3.15-rc.4).** Adds `VaultStatusBanner.retry.integration.test.tsx`
exercising the load-bearing recovery interaction end-to-end through a
real `VaultClient` (no `useActiveVaultClient` mock). Three response
paths covered: 200 (vault healthy) + 401 (vault answering, still
auth-broken) both flush the store and unmount the banner via the real
`onReachability("healthy")` callback; 502 keeps the banner up and
extends `backoffIndex`. Regression-pins the precedence flow so a
future refactor that disconnects the client→store wiring fails this
test instead of slipping through. Closes notes#118.
### LAN-IP vaults get the operator hint
- **fix(ui): RFC 1918 detection in `isLoopbackOrLocal` (0.3.15-rc.3).**
The banner from rc.2 only showed the `Try `parachute start vault``
operator hint for `localhost` / `127.0.0.1` / `.local` URLs, so a
self-hosted vault on a home LAN at e.g. `192.168.1.10:1940` got no
hint even though the recovery is identical. Adds RFC 1918 private
IPv4 range matching (10/8, 172.16-31/12, 192.168/16). Tailnet and
cloud vaults remain correctly unaffected. Tests cover all three
ranges, the 172.15/172.32 boundary excludes, and public-IP
negatives that share a prefix digit. Closes notes#117.
### Graceful vault-unreachable UX
- **feat(ui): banner + status dot + retry backoff when vault is unreachable
(0.3.15-rc.2).** Replaces the raw 502 / blank-screen + console-error
behaviour Aaron hit after a Mac restart left vault un-started (notes#113).
- **`VaultUnreachableError`** distinguishes 5xx and network-level failures
(ECONNREFUSED, DNS, fetch TypeError) from auth/conflict/not-found in
`VaultClient.request()`. Auth-halt and 4xx errors still mean the vault
*answered*, so they don't touch reachability state.
- **`useVaultReachabilityStore`** runs the per-vault state machine
`healthy → retrying → down`. Promotion to `down` after 3 consecutive
failures (or an immediate `ECONNREFUSED`). Exponential backoff for the
recovery probe: 1s → 2s → 4s → 8s → 16s → 30s (cap matches the sync
engine tick). Not persisted to localStorage — unlike auth-halt, this
state should re-probe from scratch on reload.
- **`useReachabilityProbe`** schedules a single `setTimeout` per active
vault, pings `GET /api/vault` at `nextProbeAt`, and on success the
client's own `onReachability("healthy")` flush clears the store. Probe
auto-invalidates `notes`/`tags`/`vaultInfo`/`note` query keys so cached
data refreshes on recovery.
- **`VaultStatusBanner`** (renamed from `ReconnectBanner`) covers both
failure axes with one component: auth-halt has precedence over
unreachable (different recovery paths — re-OAuth vs wait/retry). The
unreachable banner offers `Retry now` (forces a probe + invalidates
queries) and `Dismiss` (one-shot escape hatch via `resetToHealthy`).
Local-vault operator hint (`Try `parachute start vault``) is shown
only for loopback / `.local` URLs.
- **`SyncStatusIndicator`** gains a 5th tone `unreachable` ("Vault down",
`bg-red-400`). Precedence: `halted → unreachable → offline → syncing →
online`. Auth-halt still wins; unreachable beats `navigator.onLine`
because it points at a more specific recovery.
- **`QueryProvider` retry policy** pauses React Query retries on
`VaultUnreachableError` once the store crosses `down` — this is what
stops the `/api/notes` 404 hammering in the vault log (every list/get
call legitimately hits `/api/notes?...`; nothing was stopping React
Query from retrying twice per query forever). While still `retrying`
(≤2 failures) one retry is allowed so a single blip self-heals
without ever showing the banner.
- **Tests.** `client.test.ts` adds 502/503/TypeError/AbortError mappings
and the `healthy` reset on 4xx. `reachability-store.test.ts` covers
the full state machine + backoff index growth + per-vault isolation.
`VaultStatusBanner.test.tsx` covers both modes, the auth-halt-wins
precedence, the loopback hint, the Retry/Dismiss buttons, and
`isLoopbackOrLocal`. `SyncStatusIndicator.test.tsx` adds the
`Vault down` tone test (above offline in precedence).
### Vault popover (header)
- **feat(ui): vault popover + hub-discovery + OAuth `vault=<name>` hint
(0.3.15-rc.1).** Replaces the bare `<select>` switcher in the header
with a popover that surfaces the operator's full hub-side vault list
alongside the locally-connected vaults. Implements §2 of
[`design/2026-05-12-notes-ui-audit.md`](./design/2026-05-12-notes-ui-audit.md);
the first item in the §5 ship sequence.
- **Two sections.** "Connected" lists vaults Notes has tokens for
(active vault gets a filled accent dot + "current" tag; the rest
are one click to switch). "Available from your hub" lists vaults
published at `<hub>/.well-known/parachute.json` that Notes hasn't
connected to yet, each with an inline "Connect" button. Footer
links to the existing `/vaults` management page.
- **Hub-origin discovery.** Derived from `VaultRecord.issuer` (which
under hub-as-issuer is the hub origin itself, captured at OAuth
time in `OAuthCallback.tsx`) — no schema change to the stored
record, no migration. For a standalone-vault deployment the
well-known fetch returns no peers and the Available section is
omitted (graceful degradation).
- **OAuth `vault=<name>` hint (Path A).** `beginOAuth` now accepts an
`options.params` bag appended to the authorize URL last, guarded
so caller-supplied params can never overwrite standard OAuth/PKCE
params. Notes sends `vault=<name>` so future hubs that adopt the
hint can pre-select on the consent screen; pre-#240 hubs ignore it
and the picker renders as today.
- **Mobile.** Same component, rendered as `variant="inline"` inside
the existing hamburger menu — replaces the mobile `<select>` plus
the standalone "Manage vaults" button.
### Design
## 0.3.14 (2026-05-11)
### OAuth pending-approval UX
- **feat(oauth): consume hub's `approve_url` field from the
pending-approval response.** When `/oauth/token` answers with
`error: "invalid_client"` and the hub#240 hint fields
(`approve_url`, `cli_alternative`), `completeOAuth` now throws a
typed `PendingApprovalError` instead of folding the raw JSON into a
generic "Token exchange failed" string. The `OAuthCallback` route
renders a dedicated "Waiting for hub approval" screen with a
one-click "Open approval page" link (the hub's
`/admin/approve-client/<id>` SPA route) plus the
`parachute auth approve-client …` CLI as a secondary path.
Back-compat: pre-#240 hubs that emit only `cli_alternative` still
surface the friendly screen with the CLI fallback alone; an
`invalid_client` response with no hint fields (unknown client_id,
revoked client) falls through to the generic error UI rather than
getting swallowed into the approval flow. Defense-in-depth: only
`http(s)` `approve_url` schemes make it to the rendered `href` —
any other scheme (`javascript:`, malformed) is dropped at parse
time, with the CLI alternative still surfaced if present.
## 0.3.13 (2026-05-10)
### Module manifest
- **docs(module): declare `uiUrl: "/notes"` per
[`patterns/module-ui-declaration.md`](https://github.com/ParachuteComputer/parachute-patterns/blob/main/patterns/module-ui-declaration.md).**
Lets hub render the Notes discovery tile dynamically from the
well-known doc instead of from its hardcoded `SERVICE_LABELS` map.
No runtime change in Notes itself; the field is opaque to the PWA.
## 0.3.12 (2026-05-09)
### OAuth / DCR
- **feat(oauth): include credentials on DCR registration so hub session
cookie reaches /oauth/register (#106).** Adds `credentials: 'include'`
to the `POST /oauth/register` fetch in `src/lib/vault/discovery.ts` so
the browser sends the `parachute_hub_session` cookie when registering.
Companion to hub#199 (hub-side auto-approve) and agent#140 (sibling
fix on agent's SPA).
**Scope:** Same-origin auto-approve (notes loaded at `<hub>/notes/` →
DCR at `<hub>/oauth/register`) activates as soon as hub#199/200 lands.
Cross-origin auto-approve (e.g. notes on a cloudflare URL → hub on
tailnet) does NOT work yet — it requires hub-side CORS with
`Access-Control-Allow-Credentials`, a first-party origin allowlist, and
a `SameSite` relaxation or alternative credential, tracked at
parachute-hub#201. Until that lands, cross-origin DCR continues to
register as `pending` and requires manual `parachute auth approve-client`.
## 0.3.11 (2026-05-05)
First `@latest` publish since launch (`0.3.0`). Bundles every change merged
since launch into a single tagged release plus the discovery-protocol fix
needed for hub well-known to resolve notes correctly.
### Discovery / module protocol
- **fix(spa): serve `.parachute/info` as JSON before SPA catch-all (#102).**
Notes' Vite preview SPA fallback was matching `/.parachute/info` and
`/notes/.parachute/info` and returning the index.html shell, so hub's
well-known builder couldn't read notes' module identity. The
`infoEndpointPlugin` now registers Connect middleware at both the
basePath-prefixed path (`/notes/.parachute/info`) and the root
(`/.parachute/info`) — matching the canonical contract used by vault and
scribe (no `.json` extension). The middleware runs before sirv and the
SPA fallback. Build still emits `dist/.parachute/info` as a static asset
for static-deploy scenarios.
### Accessibility
- **fix(a11y): visible RouteFallback with announceable status (#98).** The
route-level lazy fallback now renders a visible spinner with `role="status"`
so screen readers announce route transitions.
- **fix(a11y): explicit `aria-live="polite"` on RouteFallback + smoke test
(#101).** Hardens the fallback's announcement contract and adds a
regression test.
### Feature work and cleanup since launch
- **chore: closeout — capture race + queue nit + route-level lazy (#96).**
- **feat: unified single-screen capture (#94).** Capture flow consolidated.
- **feat: saved-view management UI + cluster-A closeout (#93).**
- **sync: reconnect banner + cross-tab vault sync (#92).**
- **Cleanup bundle: pinned hint, group test, vault-switch reset, settings
drain, module.json (#90).**
- **fix: capture `if_updated_at` baseline for offline note edits (#88).**
- **feat: OAuth via hub-as-issuer with refresh + DCR cache (#83).**
- **release: 0.3.2 (+ ignore `.claude` in lint/test) (#82).**
- **docs: update parachute-cli refs to parachute-hub (#81).**
- **feat: probe local hub at :1939 when same-origin probe fails (#80).**
- **docs(readme): status note — PWA install flow coming with public
exposure (#77).**
### Repo hygiene
- **chore: gitignore `.claude/` stray artifacts.** Local agent worktrees /
scheduled-task locks no longer show up as untracked files.
## 0.3.0 (2026-04-23)
Launch.
# parachute-notes daemon — DEPRECATED
**Status**: Deprecated as of 2026-05-22 — see migration below.
The `@openparachute/notes` daemon is deprecated. Notes now ships as a UI bundle (`@openparachute/notes-ui`) consumed by [parachute-app](https://github.com/ParachuteComputer/parachute-app).
## Migration
If you have notes-daemon installed today:
1. Install parachute-app: `parachute install app`
2. Apps auto-bootstraps Notes on fresh installs; if you have an existing apps install, add it manually:
`parachute-app add @openparachute/notes-ui --name notes --path /app/notes`
3. Your existing bookmarks/links to `/notes/*` continue working — hub redirects to `/app/notes/*` automatically (Phase 2 redirect window)
4. Optional: uninstall the old daemon: `parachute uninstall notes` (keeps your vault notes intact — they live in vault, not the daemon)
## Why the change
- Notes is conceptually an "app" that consumes a vault — not its own backend service
- parachute-app is the host module for custom UIs (Gitcoin Brain, Unforced Brain, etc.); Notes joins them as the first canonical app
- Reduces ecosystem surface (4 committed-core modules → 3 + 1 host module)
- New UIs can ship as bundles without each becoming a full npm-published module
Full migration arc: https://parachute.computer/design/2026-05-21-parachute-apps-design — Section 16.
## Timeline
- **Phase 1** (done): @openparachute/notes-ui published. notes-daemon continues alongside.
- **Phase 2** (this release): notes-daemon deprecated. Hub redirects /notes/* → /app/notes/*. Operators can migrate at their own pace.
- **Phase 3** (TBD, ~Q3 2026): notes-daemon retires. Port 1942 reclaimed.
- **Phase 4** (cleanup): notes-daemon package archived. Source moves to UI-only.
## Questions / Issues
File at https://github.com/ParachuteComputer/parachute-notes/issues
import{aa as h,W as g,x as l,r as e,N as f,L as m,z as b,V as y}from"./index-BDPMEkxL.js";const p=1440*60*1e3,j=5e3;function N(n,r=30,s=new Date){const d=s.getTime()-r*p,a=[];for(const t of n){const c=t.path??t.id,o=Date.parse(t.createdAt);if(Number.isFinite(o)&&o>=d&&a.push({id:`${t.id}:created`,noteId:t.id,noteName:c,kind:"created",at:t.createdAt,preview:t.preview,tags:t.tags}),t.updatedAt){const i=Date.parse(t.updatedAt);Number.isFinite(i)&&i>=d&&Number.isFinite(o)&&i-o>j&&a.push({id:`${t.id}:updated`,noteId:t.id,noteName:c,kind:"updated",at:t.updatedAt,preview:t.preview,tags:t.tags})}}return a.sort((t,c)=>Date.parse(c.at)-Date.parse(t.at)),a}const v=["today","yesterday","thisWeek","older"],k={today:"Today",yesterday:"Yesterday",thisWeek:"This week",older:"Older"};function w(n,r=new Date){const s=Date.parse(n);if(!Number.isFinite(s))return null;const d=u(r),a=u(new Date(s)),t=Math.round((d.getTime()-a.getTime())/p);return t<0||t===0?"today":t===1?"yesterday":t<7?"thisWeek":"older"}function u(n){return new Date(n.getFullYear(),n.getMonth(),n.getDate())}function D(n,r=new Date){const s={today:[],yesterday:[],thisWeek:[],older:[]};for(const d of n){const a=w(d.at,r);a&&s[a].push(d)}return s}const x=50;function F(){const n=h(i=>i.getActiveVault()),r=g(),[s,d]=l.useState(x),a=l.useMemo(()=>r.data?N(r.data):[],[r.data]),t=l.useMemo(()=>a.slice(0,s),[a,s]),c=l.useMemo(()=>D(t),[t]),o=a.length-t.length;return n?e.jsxs("div",{className:"mx-auto max-w-3xl px-4 py-6 md:px-6 md:py-10",children:[e.jsxs("header",{className:"mb-5 md:mb-6",children:[e.jsx("p",{className:"text-xs uppercase tracking-wider text-fg-dim",children:"Activity"}),e.jsx("h1",{className:"font-serif text-2xl tracking-tight md:text-3xl",children:"Recent changes"}),e.jsx("p",{className:"mt-1 text-sm text-fg-muted",children:"Last 30 days, newest first. Deletions aren't tracked yet."})]}),r.isPending?e.jsx(T,{}):r.isError?e.jsx(B,{error:r.error}):a.length===0?e.jsx(S,{}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"space-y-8",children:v.map(i=>c[i].length>0?e.jsx(E,{title:k[i],events:c[i]},i):null)}),o>0?e.jsx("div",{className:"mt-8 flex justify-center",children:e.jsxs("button",{type:"button",onClick:()=>d(i=>i+x),className:"rounded-md border border-border bg-card px-4 py-2 text-sm text-fg-muted hover:text-accent",children:["Load more (",o," remaining)"]})}):null]})]}):e.jsx(f,{to:"/",replace:!0})}function E({title:n,events:r}){return e.jsxs("section",{children:[e.jsxs("h2",{className:"mb-2 text-xs uppercase tracking-wider text-fg-dim",children:[n," (",r.length,")"]}),e.jsx("ol",{className:"divide-y divide-border rounded-md border border-border bg-card",children:r.map(s=>e.jsx("li",{children:e.jsxs(m,{to:`/n/${encodeURIComponent(s.noteId)}`,className:"block px-4 py-3 hover:bg-bg/60 focus:bg-bg/60 focus:outline-none",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-4",children:[e.jsxs("div",{className:"flex min-w-0 items-baseline gap-2",children:[e.jsx(A,{kind:s.kind}),e.jsx("span",{className:"truncate font-mono text-sm text-fg",children:s.noteName})]}),e.jsx("span",{className:"shrink-0 text-xs text-fg-dim",children:b(s.at)})]}),s.preview?e.jsx("p",{className:"mt-1 truncate text-sm text-fg-muted",children:s.preview}):null,s.tags&&s.tags.length>0?e.jsx("div",{className:"mt-2 flex flex-wrap gap-1",children:s.tags.map(d=>e.jsxs("span",{className:"rounded-md bg-border/40 px-1.5 py-0.5 text-xs text-fg-dim",children:["#",d]},d))}):null]})},s.id))})]})}function A({kind:n}){return n==="created"?e.jsx("span",{className:"shrink-0 rounded-md bg-accent/10 px-1.5 py-0.5 text-xs text-accent",children:"Created"}):e.jsx("span",{className:"shrink-0 rounded-md bg-border/40 px-1.5 py-0.5 text-xs text-fg-muted",children:"Edited"})}function S(){return e.jsxs("div",{className:"rounded-md border border-border bg-card p-10 text-center",children:[e.jsx("p",{className:"mb-4 text-fg-muted",children:"No activity in the last 30 days."}),e.jsx(m,{to:"/capture",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Open capture"})]})}function T(){return e.jsx("div",{className:"space-y-3","aria-busy":"true",children:[0,1,2,3,4].map(n=>e.jsx("div",{className:"h-16 animate-pulse rounded-md bg-border/30"},n))})}function B({error:n}){const r=n instanceof y;return e.jsxs("div",{className:"rounded-md border border-red-500/30 bg-red-500/5 p-6",children:[e.jsx("p",{className:"mb-2 font-medium text-red-400",children:r?"Session expired":"Could not load activity"}),e.jsx("p",{className:"mb-4 text-sm text-fg-muted",children:n.message}),r?e.jsx(m,{to:"/add",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Reconnect vault"}):null]})}export{F as Activity};
import{a3 as v,x as t,X as j,r as e,I as y,v as w,j as N,a as S}from"./index-BDPMEkxL.js";function R(){const[b]=v(),u=b.get("url")??"",[a,c]=t.useState(u),[i,l]=t.useState(null),[g,d]=t.useState(!1),[o,m]=t.useState(!1),x=t.useRef(null),h=t.useRef(u.length>0),n=j();t.useEffect(()=>{var s;(s=x.current)==null||s.focus()},[]),t.useEffect(()=>{h.current||n.status==="found"&&n.origin&&a===""&&(c(n.origin),h.current=!0)},[n.status,n.origin,a]);async function p(s){s.preventDefault(),l(null),d(!1);let f;try{f=w(a)}catch(r){l(r.message);return}m(!0);try{const{authorizeUrl:r}=await N(f);window.location.assign(r)}catch(r){r instanceof S?d(!0):l(r.message),m(!1)}}return e.jsxs("div",{className:"mx-auto max-w-xl px-6 py-16",children:[e.jsx("h1",{className:"mb-2 font-serif text-4xl tracking-tight",children:"Connect a vault"}),e.jsx("p",{className:"mb-8 text-fg-muted",children:"Paste your Parachute hub URL. You'll be taken to its consent page to authorize Parachute Notes."}),e.jsxs("form",{onSubmit:p,className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:"vault-url",className:"mb-1.5 block text-sm font-medium text-fg",children:"Hub URL"}),e.jsx("input",{id:"vault-url",ref:x,type:"url",required:!0,placeholder:"http://localhost:1939",value:a,onChange:s=>c(s.target.value),disabled:o,className:"w-full rounded-md border border-border bg-card px-3 py-2 font-mono text-sm text-fg focus:border-accent focus:outline-none"}),e.jsxs("p",{className:"mt-1.5 text-xs text-fg-dim",children:["For a local install the hub lives at ",e.jsx("code",{children:"http://localhost:1939"}),". A standalone vault URL (e.g. ",e.jsx("code",{children:"https://host/vault/default"}),") also works — Notes will OAuth against whichever issuer answers."]})]}),g?e.jsx(y,{}):null,i?e.jsx("div",{className:"rounded-md border border-red-400/30 bg-red-400/5 px-3 py-2 text-sm text-red-400",children:i}):null,e.jsx("button",{type:"submit",disabled:o||!a,className:"w-full rounded-md bg-accent px-4 py-2.5 text-sm font-medium text-white hover:bg-accent-hover disabled:cursor-not-allowed disabled:opacity-60",children:o?"Starting OAuth…":"Continue"})]})]})}export{R as AddVault};
import{aa as k,a3 as E,W as A,x as y,r as e,N as K,L as d,V as S}from"./index-BDPMEkxL.js";import{d as f,c as j,e as P,m as T,t as V,s as N,p as i,a as C}from"./dates-BGZoWpL2.js";const _=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],x=5;function Y(){const a=k(t=>t.getActiveVault()),[o]=E(),l=o.get("month"),r=f(l)??f(j()),s=A(),h=P(),v=y.useMemo(()=>T(r.year,r.month),[r.year,r.month]),$=y.useMemo(()=>{const t=new Map;if(!s.data)return t;for(const n of s.data){const c=V(n.createdAt);c&&t.set(c,(t.get(c)??0)+1)}return t},[s.data]);if(!a)return e.jsx(K,{to:"/",replace:!0});const u=N(r.year,r.month,-1),p=N(r.year,r.month,1),b=`${u.year}-${i(u.month)}`,g=`${p.year}-${i(p.month)}`,M=j(),w=`${r.year}-${i(r.month)}`===M;return e.jsxs("div",{className:"mx-auto max-w-4xl px-4 py-6 md:px-6 md:py-10",children:[e.jsxs("header",{className:"mb-6 flex flex-wrap items-baseline justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-xs uppercase tracking-wider text-fg-dim",children:"Calendar"}),e.jsx("h1",{className:"font-serif text-3xl tracking-tight",children:C(r.year,r.month)})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm",children:[e.jsxs(d,{to:`/calendar?month=${b}`,className:"rounded-md border border-border bg-card px-3 py-1.5 text-fg-muted hover:text-accent","aria-label":"Previous month",children:["← ",b]}),w?null:e.jsx(d,{to:"/calendar",className:"rounded-md border border-border bg-card px-3 py-1.5 text-fg-muted hover:text-accent",children:"This month"}),e.jsxs(d,{to:`/calendar?month=${g}`,className:"rounded-md border border-border bg-card px-3 py-1.5 text-fg-muted hover:text-accent","aria-label":"Next month",children:[g," →"]}),e.jsx(d,{to:`/today?date=${h}`,className:"rounded-md border border-border bg-card px-3 py-1.5 text-fg-muted hover:text-accent",children:"Today"})]})]}),s.isError?e.jsx(L,{error:s.error}):e.jsxs("div",{className:"rounded-md border border-border bg-card","aria-busy":s.isPending,children:[e.jsx("div",{className:"grid grid-cols-7 border-b border-border text-xs uppercase tracking-wider text-fg-dim",children:_.map(t=>e.jsx("div",{className:"px-2 py-2 text-center",children:t},t))}),e.jsx("div",{className:"grid grid-cols-7",children:v.map(t=>{const n=`${t.getFullYear()}-${i(t.getMonth()+1)}-${i(t.getDate())}`,c=t.getMonth()+1===r.month,m=$.get(n)??0,D=n===h;return e.jsxs(d,{to:`/today?date=${n}`,className:`flex min-h-20 flex-col border-b border-r border-border p-1.5 text-xs hover:bg-bg/60 focus:bg-bg/60 focus:outline-none ${c?"":"opacity-40"}`,"aria-label":`${n} — ${m} notes`,children:[e.jsx("span",{className:`mb-1 inline-flex h-6 w-6 items-center justify-center rounded-full ${D?"bg-accent text-white":"text-fg"}`,children:t.getDate()}),m>0?e.jsx(F,{count:m}):e.jsx("span",{className:"sr-only",children:"no notes"})]},n)})})]}),e.jsx("p",{className:"mt-3 text-xs text-fg-dim",children:"Each dot is a note created on that day. Click any day to open /today."})]})}function F({count:a}){const o=Math.min(a,x),l=a>x?a-x:0;return e.jsxs("span",{className:"flex flex-wrap items-center gap-0.5",children:[Array.from({length:o}).map((r,s)=>e.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-accent","aria-hidden":"true"},s)),l>0?e.jsxs("span",{className:"ml-0.5 text-[10px] text-fg-dim",children:["+",l]}):null]})}function L({error:a}){const o=a instanceof S;return e.jsxs("div",{className:"rounded-md border border-red-500/30 bg-red-500/5 p-6",children:[e.jsx("p",{className:"mb-2 font-medium text-red-400",children:o?"Session expired":"Could not load notes"}),e.jsx("p",{className:"mb-4 text-sm text-fg-muted",children:a.message}),o?e.jsx(d,{to:"/add",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Reconnect vault"}):null]})}export{Y as Calendar};
import{aa as xe,a7 as be,a4 as ye,a5 as ve,E as we,x as i,t as Y,n as ke,s as Te,m as S,k as Re,r as a,N as Se,z as je,e as Ne,u as oe,L as Ee}from"./index-BDPMEkxL.js";const Ie=["audio/webm;codecs=opus","audio/mp4","audio/ogg;codecs=opus"];function Ce(r=Ie){if(typeof MediaRecorder>"u")return null;for(const t of r)if(MediaRecorder.isTypeSupported(t))return t;return null}function Me(r){return r.startsWith("audio/webm")?"webm":r.startsWith("audio/mp4")?"m4a":r.startsWith("audio/ogg")?"ogg":r.startsWith("audio/wav")?"wav":"bin"}function Ae(r){const t=r.now??(()=>Date.now()),d=r.MediaRecorderCtor??MediaRecorder,n=new d(r.stream,{mimeType:r.mimeType}),l=[];let s="idle",m=0,A=0;n.ondataavailable=k=>{k.data&&k.data.size>0&&l.push(k.data)};const p=()=>{for(const k of r.stream.getTracks())k.stop()};return{get state(){return s},get mimeType(){return r.mimeType},start(){if(s!=="idle")throw new Error(`Cannot start from ${s}`);n.start(),m=t(),s="recording"},pause(){s==="recording"&&(n.pause(),A+=t()-m,s="paused")},resume(){s==="paused"&&(n.resume(),m=t(),s="recording")},async stop(){if(s==="idle"||s==="stopped")throw new Error(`Cannot stop from ${s}`);s==="recording"&&(A+=t()-m);const k=new Promise(x=>{n.onstop=async()=>{const L=await $e(l);x({data:L,mimeType:r.mimeType,durationMs:A})}});return n.stop(),s="stopped",p(),k},cancel(){if(s==="recording"||s==="paused")try{n.stop()}catch{}s="stopped",l.length=0,p()}}}async function De(r){const t=r;return typeof t.arrayBuffer=="function"?t.arrayBuffer():new Promise((d,n)=>{const l=new FileReader;l.onload=()=>d(l.result),l.onerror=()=>n(l.error??new Error("FileReader error")),l.readAsArrayBuffer(r)})}async function $e(r){if(r.length===0)return new ArrayBuffer(0);const t=await Promise.all(r.map(s=>De(s))),d=t.reduce((s,m)=>s+m.byteLength,0),n=new Uint8Array(d);let l=0;for(const s of t)n.set(new Uint8Array(s),l),l+=s.byteLength;return n.buffer}async function Oe(){var r;if(typeof navigator>"u"||!((r=navigator.mediaDevices)!=null&&r.getUserMedia)){const t=new Error("Microphone is not available in this browser.");throw t.kind="unavailable",t}try{return await navigator.mediaDevices.getUserMedia({audio:!0})}catch(t){const d=new Error(t instanceof Error?t.message:"Microphone permission denied."),n=t instanceof DOMException?t.name:"";throw d.kind=n==="NotFoundError"||n==="OverconstrainedError"?"no-device":"permission-denied",d}}function Le(r,t=new Date){return`memo-${t.toISOString().replace(/[:.]/g,"-").replace(/Z$/,"")}.${Me(r)}`}function se(r=new Date){const t=r.getFullYear(),d=String(r.getMonth()+1).padStart(2,"0"),n=String(r.getDate()).padStart(2,"0"),l=String(r.getHours()).padStart(2,"0"),s=String(r.getMinutes()).padStart(2,"0"),m=String(r.getSeconds()).padStart(2,"0");return`Notes/${t}/${d}-${n}/${l}-${s}-${m}`}const Pe=/(?:^|\s)#([a-zA-Z][\w-]*)/g;function Z(r){const t=new Set;for(const d of r.matchAll(Pe)){const n=oe(d[1]??"");n&&t.add(n)}return[...t]}function G(r){const t=Math.floor(r/1e3),d=Math.floor(t/60),n=t%60;return`${String(d).padStart(2,"0")}:${String(n).padStart(2,"0")}`}function Fe({moreFieldsOpenDefault:r=!1}={}){const t=xe(e=>e.getActiveVault()),d=be(e=>e.push),{db:n,blobStore:l,engine:s}=ye(),{roles:m}=ve((t==null?void 0:t.id)??null),A=we(),[p,k]=i.useState(""),[x,L]=i.useState([]),[ie,F]=i.useState(""),[ce,de]=i.useState(r),D=i.useRef(se()),J=i.useRef(!1),[j,Q]=i.useState(()=>D.current),le=i.useCallback(e=>{J.current=e.trim()!==""&&e!==D.current,Q(e)},[]),[N,ue]=i.useState(""),[c,b]=i.useState({kind:"idle"}),[me,B]=i.useState(0),$=i.useRef(null),[q,X]=i.useState(null),[pe,fe]=i.useState(0),V=i.useRef(null),E=i.useRef(null),W=i.useRef(null),P=i.useRef(!1);i.useEffect(()=>{if(c.kind!=="recording")return;const e=setInterval(()=>B(Date.now()-c.startedAt),250);return()=>clearInterval(e)},[c]),i.useEffect(()=>()=>{E.current&&URL.revokeObjectURL(E.current)},[]),i.useEffect(()=>{var e;(e=W.current)==null||e.focus()},[]);const ge=i.useCallback(async()=>{if(!(c.kind==="recording"||c.kind==="requesting")){b({kind:"requesting"});try{const e=Ce();if(!e){b({kind:"denied",message:"This browser can't record audio in a format we can save."});return}const o=await Oe(),u=Ae({stream:o,mimeType:e});V.current=u,u.start(),B(0),b({kind:"recording",startedAt:Date.now()})}catch(e){const o=e,u=o.kind==="permission-denied"?"Microphone access was denied. Update your browser's site settings to record.":o.kind==="no-device"?"No microphone was found on this device.":o instanceof Error?o.message:"Microphone is not available in this browser.";b({kind:"denied",message:u})}}},[c]),ee=i.useCallback(async()=>{const e=V.current;if(!(!e||c.kind!=="recording"))try{const o=await e.stop();V.current=null;const u=new Blob([o.data],{type:o.mimeType}),y=URL.createObjectURL(u);E.current&&URL.revokeObjectURL(E.current),E.current=y,b({kind:"have-audio",data:o.data,mimeType:o.mimeType,url:y,durationMs:o.durationMs})}catch(o){d(o instanceof Error?`Recording failed: ${o.message}`:"Recording failed.","error"),b({kind:"idle"})}},[c,d]);i.useEffect(()=>{if(c.kind!=="recording")return;const e=()=>{ee()};return window.addEventListener("pointerup",e),window.addEventListener("pointercancel",e),()=>{window.removeEventListener("pointerup",e),window.removeEventListener("pointercancel",e)}},[c,ee]);const _=i.useCallback(()=>{E.current&&(URL.revokeObjectURL(E.current),E.current=null),b({kind:"idle"}),B(0)},[]),te=i.useCallback(()=>{var e;if($.current=null,X(null),k(""),L([]),F(""),!J.current){const o=se();D.current=o,Q(o)}_(),(e=W.current)==null||e.focus()},[_]),U=c.kind==="have-audio",T=p.trim().length>0,H=(T||U)&&c.kind!=="saving",z=i.useCallback(async()=>{if(!H||!n||!t)return;if(U&&!l){d("Sync queue not ready — try again in a moment.","error");return}const e=c.kind==="have-audio"?c:null;P.current=!0,b({kind:"saving"});const o=x.filter(g=>g.length>0),u=Z(p),y=[];T&&y.push(m.captureText),e&&y.push(m.captureVoice);const v=Array.from(new Set([...y,...o,...u].filter(g=>g.length>0))),f=$.current,w=(f==null?void 0:f.localId)??Y(),I=j.trim()||D.current,C=N.trim(),h=C?{summary:C}:void 0;A&&ke(t.id,A);try{if(e){const g=new Date,O=Le(e.mimeType,g),M=Te(),R=T?`${p.trim()}
_Transcript pending._
![[${O}]]
`:`_Transcript pending._
![[${O}]]
`,ae=I;if(!l)throw new Error("blob store missing");await l.put(M,e.data,e.mimeType,t.id),await S(n,{kind:"create-note",localId:w,payload:{content:R,path:ae,...v.length?{tags:v}:{},...h?{metadata:h}:{}}},{vaultId:t.id}),await S(n,{kind:"upload-attachment",blobId:M,filename:O,mimeType:e.mimeType},{vaultId:t.id}),await S(n,{kind:"link-attachment",noteId:w,pathRef:Re(M),mimeType:e.mimeType,transcribe:!0},{vaultId:t.id})}else f!=null&&f.createCommitted?await S(n,{kind:"update-note",targetId:w,payload:{content:p,path:I,...v.length?{tags:{add:v}}:{},...h?{metadata:h}:{}}},{vaultId:t.id}):await S(n,{kind:"create-note",localId:w,payload:{content:p,path:I,...v.length?{tags:v}:{},...h?{metadata:h}:{}}},{vaultId:t.id});s==null||s.runOnce(),d(e?"Captured — syncing audio.":"Captured.","success"),te(),b({kind:"idle"}),P.current=!1}catch(g){d(g instanceof Error?`Capture failed: ${g.message}`:"Capture failed.","error"),P.current=!1,b(e?{kind:"have-audio",data:e.data,mimeType:e.mimeType,url:e.url,durationMs:e.durationMs}:{kind:"idle"})}},[H,n,t,l,A,c,U,T,x,p,j,N,m.captureText,m.captureVoice,s,d,te]),re=i.useCallback(async()=>{if(!n||!t||c.kind!=="idle"||!T)return;const e=x.filter(h=>h.length>0),o=Z(p),u=Array.from(new Set([m.captureText,...e,...o].filter(h=>h.length>0))),y=j.trim()||D.current,v=N.trim(),f=v?{summary:v}:void 0,w=$.current,I=!w,C=(w==null?void 0:w.localId)??Y();I&&($.current={localId:C,createCommitted:!0});try{I?await S(n,{kind:"create-note",localId:C,payload:{content:p,path:y,...u.length?{tags:u}:{},...f?{metadata:f}:{}}},{vaultId:t.id}):await S(n,{kind:"update-note",targetId:C,payload:{content:p,path:y,...u.length?{tags:{add:u}}:{},...f?{metadata:f}:{}}},{vaultId:t.id}),s==null||s.runOnce(),X(Date.now())}catch{I&&($.current=null)}},[n,t,c.kind,T,p,x,j,N,m.captureText,s]),he=i.useCallback(e=>{(e.metaKey||e.ctrlKey)&&e.key==="Enter"&&(e.preventDefault(),z())},[z]),ne=i.useRef({db:n,activeVaultId:(t==null?void 0:t.id)??null,content:p,tags:x,pathOverride:j,summary:N,roles:m});return ne.current={db:n,activeVaultId:(t==null?void 0:t.id)??null,content:p,tags:x,pathOverride:j,summary:N,roles:m},i.useEffect(()=>()=>{if(P.current)return;const{db:e,activeVaultId:o,content:u,tags:y,pathOverride:v,summary:f,roles:w}=ne.current;if(!u.trim()||!e||!o)return;const C=y.filter(K=>K.length>0),h=Z(u),g=Array.from(new Set([w.captureText,...C,...h].filter(K=>K.length>0))),O=v.trim()||D.current,M=f.trim(),R=$.current;(R!=null&&R.createCommitted?S(e,{kind:"update-note",targetId:R.localId,payload:{content:u,path:O,...g.length?{tags:{add:g}}:{},...M?{metadata:{summary:M}}:{}}},{vaultId:o}):S(e,{kind:"create-note",localId:(R==null?void 0:R.localId)??Y(),payload:{content:u,path:O,...g.length?{tags:g}:{},...M?{metadata:{summary:M}}:{}}},{vaultId:o})).catch(()=>{})},[]),i.useEffect(()=>{if(q===null)return;const e=setInterval(()=>{fe(o=>o+1)},15e3);return()=>clearInterval(e)},[q]),i.useEffect(()=>{if(c.kind==="recording"||c.kind==="requesting"||c.kind==="saving"||c.kind==="have-audio"||!T)return;const e=setTimeout(()=>{P.current||re()},5e3);return()=>clearTimeout(e)},[c.kind,T,p,x,j,N,re]),t?a.jsxs("div",{className:"mx-auto max-w-2xl px-4 py-5 md:px-6 md:py-8",children:[a.jsxs("header",{className:"mb-5",children:[a.jsx("h1",{className:"font-serif text-2xl text-fg md:text-3xl",children:"Capture"}),a.jsxs("p",{className:"mt-1 text-xs text-fg-dim",children:["Type a thought, hold the mic to record, or both."," ",a.jsx("kbd",{className:"rounded bg-bg/60 px-1",children:"⌘"}),a.jsx("kbd",{className:"rounded bg-bg/60 px-1",children:"↵"})," to send."]})]}),a.jsxs("section",{className:"flex flex-col gap-4 rounded-xl border border-border bg-card p-5 md:p-6",children:[a.jsx("textarea",{ref:W,value:p,onChange:e=>k(e.target.value),onKeyDown:he,placeholder:"What are you thinking?","aria-label":"Capture content",rows:8,disabled:c.kind==="saving",className:"min-h-[30vh] w-full resize-y rounded-md border border-border bg-bg px-3 py-2 text-sm text-fg placeholder:text-fg-dim focus:border-accent focus:outline-none disabled:opacity-60"}),q!==null?a.jsxs("p",{className:"-mt-2 text-right text-[11px] text-fg-dim","aria-live":"polite","data-indicator-tick":pe,children:["Draft saved · ",je(new Date(q).toISOString())]}):null,c.kind==="have-audio"?a.jsxs("div",{className:"flex flex-col gap-2 rounded-md border border-accent/30 bg-accent/5 p-3",children:[a.jsxs("div",{className:"flex items-center justify-between gap-3",children:[a.jsxs("span",{className:"text-sm text-fg-muted",children:["🎙 Recorded ",G(c.durationMs)]}),a.jsx("button",{type:"button",onClick:_,className:"text-xs text-fg-dim hover:text-red-400",children:"Discard"})]}),a.jsx("audio",{controls:!0,src:c.url,className:"w-full",children:a.jsx("track",{kind:"captions"})}),a.jsx("p",{className:"text-xs text-fg-dim",children:"Transcript will be appended once your vault processes it."})]}):null,c.kind==="denied"?a.jsx("p",{className:"rounded-md border border-red-500/30 bg-red-500/5 px-3 py-2 text-xs text-red-400",children:c.message}):null,a.jsx(Ne,{tags:x,input:ie,onInputChange:F,onAdd:e=>{const o=oe(e);!o||x.includes(o)||(L(u=>[...u,o]),F(""))},onRemove:e=>L(o=>o.filter(u=>u!==e))}),a.jsxs("details",{className:"group rounded-md border border-border bg-bg/50",open:ce,onToggle:e=>de(e.currentTarget.open),children:[a.jsx("summary",{className:"cursor-pointer select-none px-3 py-2 text-xs text-fg-muted hover:text-accent",children:"More fields"}),a.jsxs("div",{className:"space-y-3 px-3 pb-3 pt-1",children:[a.jsxs("label",{className:"flex flex-col gap-1 text-xs",children:[a.jsx("span",{className:"text-fg-dim",children:"Path"}),a.jsx("input",{type:"text",value:j,onChange:e=>le(e.target.value),placeholder:"(blank → uses generated path)","aria-label":"Path override",className:"rounded-md border border-border bg-card px-2.5 py-1.5 font-mono text-xs text-fg focus:border-accent focus:outline-none"})]}),a.jsxs("label",{className:"flex flex-col gap-1 text-xs",children:[a.jsx("span",{className:"text-fg-dim",children:"Summary"}),a.jsx("input",{type:"text",value:N,onChange:e=>ue(e.target.value),placeholder:"(optional one-line description)","aria-label":"Summary",className:"rounded-md border border-border bg-card px-2.5 py-1.5 text-xs text-fg focus:border-accent focus:outline-none"})]}),a.jsxs("p",{className:"text-xs text-fg-dim",children:["Need to attach a file?"," ",a.jsx(Ee,{to:"/new",className:"text-accent hover:underline",children:"Open the full editor"}),"."]})]})]}),a.jsxs("div",{className:"flex items-center justify-between gap-3 pt-2",children:[a.jsx(Ue,{phase:c,elapsedMs:me,onPointerDown:()=>void ge()}),a.jsxs("div",{className:"flex flex-col items-end gap-1",children:[a.jsx("button",{type:"button",onClick:()=>void z(),disabled:!H,className:"min-h-11 rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover disabled:opacity-40",children:c.kind==="saving"?"Saving…":"Capture"}),a.jsx("span",{className:"text-[11px] text-fg-dim",children:U&&T?"Will save as a note with audio attached.":U?"Will save as a voice memo.":T?"Will save as a text note.":"Type or record to capture."})]})]})]})]}):a.jsx(Se,{to:"/",replace:!0})}function Ue({phase:r,elapsedMs:t,onPointerDown:d}){const n=r.kind==="recording",l=r.kind==="requesting",s=n?`Recording — release to stop (${G(t)})`:l?"Requesting microphone…":"Hold to record";return a.jsxs("button",{type:"button",onPointerDown:m=>{m.preventDefault(),d()},"aria-label":s,"aria-pressed":n,disabled:r.kind==="saving",className:`flex min-h-11 items-center gap-2 rounded-full border px-4 py-2 text-sm font-medium transition select-none ${n?"border-red-500/40 bg-red-500/10 text-red-400":"border-accent/30 bg-accent/10 text-accent hover:bg-accent/15"} disabled:opacity-40`,children:[a.jsx("span",{"aria-hidden":"true",className:n?"animate-pulse":"",children:"🎙"}),a.jsx("span",{children:n?`Rec ${G(t)}`:l?"Requesting…":"Hold to record"})]})}export{Fe as Capture,Z as extractHashtags};
function u(t){return t<10?`0${t}`:String(t)}function s(t=new Date){return`${t.getFullYear()}-${u(t.getMonth()+1)}-${u(t.getDate())}`}function l(t){if(!t)return null;const e=new Date(t);return Number.isNaN(e.getTime())?null:s(e)}function c(t){if(!t||!/^\d{4}-\d{2}-\d{2}$/.test(t))return null;const[e,n,r]=t.split("-").map(Number),a=new Date(e,n-1,r);return Number.isNaN(a.getTime())?null:a}function f(t=new Date){return`${t.getFullYear()}-${u(t.getMonth()+1)}`}function d(t){if(!t||!/^\d{4}-\d{2}$/.test(t))return null;const[e,n]=t.split("-").map(Number);return n<1||n>12?null:{year:e,month:n}}function g(t,e,n){const r=t*12+(e-1)+n;return{year:Math.floor(r/12),month:r%12+1}}function m(t,e){const r=new Date(t,e-1,1).getDay(),a=new Date(t,e-1,1-r),i=[];for(let o=0;o<42;o++)i.push(new Date(a.getFullYear(),a.getMonth(),a.getDate()+o));return i}function D(t){const e=c(t);return e?e.toLocaleDateString(void 0,{weekday:"long",year:"numeric",month:"long",day:"numeric"}):t}function h(t,e){return new Date(t,e-1,1).toLocaleDateString(void 0,{year:"numeric",month:"long"})}export{h as a,c as b,f as c,d,s as e,D as f,m,u as p,g as s,l as t};

Sorry, the diff of this file is too big to display

@import"https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;1,9..40,300;1,9..40,400&family=JetBrains+Mono:wght@400;500&display=swap";/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial}}}@layer theme{:root,:host{--font-sans:"DM Sans", -apple-system, BlinkMacSystemFont, sans-serif;--font-serif:"Instrument Serif", Georgia, serif;--font-mono:"JetBrains Mono", "SF Mono", Monaco, monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-100:oklch(96.2% .059 95.617);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-700:oklch(55.5% .163 48.998);--color-emerald-300:oklch(84.5% .143 164.978);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-sky-300:oklch(82.8% .111 230.318);--color-sky-400:oklch(74.6% .16 232.661);--color-sky-500:oklch(68.5% .169 237.323);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--text-5xl:3rem;--text-5xl--line-height:1;--font-weight-medium:500;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-bg:#faf8f4;--color-bg-soft:#f3f0ea;--color-fg:#2c2a26;--color-fg-muted:#6b6860;--color-fg-dim:#9a9690;--color-accent:#4a7c59;--color-accent-hover:#3d6849;--color-accent-light:#6a9b77;--color-border:#e4e0d8;--color-card:#fff;--font-size-prose:18px;--font-size-editor:15px}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.inset-x-0{inset-inline:calc(var(--spacing) * 0)}.top-0{top:calc(var(--spacing) * 0)}.top-full{top:100%}.right-0{right:calc(var(--spacing) * 0)}.right-3{right:calc(var(--spacing) * 3)}.bottom-0{bottom:calc(var(--spacing) * 0)}.bottom-3{bottom:calc(var(--spacing) * 3)}.bottom-4{bottom:calc(var(--spacing) * 4)}.bottom-6{bottom:calc(var(--spacing) * 6)}.left-1\/2{left:50%}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.m-0{margin:calc(var(--spacing) * 0)}.m-auto{margin:auto}.mx-1{margin-inline:calc(var(--spacing) * 1)}.mx-auto{margin-inline:auto}.-mt-2{margin-top:calc(var(--spacing) * -2)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-10{margin-top:calc(var(--spacing) * 10)}.mr-1{margin-right:calc(var(--spacing) * 1)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.mb-10{margin-bottom:calc(var(--spacing) * 10)}.ml-0\.5{margin-left:calc(var(--spacing) * .5)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-auto{margin-left:auto}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1{height:calc(var(--spacing) * 1)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-14{height:calc(var(--spacing) * 14)}.h-16{height:calc(var(--spacing) * 16)}.h-24{height:calc(var(--spacing) * 24)}.h-28{height:calc(var(--spacing) * 28)}.h-32{height:calc(var(--spacing) * 32)}.h-\[24rem\]{height:24rem}.h-\[40rem\]{height:40rem}.h-\[calc\(100dvh-5rem\)\]{height:calc(100dvh - 5rem)}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-56{max-height:calc(var(--spacing) * 56)}.max-h-\[32rem\]{max-height:32rem}.max-h-\[50vh\]{max-height:50vh}.max-h-\[60vh\]{max-height:60vh}.max-h-full{max-height:100%}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-11{min-height:calc(var(--spacing) * 11)}.min-h-20{min-height:calc(var(--spacing) * 20)}.min-h-\[30vh\]{min-height:30vh}.min-h-\[60vh\]{min-height:60vh}.min-h-dvh{min-height:100dvh}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-1\/3{width:33.3333%}.w-2{width:calc(var(--spacing) * 2)}.w-2\/3{width:66.6667%}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-10{width:calc(var(--spacing) * 10)}.w-32{width:calc(var(--spacing) * 32)}.w-40{width:calc(var(--spacing) * 40)}.w-44{width:calc(var(--spacing) * 44)}.w-48{width:calc(var(--spacing) * 48)}.w-72{width:calc(var(--spacing) * 72)}.w-80{width:calc(var(--spacing) * 80)}.w-full{width:100%}.w-px{width:1px}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-\[12rem\]{max-width:12rem}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.max-w-xl{max-width:var(--container-xl)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-11{min-width:calc(var(--spacing) * 11)}.min-w-24{min-width:calc(var(--spacing) * 24)}.min-w-48{min-width:calc(var(--spacing) * 48)}.flex-1{flex:1}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.animate-pulse{animation:var(--animate-pulse)}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize-y{resize:vertical}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-around{justify-content:space-around}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-10{gap:calc(var(--spacing) * 10)}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * .5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 8) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 8) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}.gap-y-3{row-gap:calc(var(--spacing) * 3)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-border>:not(:last-child)){border-color:var(--color-border)}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t-md{border-top-left-radius:var(--radius-md);border-top-right-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-accent{border-color:var(--color-accent)}.border-accent\/30{border-color:#4a7c594d}@supports (color:color-mix(in lab,red,red)){.border-accent\/30{border-color:color-mix(in oklab,var(--color-accent) 30%,transparent)}}.border-accent\/40{border-color:#4a7c5966}@supports (color:color-mix(in lab,red,red)){.border-accent\/40{border-color:color-mix(in oklab,var(--color-accent) 40%,transparent)}}.border-accent\/60{border-color:#4a7c5999}@supports (color:color-mix(in lab,red,red)){.border-accent\/60{border-color:color-mix(in oklab,var(--color-accent) 60%,transparent)}}.border-amber-400\/40{border-color:#fcbb0066}@supports (color:color-mix(in lab,red,red)){.border-amber-400\/40{border-color:color-mix(in oklab,var(--color-amber-400) 40%,transparent)}}.border-amber-500\/30{border-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.border-amber-500\/30{border-color:color-mix(in oklab,var(--color-amber-500) 30%,transparent)}}.border-amber-500\/40{border-color:#f99c0066}@supports (color:color-mix(in lab,red,red)){.border-amber-500\/40{border-color:color-mix(in oklab,var(--color-amber-500) 40%,transparent)}}.border-border{border-color:var(--color-border)}.border-red-400\/30{border-color:#ff65684d}@supports (color:color-mix(in lab,red,red)){.border-red-400\/30{border-color:color-mix(in oklab,var(--color-red-400) 30%,transparent)}}.border-red-500\/30{border-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.border-red-500\/30{border-color:color-mix(in oklab,var(--color-red-500) 30%,transparent)}}.border-red-500\/40{border-color:#fb2c3666}@supports (color:color-mix(in lab,red,red)){.border-red-500\/40{border-color:color-mix(in oklab,var(--color-red-500) 40%,transparent)}}.border-sky-500\/30{border-color:#00a5ef4d}@supports (color:color-mix(in lab,red,red)){.border-sky-500\/30{border-color:color-mix(in oklab,var(--color-sky-500) 30%,transparent)}}.border-transparent{border-color:#0000}.bg-accent{background-color:var(--color-accent)}.bg-accent\/5{background-color:#4a7c590d}@supports (color:color-mix(in lab,red,red)){.bg-accent\/5{background-color:color-mix(in oklab,var(--color-accent) 5%,transparent)}}.bg-accent\/10{background-color:#4a7c591a}@supports (color:color-mix(in lab,red,red)){.bg-accent\/10{background-color:color-mix(in oklab,var(--color-accent) 10%,transparent)}}.bg-accent\/15{background-color:#4a7c5926}@supports (color:color-mix(in lab,red,red)){.bg-accent\/15{background-color:color-mix(in oklab,var(--color-accent) 15%,transparent)}}.bg-accent\/20{background-color:#4a7c5933}@supports (color:color-mix(in lab,red,red)){.bg-accent\/20{background-color:color-mix(in oklab,var(--color-accent) 20%,transparent)}}.bg-amber-400{background-color:var(--color-amber-400)}.bg-amber-400\/10{background-color:#fcbb001a}@supports (color:color-mix(in lab,red,red)){.bg-amber-400\/10{background-color:color-mix(in oklab,var(--color-amber-400) 10%,transparent)}}.bg-amber-500\/5{background-color:#f99c000d}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/5{background-color:color-mix(in oklab,var(--color-amber-500) 5%,transparent)}}.bg-amber-500\/10{background-color:#f99c001a}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/10{background-color:color-mix(in oklab,var(--color-amber-500) 10%,transparent)}}.bg-amber-500\/20{background-color:#f99c0033}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/20{background-color:color-mix(in oklab,var(--color-amber-500) 20%,transparent)}}.bg-amber-500\/30{background-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/30{background-color:color-mix(in oklab,var(--color-amber-500) 30%,transparent)}}.bg-bg{background-color:var(--color-bg)}.bg-bg\/40{background-color:#faf8f466}@supports (color:color-mix(in lab,red,red)){.bg-bg\/40{background-color:color-mix(in oklab,var(--color-bg) 40%,transparent)}}.bg-bg\/50{background-color:#faf8f480}@supports (color:color-mix(in lab,red,red)){.bg-bg\/50{background-color:color-mix(in oklab,var(--color-bg) 50%,transparent)}}.bg-bg\/60{background-color:#faf8f499}@supports (color:color-mix(in lab,red,red)){.bg-bg\/60{background-color:color-mix(in oklab,var(--color-bg) 60%,transparent)}}.bg-bg\/80{background-color:#faf8f4cc}@supports (color:color-mix(in lab,red,red)){.bg-bg\/80{background-color:color-mix(in oklab,var(--color-bg) 80%,transparent)}}.bg-bg\/90{background-color:#faf8f4e6}@supports (color:color-mix(in lab,red,red)){.bg-bg\/90{background-color:color-mix(in oklab,var(--color-bg) 90%,transparent)}}.bg-bg\/95{background-color:#faf8f4f2}@supports (color:color-mix(in lab,red,red)){.bg-bg\/95{background-color:color-mix(in oklab,var(--color-bg) 95%,transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab,red,red)){.bg-black\/60{background-color:color-mix(in oklab,var(--color-black) 60%,transparent)}}.bg-border{background-color:var(--color-border)}.bg-border\/30{background-color:#e4e0d84d}@supports (color:color-mix(in lab,red,red)){.bg-border\/30{background-color:color-mix(in oklab,var(--color-border) 30%,transparent)}}.bg-border\/40{background-color:#e4e0d866}@supports (color:color-mix(in lab,red,red)){.bg-border\/40{background-color:color-mix(in oklab,var(--color-border) 40%,transparent)}}.bg-border\/60{background-color:#e4e0d899}@supports (color:color-mix(in lab,red,red)){.bg-border\/60{background-color:color-mix(in oklab,var(--color-border) 60%,transparent)}}.bg-card{background-color:var(--color-card)}.bg-card\/30{background-color:#ffffff4d}@supports (color:color-mix(in lab,red,red)){.bg-card\/30{background-color:color-mix(in oklab,var(--color-card) 30%,transparent)}}.bg-card\/40{background-color:#fff6}@supports (color:color-mix(in lab,red,red)){.bg-card\/40{background-color:color-mix(in oklab,var(--color-card) 40%,transparent)}}.bg-card\/50{background-color:#ffffff80}@supports (color:color-mix(in lab,red,red)){.bg-card\/50{background-color:color-mix(in oklab,var(--color-card) 50%,transparent)}}.bg-card\/60{background-color:#fff9}@supports (color:color-mix(in lab,red,red)){.bg-card\/60{background-color:color-mix(in oklab,var(--color-card) 60%,transparent)}}.bg-card\/90{background-color:#ffffffe6}@supports (color:color-mix(in lab,red,red)){.bg-card\/90{background-color:color-mix(in oklab,var(--color-card) 90%,transparent)}}.bg-emerald-400{background-color:var(--color-emerald-400)}.bg-emerald-500\/20{background-color:#00bb7f33}@supports (color:color-mix(in lab,red,red)){.bg-emerald-500\/20{background-color:color-mix(in oklab,var(--color-emerald-500) 20%,transparent)}}.bg-red-400{background-color:var(--color-red-400)}.bg-red-400\/5{background-color:#ff65680d}@supports (color:color-mix(in lab,red,red)){.bg-red-400\/5{background-color:color-mix(in oklab,var(--color-red-400) 5%,transparent)}}.bg-red-500{background-color:var(--color-red-500)}.bg-red-500\/5{background-color:#fb2c360d}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/5{background-color:color-mix(in oklab,var(--color-red-500) 5%,transparent)}}.bg-red-500\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/10{background-color:color-mix(in oklab,var(--color-red-500) 10%,transparent)}}.bg-red-500\/20{background-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/20{background-color:color-mix(in oklab,var(--color-red-500) 20%,transparent)}}.bg-red-500\/30{background-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/30{background-color:color-mix(in oklab,var(--color-red-500) 30%,transparent)}}.bg-sky-400{background-color:var(--color-sky-400)}.bg-sky-500\/5{background-color:#00a5ef0d}@supports (color:color-mix(in lab,red,red)){.bg-sky-500\/5{background-color:color-mix(in oklab,var(--color-sky-500) 5%,transparent)}}.bg-transparent{background-color:#0000}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.p-10{padding:calc(var(--spacing) * 10)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-7{padding-block:calc(var(--spacing) * 7)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-16{padding-block:calc(var(--spacing) * 16)}.py-20{padding-block:calc(var(--spacing) * 20)}.py-24{padding-block:calc(var(--spacing) * 24)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pt-\[10vh\]{padding-top:10vh}.pr-1{padding-right:calc(var(--spacing) * 1)}.pb-1\.5{padding-bottom:calc(var(--spacing) * 1.5)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pb-16{padding-bottom:calc(var(--spacing) * 16)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-5{padding-left:calc(var(--spacing) * 5)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.font-serif{font-family:var(--font-serif)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-none{--tw-leading:1;line-height:1}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.text-accent{color:var(--color-accent)}.text-accent\/70{color:#4a7c59b3}@supports (color:color-mix(in lab,red,red)){.text-accent\/70{color:color-mix(in oklab,var(--color-accent) 70%,transparent)}}.text-amber-50{color:var(--color-amber-50)}.text-amber-100{color:var(--color-amber-100)}.text-amber-100\/70{color:#fef3c6b3}@supports (color:color-mix(in lab,red,red)){.text-amber-100\/70{color:color-mix(in oklab,var(--color-amber-100) 70%,transparent)}}.text-amber-100\/90{color:#fef3c6e6}@supports (color:color-mix(in lab,red,red)){.text-amber-100\/90{color:color-mix(in oklab,var(--color-amber-100) 90%,transparent)}}.text-amber-200{color:var(--color-amber-200)}.text-amber-200\/80{color:#fee685cc}@supports (color:color-mix(in lab,red,red)){.text-amber-200\/80{color:color-mix(in oklab,var(--color-amber-200) 80%,transparent)}}.text-amber-300{color:var(--color-amber-300)}.text-amber-500{color:var(--color-amber-500)}.text-amber-700{color:var(--color-amber-700)}.text-emerald-300{color:var(--color-emerald-300)}.text-fg{color:var(--color-fg)}.text-fg-dim{color:var(--color-fg-dim)}.text-fg-muted{color:var(--color-fg-muted)}.text-red-50{color:var(--color-red-50)}.text-red-100{color:var(--color-red-100)}.text-red-200{color:var(--color-red-200)}.text-red-200\/80{color:#ffcacacc}@supports (color:color-mix(in lab,red,red)){.text-red-200\/80{color:color-mix(in oklab,var(--color-red-200) 80%,transparent)}}.text-red-300{color:var(--color-red-300)}.text-red-400{color:var(--color-red-400)}.text-sky-300{color:var(--color-sky-300)}.text-white{color:var(--color-white)}.text-white\/80{color:#fffc}@supports (color:color-mix(in lab,red,red)){.text-white\/80{color:color-mix(in oklab,var(--color-white) 80%,transparent)}}.capitalize{text-transform:capitalize}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.decoration-dashed{text-decoration-style:dashed}.underline-offset-4{text-underline-offset:4px}.accent-accent{accent-color:var(--color-accent)}.opacity-40{opacity:.4}.opacity-60{opacity:.6}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.select-none{-webkit-user-select:none;user-select:none}.group-open\:rotate-90:is(:where(.group):is([open],:popover-open,:open) *){rotate:90deg}.placeholder\:text-fg-dim::placeholder{color:var(--color-fg-dim)}.backdrop\:bg-black\/40::backdrop{background-color:#0006}@supports (color:color-mix(in lab,red,red)){.backdrop\:bg-black\/40::backdrop{background-color:color-mix(in oklab,var(--color-black) 40%,transparent)}}@media(hover:hover){.hover\:border-accent:hover{border-color:var(--color-accent)}.hover\:border-accent\/50:hover{border-color:#4a7c5980}@supports (color:color-mix(in lab,red,red)){.hover\:border-accent\/50:hover{border-color:color-mix(in oklab,var(--color-accent) 50%,transparent)}}.hover\:border-border:hover{border-color:var(--color-border)}.hover\:border-red-500\/40:hover{border-color:#fb2c3666}@supports (color:color-mix(in lab,red,red)){.hover\:border-red-500\/40:hover{border-color:color-mix(in oklab,var(--color-red-500) 40%,transparent)}}.hover\:bg-accent-hover:hover{background-color:var(--color-accent-hover)}.hover\:bg-accent\/5:hover{background-color:#4a7c590d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-accent\/5:hover{background-color:color-mix(in oklab,var(--color-accent) 5%,transparent)}}.hover\:bg-accent\/10:hover{background-color:#4a7c591a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-accent\/10:hover{background-color:color-mix(in oklab,var(--color-accent) 10%,transparent)}}.hover\:bg-accent\/15:hover{background-color:#4a7c5926}@supports (color:color-mix(in lab,red,red)){.hover\:bg-accent\/15:hover{background-color:color-mix(in oklab,var(--color-accent) 15%,transparent)}}.hover\:bg-accent\/20:hover{background-color:#4a7c5933}@supports (color:color-mix(in lab,red,red)){.hover\:bg-accent\/20:hover{background-color:color-mix(in oklab,var(--color-accent) 20%,transparent)}}.hover\:bg-amber-500\/20:hover{background-color:#f99c0033}@supports (color:color-mix(in lab,red,red)){.hover\:bg-amber-500\/20:hover{background-color:color-mix(in oklab,var(--color-amber-500) 20%,transparent)}}.hover\:bg-amber-500\/50:hover{background-color:#f99c0080}@supports (color:color-mix(in lab,red,red)){.hover\:bg-amber-500\/50:hover{background-color:color-mix(in oklab,var(--color-amber-500) 50%,transparent)}}.hover\:bg-bg:hover{background-color:var(--color-bg)}.hover\:bg-bg\/50:hover{background-color:#faf8f480}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bg\/50:hover{background-color:color-mix(in oklab,var(--color-bg) 50%,transparent)}}.hover\:bg-bg\/60:hover{background-color:#faf8f499}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bg\/60:hover{background-color:color-mix(in oklab,var(--color-bg) 60%,transparent)}}.hover\:bg-card:hover{background-color:var(--color-card)}.hover\:bg-red-500\/10:hover{background-color:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/10:hover{background-color:color-mix(in oklab,var(--color-red-500) 10%,transparent)}}.hover\:bg-red-500\/40:hover{background-color:#fb2c3666}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/40:hover{background-color:color-mix(in oklab,var(--color-red-500) 40%,transparent)}}.hover\:bg-red-500\/50:hover{background-color:#fb2c3680}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/50:hover{background-color:color-mix(in oklab,var(--color-red-500) 50%,transparent)}}.hover\:bg-red-600:hover{background-color:var(--color-red-600)}.hover\:text-accent:hover{color:var(--color-accent)}.hover\:text-accent-hover:hover{color:var(--color-accent-hover)}.hover\:text-amber-100:hover{color:var(--color-amber-100)}.hover\:text-fg:hover{color:var(--color-fg)}.hover\:text-red-100:hover{color:var(--color-red-100)}.hover\:text-red-300:hover{color:var(--color-red-300)}.hover\:text-red-400:hover{color:var(--color-red-400)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:border-accent:focus{border-color:var(--color-accent)}.focus\:border-border:focus{border-color:var(--color-border)}.focus\:border-red-400:focus{border-color:var(--color-red-400)}.focus\:bg-bg\/60:focus{background-color:#faf8f499}@supports (color:color-mix(in lab,red,red)){.focus\:bg-bg\/60:focus{background-color:color-mix(in oklab,var(--color-bg) 60%,transparent)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:outline-accent:focus-visible{outline-color:var(--color-accent)}@media(hover:hover){.enabled\:hover\:text-accent:enabled:hover{color:var(--color-accent)}}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}@media(min-width:40rem){.sm\:inline{display:inline}}@media(min-width:48rem){.md\:sticky{position:sticky}.md\:top-6{top:calc(var(--spacing) * 6)}.md\:mb-6{margin-bottom:calc(var(--spacing) * 6)}.md\:block{display:block}.md\:hidden{display:none}.md\:min-h-0{min-height:calc(var(--spacing) * 0)}.md\:grid-cols-\[14rem_1fr\]{grid-template-columns:14rem 1fr}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:justify-between{justify-content:space-between}:where(.md\:space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.md\:self-auto{align-self:auto}.md\:self-start{align-self:flex-start}.md\:p-6{padding:calc(var(--spacing) * 6)}.md\:px-4{padding-inline:calc(var(--spacing) * 4)}.md\:px-6{padding-inline:calc(var(--spacing) * 6)}.md\:py-3{padding-block:calc(var(--spacing) * 3)}.md\:py-8{padding-block:calc(var(--spacing) * 8)}.md\:py-10{padding-block:calc(var(--spacing) * 10)}.md\:py-12{padding-block:calc(var(--spacing) * 12)}.md\:pb-0{padding-bottom:calc(var(--spacing) * 0)}.md\:text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}}@media(min-width:64rem){.lg\:sticky{position:sticky}.lg\:top-24{top:calc(var(--spacing) * 24)}.lg\:block{display:block}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-\[minmax\(0\,1fr\)_18rem\]{grid-template-columns:minmax(0,1fr) 18rem}.lg\:self-start{align-self:flex-start}.lg\:px-6{padding-inline:calc(var(--spacing) * 6)}.lg\:py-5{padding-block:calc(var(--spacing) * 5)}.lg\:text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}}@media(prefers-color-scheme:dark){.dark\:text-amber-300{color:var(--color-amber-300)}}}pre code.hljs{padding:1em;display:block;overflow-x:auto}code.hljs{padding:3px 5px}.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:#005cc5}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-comment,.hljs-code,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}:root[data-text-size=larger]{--font-size-prose:22px;--font-size-editor:18px;font-size:18px}:root[data-text-size=largest]{--font-size-prose:26px;--font-size-editor:22px;font-size:22px}@media(prefers-color-scheme:dark){:root:not([data-theme=light]){--color-bg:#1a1917;--color-bg-soft:#23221f;--color-fg:#e8e5de;--color-fg-muted:#a8a49b;--color-fg-dim:#706c64;--color-accent:#7ab087;--color-accent-hover:#8bc098;--color-accent-light:#5b8c6a;--color-sky:#7fb3cc;--color-border:#33312d;--color-border-light:#2a2926;--color-card:#23221f;--color-card-hover:#2a2926}}:root[data-theme=dark]{--color-bg:#1a1917;--color-bg-soft:#23221f;--color-fg:#e8e5de;--color-fg-muted:#a8a49b;--color-fg-dim:#706c64;--color-accent:#7ab087;--color-accent-hover:#8bc098;--color-accent-light:#5b8c6a;--color-sky:#7fb3cc;--color-border:#33312d;--color-border-light:#2a2926;--color-card:#23221f;--color-card-hover:#2a2926}html,body{font-family:var(--font-sans);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;line-height:1.65}body{padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right);padding-bottom:env(safe-area-inset-bottom)}.prose-note{color:var(--color-fg);font-size:var(--font-size-prose);line-height:1.7}.prose-note h1,.prose-note h2,.prose-note h3,.prose-note h4{font-family:var(--font-serif);color:var(--color-fg);letter-spacing:-.015em;margin-top:1.75em;margin-bottom:.5em;line-height:1.25}.prose-note h1{font-size:1.875rem}.prose-note h2{font-size:1.5rem}.prose-note h3{font-size:1.25rem}.prose-note h4{font-size:1.1rem}.prose-note p{margin:.75em 0}.prose-note ul,.prose-note ol{margin:.75em 0;padding-left:1.5rem}.prose-note ul{list-style:outside}.prose-note ol{list-style:decimal}.prose-note li,.prose-note li>p{margin:.25em 0}.prose-note blockquote{border-left:3px solid var(--color-border);color:var(--color-fg-muted);margin:1em 0;padding-left:1rem;font-style:italic}.prose-note code{font-family:var(--font-mono);background:var(--color-bg-soft);border-radius:3px;padding:.1em .35em;font-size:.875em}.prose-note pre{background:var(--color-bg-soft);border:1px solid var(--color-border);border-radius:6px;margin:1em 0;padding:.9rem 1rem;font-size:.875em;line-height:1.5;overflow-x:auto}.prose-note pre code{font-size:inherit;background:0 0;border-radius:0;padding:0}.prose-note table{border-collapse:collapse;width:100%;margin:1em 0;font-size:.9em}.prose-note th,.prose-note td{border:1px solid var(--color-border);text-align:left;padding:.5rem .75rem}.prose-note th{background:var(--color-bg-soft);font-weight:500}.prose-note hr{border:0;border-top:1px solid var(--color-border);margin:1.5em 0}.prose-note img{border-radius:6px;max-width:100%;height:auto}.prose-note input[type=checkbox]{margin-right:.4em}@media(prefers-color-scheme:dark){:root:not([data-theme=light]) .prose-note code,:root:not([data-theme=light]) .prose-note pre{border-color:var(--color-border);background:#1f1e1b}:root:not([data-theme=light]) .prose-note .hljs{color:var(--color-fg);background:#1f1e1b!important}}:root[data-theme=dark] .prose-note code,:root[data-theme=dark] .prose-note pre{border-color:var(--color-border);background:#1f1e1b}:root[data-theme=dark] .prose-note .hljs{color:var(--color-fg);background:#1f1e1b!important}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}
import{x as d,r as e,a7 as D,J as V,V as C,g as _,Y as z,aa as O,U as Y,N as K,L as R,Q as W,a8 as q,f as H,z as T,e as J,u as Q}from"./index-BDPMEkxL.js";import{u as Z,A as G,C as X,a as ee,b as te}from"./useAttachmentUploader-CRSqlwYK.js";import{P as se,D as ne}from"./PinArchiveButtons-DogtDLiB.js";import{b as re,N as ae}from"./NoteRenderer-cz03kLyS.js";const oe=250;function de({noteId:t,attachment:n}){const[l,a]=d.useState(!1),o=ce(n);return e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",onClick:()=>a(!0),"aria-label":`Remove attachment ${o}`,className:"shrink-0 rounded border border-transparent px-1.5 py-0.5 text-fg-dim hover:border-red-500/40 hover:text-red-400",children:"✕"}),l?e.jsx(ie,{noteId:t,attachment:n,label:o,onClose:()=>a(!1)}):null]})}function ie({noteId:t,attachment:n,label:l,onClose:a}){const o=D(i=>i.push),m=V(),[s,h]=d.useState(!1),[w,p]=d.useState(null),N=d.useRef(null);d.useEffect(()=>{const i=setTimeout(()=>h(!0),oe);return()=>clearTimeout(i)},[]),d.useEffect(()=>{var i;(i=N.current)==null||i.focus()},[]),d.useEffect(()=>{const i=g=>{g.key==="Escape"&&a()};return window.addEventListener("keydown",i),()=>window.removeEventListener("keydown",i)},[a]);const b=d.useCallback(()=>{!s||m.isPending||(p(null),m.mutate({noteId:t,attachmentId:n.id},{onSuccess:()=>{o(`Removed ${l}`,"success"),a()},onError:i=>{if(i instanceof C){p("Session expired. Reconnect to remove attachments.");return}if(i instanceof _){o(`Already removed ${l}`,"info"),a();return}p(i instanceof Error?i.message:"Remove failed")}}))},[s,n.id,l,m,t,a,o]);return e.jsx("dialog",{open:!0,"aria-labelledby":"confirm-remove-attachment-title",className:"fixed inset-0 z-40 m-0 flex h-full max-h-full w-full max-w-full items-center justify-center bg-black/60 p-4",onMouseDown:i=>{i.target===i.currentTarget&&a()},children:e.jsxs("div",{className:"w-full max-w-md rounded-md border border-border bg-card p-6 shadow-xl",children:[e.jsx("h2",{id:"confirm-remove-attachment-title",className:"mb-2 font-serif text-lg text-red-400",children:"Remove attachment?"}),e.jsxs("p",{className:"mb-3 text-sm text-fg-muted",children:[e.jsx("span",{className:"rounded bg-bg/60 px-1 py-0.5 font-mono text-xs text-fg",children:l})," ","will be detached from this note. If no other note references the file, it will also be deleted from storage. Markdown referencing it will show a broken link until you update it."]}),w?e.jsx("p",{role:"alert",className:"mb-3 text-sm text-red-400",children:w}):null,e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{ref:N,type:"button",onClick:a,className:"min-h-11 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg-muted hover:text-fg",children:"Cancel"}),e.jsx("button",{type:"button",onClick:b,disabled:!s||m.isPending,className:"min-h-11 rounded-md bg-red-500 px-4 py-1.5 text-sm font-medium text-white hover:bg-red-600 disabled:opacity-40",children:m.isPending?"Removing…":"Remove"})]})]})})}function ce(t){if(t.filename)return t.filename;if(t.path){const n=t.path.split("/").pop();return n||t.path}return t.id}function we(){const{id:t}=z(),n=t?decodeURIComponent(t):void 0,l=O(o=>o.getActiveVault()),a=Y(n);return l?e.jsxs("div",{className:"mx-auto max-w-6xl px-4 py-5 md:px-6 md:py-8",children:[e.jsx("nav",{className:"mb-4 text-sm text-fg-dim",children:e.jsx(R,{to:n?`/n/${encodeURIComponent(n)}`:"/",className:"hover:text-accent",children:"← Back to note"})}),a.isPending?e.jsx(xe,{}):a.isError?e.jsx(fe,{error:a.error}):a.data?e.jsx(le,{note:a.data}):e.jsx(he,{id:n??""})]}):e.jsx(K,{to:"/",replace:!0})}function S(t){return{content:t.content??"",path:t.path??"",tags:[...t.tags??[]]}}function le({note:t}){const n=W(),l=D(r=>r.push),a=d.useMemo(()=>re(t),[t]),[o,m]=d.useState(()=>S(t)),[s,h]=d.useState(()=>S(t)),[w,p]=d.useState(""),[N,b]=d.useState(null),[i,g]=d.useState(null),[y,L]=d.useState("edit"),v=q(t.id),k=d.useRef(t),E=d.useRef(null),j=Z({noteId:t.id,onInsert:r=>{E.current?E.current.insertAtCursor(r):h(c=>({...c,content:`${c.content}${r}`}))},onLinked:()=>{l("Attachment added","success")},onError:r=>l(r,"error")});d.useEffect(()=>{k.current=t},[t]);const u=s.content!==o.content||s.path!==o.path||!pe(s.tags,o.tags),A=d.useCallback(()=>{if(!u||v.isPending)return;const r={};s.content!==o.content&&(r.content=s.content),s.path!==o.path&&(r.path=s.path);const c=be(o.tags,s.tags);(c.add.length||c.remove.length)&&(r.tags=c);const f=k.current.updatedAt??k.current.createdAt;f&&(r.if_updated_at=f),g(null),b(null),v.mutate(r,{onSuccess:x=>{m(S(x)),h(S(x)),k.current=x,x.id!==t.id&&n(`/n/${encodeURIComponent(x.id)}/edit`,{replace:!0})},onError:x=>{x instanceof H?b(x):x instanceof C?g("Session expired. Reconnect to save."):g(x instanceof Error?x.message:"Save failed")}})},[o,s,u,v,n,t.id]),U=d.useCallback(()=>{u&&confirm("Discard all edits and revert to last saved version?")&&(h(o),b(null),g(null))},[o,u]),P=d.useCallback(()=>{u&&!confirm("Discard unsaved changes?")||n(`/n/${encodeURIComponent(t.id)}`)},[u,n,t.id]);d.useEffect(()=>{if(!u)return;const r=c=>{c.preventDefault(),c.returnValue=""};return window.addEventListener("beforeunload",r),()=>window.removeEventListener("beforeunload",r)},[u]);const $=s.path!==o.path,B=r=>{const c=Q(r);c&&(s.tags.includes(c)||(h(f=>({...f,tags:[...f.tags,c]})),p("")))},F=r=>{h(c=>({...c,tags:c.tags.filter(f=>f!==r)}))},M=s.content;return e.jsxs("article",{children:[e.jsxs("header",{className:"mb-4 border-b border-border pb-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx("span",{className:"text-xs uppercase tracking-wider text-fg-dim",children:"Editing"}),u?e.jsxs("span",{className:"inline-flex items-center gap-1 text-xs text-accent","aria-label":"unsaved changes",children:[e.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-accent"}),"unsaved"]}):e.jsxs("span",{className:"text-xs text-fg-dim",children:["saved ",T(t.updatedAt)]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(se,{note:t}),e.jsx(ne,{note:t}),e.jsx("span",{className:"mx-1 h-5 w-px bg-border","aria-hidden":"true"}),e.jsx("button",{type:"button",onClick:U,disabled:!u||v.isPending,className:"min-h-11 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg-muted hover:text-accent disabled:opacity-40",children:"Revert"}),e.jsx("button",{type:"button",onClick:P,className:"min-h-11 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg-muted hover:text-accent",children:"Cancel"}),e.jsx("button",{type:"button",onClick:A,disabled:!u||v.isPending,className:"min-h-11 rounded-md bg-accent px-4 py-1.5 text-sm font-medium text-white hover:bg-accent-hover disabled:opacity-40",title:"Save (⌘S)",children:v.isPending?"Saving…":"Save"})]})]}),e.jsxs("div",{className:"mt-3 flex flex-col gap-2",children:[e.jsx(J,{tags:s.tags,input:w,onInputChange:p,onAdd:B,onRemove:F}),e.jsxs("label",{className:"flex items-baseline gap-3 text-sm",children:[e.jsx("span",{className:"shrink-0 text-xs uppercase tracking-wider text-fg-dim",children:"Path"}),e.jsx("input",{type:"text",value:s.path,onChange:r=>h(c=>({...c,path:r.target.value})),className:"flex-1 rounded-md border border-border bg-card px-2.5 py-1 font-mono text-sm text-fg focus:border-accent focus:outline-none","aria-label":"Note path",placeholder:"(no path)"})]}),$?e.jsx("p",{className:"text-xs text-accent",children:"Renaming moves the note — its id may change."}):null]})]}),N?e.jsx(ue,{conflict:N,onReload:()=>{window.location.reload()},onDismiss:()=>b(null)}):null,i?e.jsx("div",{className:"mb-4 rounded-md border border-red-500/30 bg-red-500/5 p-3 text-sm text-red-400",children:i}):null,e.jsx("div",{role:"tablist","aria-label":"Editor view",className:"mb-3 inline-flex rounded-md border border-border bg-card p-0.5 text-sm lg:hidden",children:["edit","preview"].map(r=>e.jsx("button",{type:"button",role:"tab","aria-selected":y===r,onClick:()=>L(r),className:`rounded px-3 py-1.5 capitalize ${y===r?"bg-accent text-white":"text-fg-muted hover:text-accent"}`,children:r},r))}),e.jsxs("div",{className:"grid min-h-[60vh] gap-4 lg:grid-cols-2",children:[e.jsx(G,{onDropFiles:j.start,className:`min-w-0 rounded-md border border-border bg-card ${y==="edit"?"":"hidden lg:block"}`,hint:I,children:e.jsx(X,{ref:E,value:s.content,onChange:r=>h(c=>({...c,content:r})),onSave:A,onCancel:P,onPasteFile:r=>(j.start(r),!0)})}),e.jsx("div",{className:`min-w-0 overflow-auto rounded-md border border-border bg-card p-4 ${y==="preview"?"":"hidden lg:block"}`,children:e.jsx(ae,{note:{path:s.path,content:M},resolve:a})})]}),e.jsx(me,{noteId:t.id,attachments:t.attachments??[],uploads:j.uploads,onPickFiles:j.start,onCancel:j.cancel,onDismiss:j.dismiss})]})}const I=e.jsxs(e.Fragment,{children:["Images, audio, webm video."," ",e.jsx("a",{href:"https://github.com/ParachuteComputer/parachute-vault/issues/127",target:"_blank",rel:"noreferrer",className:"underline",children:"PDF + mp4 coming"})]});function me({noteId:t,attachments:n,uploads:l,onPickFiles:a,onCancel:o,onDismiss:m}){return e.jsxs("section",{className:"mt-6 border-t border-border pt-4",children:[e.jsxs("div",{className:"mb-3 flex items-center justify-between",children:[e.jsx("h2",{className:"font-serif text-lg",children:"Attachments"}),e.jsx(ee,{onPickFiles:a})]}),e.jsxs("p",{className:"mb-3 text-xs text-fg-dim",children:["Drop or paste files into the editor. Max 100 MB each. ",I,"."]}),e.jsx(te,{uploads:l,onCancel:o,onDismiss:m}),n.length>0?e.jsx("ul",{className:"mt-3 space-y-1 text-sm",children:n.map(s=>e.jsxs("li",{className:"flex items-center justify-between gap-2 rounded border border-border bg-card/50 px-3 py-1.5 font-mono text-xs",children:[e.jsx("span",{className:"truncate",title:s.path??s.id,children:s.filename??s.path??s.id}),e.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[s.mimeType?e.jsx("span",{className:"text-fg-dim",children:s.mimeType}):null,e.jsx(de,{noteId:t,attachment:s})]})]},s.id))}):null]})}function ue({conflict:t,onReload:n,onDismiss:l}){return e.jsxs("div",{className:"mb-4 rounded-md border border-amber-500/40 bg-amber-500/10 p-4",children:[e.jsx("p",{className:"mb-1 font-medium text-amber-500",children:"This note was edited elsewhere."}),e.jsxs("p",{className:"mb-3 text-sm text-fg-muted",children:["Your save was rejected to avoid overwriting the other edit.",t.currentUpdatedAt?` Latest update ${T(t.currentUpdatedAt)}.`:""]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx("button",{type:"button",onClick:n,className:"rounded-md bg-accent px-3 py-1.5 text-sm font-medium text-white hover:bg-accent-hover",children:"Reload latest (discard my edits)"}),e.jsx("button",{type:"button",onClick:l,className:"rounded-md border border-border px-3 py-1.5 text-sm text-fg-muted hover:text-fg",children:"Keep editing"})]})]})}function xe(){return e.jsxs("div",{className:"grid min-h-[60vh] gap-4 lg:grid-cols-2","aria-busy":"true",children:[e.jsx("div",{className:"animate-pulse rounded-md border border-border bg-card"}),e.jsx("div",{className:"animate-pulse rounded-md border border-border bg-card"})]})}function he({id:t}){return e.jsxs("div",{className:"rounded-md border border-border bg-card p-10 text-center",children:[e.jsx("p",{className:"mb-2 font-serif text-xl",children:"Note not found"}),e.jsxs("p",{className:"mb-4 text-sm text-fg-muted",children:["No note with id ",e.jsx("span",{className:"font-mono",children:t})," in this vault."]}),e.jsx(R,{to:"/",className:"text-sm text-accent hover:underline",children:"Back to all notes"})]})}function fe({error:t}){const n=t instanceof C;return e.jsxs("div",{className:"rounded-md border border-red-500/30 bg-red-500/5 p-6",children:[e.jsx("p",{className:"mb-2 font-medium text-red-400",children:n?"Session expired":"Could not load note"}),e.jsx("p",{className:"mb-4 text-sm text-fg-muted",children:t.message}),n?e.jsx(R,{to:"/add",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Reconnect vault"}):null]})}function pe(t,n){if(t.length!==n.length)return!1;const l=new Set(t);for(const a of n)if(!l.has(a))return!1;return!0}function be(t,n){const l=new Set(t),a=new Set(n),o=n.filter(s=>!l.has(s)),m=t.filter(s=>!a.has(s));return{add:o,remove:m}}export{we as NoteEditor};
import{aa as P,Q as T,a7 as I,H as R,M as L,x as n,r as e,N as V,V as $,L as F,e as M,u as _}from"./index-BDPMEkxL.js";import{u as U,A as B,C as z,a as H,b as O}from"./useAttachmentUploader-CRSqlwYK.js";import{b as Q,N as W}from"./NoteRenderer-cz03kLyS.js";const Y={content:"",path:"",tags:[],summary:""};function J(){const w=P(t=>t.getActiveVault()),l=T(),d=I(t=>t.push),c=R(),f=L(),[a,o]=n.useState(Y),[C,b]=n.useState(""),[v,x]=n.useState(null),[m,k]=n.useState([]),p=n.useRef(null),i=U({noteId:null,onInsert:t=>{p.current?p.current.insertAtCursor(t):o(s=>({...s,content:`${s.content}${t}`}))},onStaged:t=>k(s=>[...s,t]),onError:t=>d(t,"error")});if(!w)return e.jsx(V,{to:"/",replace:!0});const u=a.content.length>0||a.path.length>0||a.tags.length>0||a.summary.length>0,h=a.content.trim().length>0&&a.path.trim().length>0,j=n.useCallback(()=>{if(!h||c.isPending)return;const t={content:a.content,path:a.path.trim()};a.tags.length&&(t.tags=a.tags);const s=a.summary.trim();s&&(t.metadata={summary:s}),x(null),c.mutate(t,{onSuccess:async r=>{for(const g of m)try{await f.mutateAsync({noteId:r.id,path:g.path,mimeType:g.mimeType})}catch(y){const D=y instanceof Error?y.message:"Link failed";d(`Failed to attach ${g.filename}: ${D}`,"error")}d(`Created ${r.path??r.id}`,"success"),l(`/n/${encodeURIComponent(r.id)}`)},onError:r=>{r instanceof $?x("Session expired. Reconnect to save."):x(r instanceof Error?`${r.message} — if the path is taken, try a different one.`:"Create failed")}})},[a,h,f,c,l,d,m]),N=n.useCallback(()=>{u&&!confirm("Discard this draft?")||l("/")},[u,l]);n.useEffect(()=>{if(!u)return;const t=s=>{s.preventDefault(),s.returnValue=""};return window.addEventListener("beforeunload",t),()=>window.removeEventListener("beforeunload",t)},[u]);const A=t=>{const s=_(t);!s||a.tags.includes(s)||(o(r=>({...r,tags:[...r.tags,s]})),b(""))},E=t=>{o(s=>({...s,tags:s.tags.filter(r=>r!==t)}))},S=Q({id:"__new__",createdAt:new Date().toISOString()});return e.jsxs("div",{className:"mx-auto max-w-6xl px-4 py-5 md:px-6 md:py-8",children:[e.jsx("nav",{className:"mb-4 text-sm text-fg-dim",children:e.jsx(F,{to:"/",className:"hover:text-accent",children:"← All notes"})}),e.jsxs("article",{children:[e.jsxs("header",{className:"mb-4 border-b border-border pb-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsx("div",{className:"flex items-center gap-2 text-sm",children:e.jsx("span",{className:"text-xs uppercase tracking-wider text-fg-dim",children:"New note"})}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{type:"button",onClick:N,className:"min-h-11 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg-muted hover:text-accent",children:"Cancel"}),e.jsx("button",{type:"button",onClick:j,disabled:!h||c.isPending,className:"min-h-11 rounded-md bg-accent px-4 py-1.5 text-sm font-medium text-white hover:bg-accent-hover disabled:opacity-40",title:"Create (⌘S)",children:c.isPending?"Creating…":"Create"})]})]}),e.jsxs("div",{className:"mt-3 flex flex-col gap-2",children:[e.jsxs("label",{className:"flex items-baseline gap-3 text-sm",children:[e.jsx("span",{className:"shrink-0 text-xs uppercase tracking-wider text-fg-dim",children:"Path"}),e.jsx("input",{type:"text",value:a.path,onChange:t=>o(s=>({...s,path:t.target.value})),className:"flex-1 rounded-md border border-border bg-card px-2.5 py-1 font-mono text-sm text-fg focus:border-accent focus:outline-none","aria-label":"Note path",placeholder:"e.g. Projects/README"})]}),e.jsxs("label",{className:"flex items-baseline gap-3 text-sm",children:[e.jsx("span",{className:"shrink-0 text-xs uppercase tracking-wider text-fg-dim",children:"Summary"}),e.jsx("input",{type:"text",value:a.summary,onChange:t=>o(s=>({...s,summary:t.target.value})),className:"flex-1 rounded-md border border-border bg-card px-2.5 py-1 text-sm text-fg focus:border-accent focus:outline-none","aria-label":"Note summary",placeholder:"(optional one-line description)"})]}),e.jsx(M,{tags:a.tags,input:C,onInputChange:b,onAdd:A,onRemove:E})]})]}),v?e.jsx("div",{role:"alert",className:"mb-4 rounded-md border border-red-500/30 bg-red-500/5 p-3 text-sm text-red-400",children:v}):null,e.jsxs("div",{className:"grid min-h-[60vh] gap-4 lg:grid-cols-2",children:[e.jsx(B,{onDropFiles:i.start,className:"min-w-0 rounded-md border border-border bg-card",hint:"Images, audio, webm video",children:e.jsx(z,{ref:p,value:a.content,onChange:t=>o(s=>({...s,content:t})),onSave:j,onCancel:N,onPasteFile:t=>(i.start(t),!0)})}),e.jsx("div",{className:"min-w-0 overflow-auto rounded-md border border-border bg-card p-4",children:a.content.trim()?e.jsx(W,{note:{path:a.path,content:a.content},resolve:S}):e.jsx("p",{className:"text-sm text-fg-dim",children:"Preview appears here as you type."})})]}),e.jsxs("section",{className:"mt-6 border-t border-border pt-4",children:[e.jsxs("div",{className:"mb-3 flex items-center justify-between",children:[e.jsx("h2",{className:"font-serif text-lg",children:"Attachments"}),e.jsx(H,{onPickFiles:i.start})]}),e.jsxs("p",{className:"mb-3 text-xs text-fg-dim",children:["Drop or paste files into the editor. Attachments link to the note when you save. Max 100 MB each. Images, audio, webm video."," ",e.jsx("a",{href:"https://github.com/ParachuteComputer/parachute-vault/issues/127",target:"_blank",rel:"noreferrer",className:"underline",children:"PDF + mp4 coming"}),"."]}),e.jsx(O,{uploads:i.uploads,onCancel:i.cancel,onDismiss:i.dismiss}),m.length>0?e.jsx("ul",{className:"mt-3 space-y-1 text-sm",children:m.map(t=>e.jsxs("li",{className:"flex items-center justify-between gap-2 rounded border border-border bg-card/50 px-3 py-1.5 font-mono text-xs text-fg-muted",children:[e.jsx("span",{className:"truncate",children:t.filename}),e.jsx("span",{className:"shrink-0 text-fg-dim",children:"staged"})]},t.path))}):null]})]})]})}export{J as NoteNew};

Sorry, the diff of this file is too big to display

const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/react-force-graph-2d-CokIfB0T.js","assets/index-BDPMEkxL.js","assets/index-D_L2igjK.css"])))=>i.map(i=>d[i]);
import{x as c,E as v,r as t,Q as k,_ as y,Y as I,aa as R,U as A,w as E,N as C,L as p,V as L,z as j}from"./index-BDPMEkxL.js";import{P as _,D}from"./PinArchiveButtons-DogtDLiB.js";import{b as T,N as U}from"./NoteRenderer-cz03kLyS.js";const M=1,S=3,$=1;function B(e,s){const a=new Map,n=new Map;for(const d of s.values())for(const r of d.links??[]){if(r.sourceId===r.targetId||!s.has(r.sourceId)||!s.has(r.targetId))continue;const o=`${r.sourceId}|${r.targetId}|${r.relationship}`;a.has(o)||(a.set(o,{source:r.sourceId,target:r.targetId,relationship:r.relationship}),n.set(r.sourceId,(n.get(r.sourceId)??0)+1),n.set(r.targetId,(n.get(r.targetId)??0)+1))}return{nodes:[...s.values()].map(d=>{var r;return{id:d.id,path:d.path,tags:d.tags,summary:typeof((r=d.metadata)==null?void 0:r.summary)=="string"?d.metadata.summary:void 0,isAnchor:d.id===e,linkCount:n.get(d.id)??0}}),edges:[...a.values()]}}async function P(e,s,a,n){const i=new Map;i.set(e.id,e);let d=[e];for(let r=1;r<=s;r++){const o=new Set;for(const u of d)for(const x of u.links??[]){const h=x.sourceId===u.id?x.targetId:x.sourceId;h!==u.id&&(i.has(h)||o.add(h))}if(o.size===0)break;const l=await Promise.all([...o].map(u=>a(u).catch(()=>null)));if(n!=null&&n.cancelled)return i;const m=[];for(const u of l)u&&!i.has(u.id)&&(i.set(u.id,u),m.push(u));d=m}return i}function V(e,s,a){const[n,i]=c.useState(null),[d,r]=c.useState(!1);return c.useEffect(()=>{if(!e||!s){i(null),r(!1);return}const o={cancelled:!1};return r(!0),P(s,a,l=>e.getNote(l,{includeLinks:!0}),o).then(l=>{o.cancelled||(i(B(s.id,l)),r(!1))}).catch(()=>{o.cancelled||r(!1)}),()=>{o.cancelled=!0}},[e,s,a]),{data:n,isLoading:d}}const F=c.lazy(()=>y(()=>import("./react-force-graph-2d-CokIfB0T.js"),__vite__mapDeps([0,1,2])));function z({anchor:e}){const[s,a]=c.useState(!0),[n,i]=c.useState($),d=v(),{data:r,isLoading:o}=V(d,s?e:void 0,n);return t.jsxs("section",{className:"mt-10 border-t border-border pt-6",children:[t.jsxs("header",{className:"mb-4 flex flex-wrap items-center justify-between gap-3",children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsxs("button",{type:"button",onClick:()=>a(l=>!l),"aria-expanded":s,className:"font-serif text-xl text-fg hover:text-accent",children:[s?"▾":"▸"," Neighborhood"]}),s&&r?t.jsxs("span",{className:"text-xs text-fg-dim",children:[r.nodes.length," ",r.nodes.length===1?"note":"notes"]}):null]}),s?t.jsx(G,{depth:n,onChange:i}):null]}),s?t.jsx(O,{data:r,isLoading:o}):null]})}function G({depth:e,onChange:s}){const a=[];for(let n=M;n<=S;n++)a.push(n);return t.jsxs("fieldset",{className:"flex items-center gap-1 text-xs text-fg-dim",children:[t.jsx("legend",{className:"mr-1 inline-block",children:"Hops"}),a.map(n=>t.jsx("button",{type:"button","aria-pressed":n===e,onClick:()=>s(n),className:n===e?"rounded border border-accent bg-accent/10 px-2 py-0.5 text-accent":"rounded border border-border bg-card px-2 py-0.5 hover:text-accent",children:n},n))]})}function O({data:e,isLoading:s}){return!e&&s?t.jsx(w,{}):e?e.nodes.length<=1?t.jsx("div",{className:"rounded-md border border-border bg-card p-6 text-center text-sm text-fg-dim",children:"This note has no neighbors yet."}):t.jsx(H,{data:e}):null}function w(){return t.jsx("div",{"aria-busy":"true",className:"h-[24rem] w-full animate-pulse rounded-md border border-border bg-card"})}function H({data:e}){const s=k(),a=c.useRef(null),[n,i]=c.useState({w:600,h:384});c.useEffect(()=>{const r=a.current;if(!r)return;const o=()=>{const m=r.getBoundingClientRect();i({w:Math.max(320,Math.floor(m.width)),h:384})};o();const l=new ResizeObserver(o);return l.observe(r),()=>l.disconnect()},[]);const d=c.useMemo(()=>({nodes:e.nodes.map(r=>({...r})),links:e.edges.map(r=>({source:r.source,target:r.target,rel:r.relationship}))}),[e]);return t.jsx("div",{ref:a,"data-testid":"neighborhood-graph-canvas",className:"overflow-hidden rounded-md border border-border bg-card",children:t.jsx(c.Suspense,{fallback:t.jsx(w,{}),children:t.jsx(F,{graphData:d,width:n.w,height:n.h,nodeLabel:r=>K(r),nodeVal:r=>{const o=r;return o.isAnchor?8:3+Math.min(o.linkCount,8)},nodeColor:r=>r.isAnchor?"#c9b170":"#8a9a7a",linkColor:()=>"rgba(160, 160, 160, 0.4)",linkDirectionalArrowLength:3,linkDirectionalArrowRelPos:1,cooldownTicks:80,onNodeClick:r=>{s(`/n/${encodeURIComponent(r.id)}`)}})})})}function K(e){const s=[e.path??e.id];return e.tags&&e.tags.length>0&&s.push(`tags: ${e.tags.join(", ")}`),e.summary&&s.push(e.summary),s.join(`
`)}const W="_Transcript pending._",Q="_Transcription unavailable._";function X({content:e}){const s=e.includes(W),a=!s&&e.includes(Q);return s?t.jsxs("output",{"aria-live":"polite",className:"mb-4 inline-flex items-center gap-2 rounded-md border border-sky-500/30 bg-sky-500/5 px-3 py-1.5 text-xs text-sky-300",children:[t.jsx("span",{"aria-hidden":!0,className:"inline-block h-2 w-2 animate-pulse rounded-full bg-sky-400"}),"Transcribing…"]}):a?t.jsx("output",{className:"mb-4 inline-flex items-center gap-2 rounded-md border border-amber-500/30 bg-amber-500/5 px-3 py-1.5 text-xs text-amber-200",children:"Transcription unavailable — open the audio below and add a note by hand."}):null}function ce(){const{id:e}=I(),s=e?decodeURIComponent(e):void 0,a=R(i=>i.getActiveVault()),n=A(s);return c.useEffect(()=>{a&&s&&E(a.id,s)},[a,s]),a?t.jsxs("div",{className:"mx-auto max-w-6xl px-4 py-6 md:px-6 md:py-10",children:[t.jsx("nav",{className:"mb-6 text-sm text-fg-dim",children:t.jsx(p,{to:"/",className:"hover:text-accent",children:"← All notes"})}),n.isPending?t.jsx(ne,{}):n.isError?t.jsx(oe,{error:n.error}):n.data?t.jsx(Y,{note:n.data}):t.jsx(ae,{id:s??""})]}):t.jsx(C,{to:"/",replace:!0})}function Y({note:e}){var r;const s=c.useMemo(()=>T(e),[e]),a=e.path??e.id,n=typeof((r=e.metadata)==null?void 0:r.summary)=="string"?e.metadata.summary:null,i=c.useMemo(()=>(e.links??[]).filter(o=>o.targetId===e.id&&o.sourceId!==e.id&&o.sourceNote),[e]),d=c.useMemo(()=>{const o=new Set,l=[];for(const m of e.links??[])m.sourceId!==e.id||m.targetId===e.id||m.targetNote&&(o.has(m.targetId)||(o.add(m.targetId),l.push(m)));return l},[e]);return t.jsxs("article",{className:"grid gap-10 lg:grid-cols-[minmax(0,1fr)_18rem]",children:[t.jsxs("div",{className:"min-w-0",children:[t.jsxs("header",{className:"mb-6 border-b border-border pb-4",children:[t.jsx("h1",{className:"font-serif text-3xl tracking-tight",children:e.path?q(e.path):e.id}),e.tags&&e.tags.length>0?t.jsx(Z,{tags:e.tags}):null,t.jsx("p",{className:"mt-2 font-mono text-xs text-fg-dim break-all",children:a}),n?t.jsx("p",{className:"mt-3 text-fg-muted",children:n}):null,t.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-2",children:[t.jsx(p,{to:`/n/${encodeURIComponent(e.id)}/edit`,className:"min-h-11 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg-muted hover:text-accent",children:"Edit"}),t.jsx(_,{note:e,keyboard:!0}),t.jsx(D,{note:e})]})]}),t.jsx(X,{content:e.content??""}),t.jsx(U,{note:e,resolve:s}),e.attachments&&e.attachments.length>0?t.jsxs("section",{className:"mt-10 border-t border-border pt-6",children:[t.jsx("h2",{className:"mb-3 font-serif text-xl",children:"Attachments"}),t.jsx("div",{className:"space-y-6",children:e.attachments.map(o=>t.jsx(ee,{attachment:o},o.id))})]}):null,t.jsx(z,{anchor:e})]}),t.jsxs("aside",{className:"space-y-6 text-sm lg:sticky lg:top-24 lg:self-start",children:[t.jsx(J,{note:e}),d.length>0?t.jsx(N,{title:"Outbound",links:d,peer:"target"}):null,i.length>0?t.jsx(N,{title:"Inbound",links:i,peer:"source"}):null]})]})}function q(e){return(e.split("/").pop()??e).replace(/\.md$/i,"")}function J({note:e}){const s=e.createdAt,a=e.updatedAt,n=Object.entries(e.metadata??{}).filter(([i])=>i!=="summary");return t.jsxs("section",{className:"rounded-md border border-border bg-card p-4",children:[t.jsx("h2",{className:"mb-2 text-xs uppercase tracking-wider text-fg-dim",children:"Metadata"}),t.jsxs("dl",{className:"space-y-1.5 text-sm",children:[e.path?t.jsx(f,{label:"Path",value:t.jsx("span",{className:"font-mono text-xs break-all",children:e.path})}):null,t.jsx(f,{label:"ID",value:t.jsx("span",{className:"font-mono text-xs break-all",children:e.id})}),t.jsx(f,{label:"Created",value:t.jsx("time",{title:s,children:j(s)})}),a?t.jsx(f,{label:"Updated",value:t.jsx("time",{title:a,children:j(a)})}):null,n.map(([i,d])=>t.jsx(f,{label:i,value:t.jsx("span",{className:"break-all text-fg-muted",children:String(d)})},i))]})]})}function f({label:e,value:s}){return t.jsxs("div",{className:"flex flex-col gap-0.5",children:[t.jsx("dt",{className:"text-xs uppercase tracking-wider text-fg-dim",children:e}),t.jsx("dd",{children:s})]})}function Z({tags:e}){return t.jsx("div",{className:"mt-3 flex flex-wrap gap-1.5","aria-label":"Tags",children:e.map(s=>t.jsxs(p,{to:`/?tag=${encodeURIComponent(s)}`,className:"max-w-full break-all rounded-full border border-accent/40 bg-accent/10 px-2.5 py-0.5 text-xs font-medium text-accent hover:border-accent hover:bg-accent/20",children:["#",s]},s))})}function N({title:e,links:s,peer:a}){return t.jsxs("section",{className:"rounded-md border border-border bg-card p-4",children:[t.jsxs("h2",{className:"mb-2 text-xs uppercase tracking-wider text-fg-dim",children:[e," (",s.length,")"]}),t.jsx("ul",{className:"space-y-1.5",children:s.map(n=>{var o;const i=a==="source"?n.sourceNote:n.targetNote;if(!i)return null;const d=i.path??i.id,r=typeof((o=i.metadata)==null?void 0:o.summary)=="string"?i.metadata.summary:null;return t.jsx("li",{children:t.jsxs(p,{to:`/n/${encodeURIComponent(i.id)}`,className:"block rounded px-1 py-0.5 hover:bg-bg/50",children:[t.jsx("div",{className:"truncate font-mono text-xs text-fg-muted hover:text-accent",children:d}),r?t.jsx("div",{className:"mt-0.5 line-clamp-2 text-xs text-fg-dim",children:r}):null]})},`${n.sourceId}->${n.targetId}:${n.relationship}`)})})]})}function ee({attachment:e}){const s=(e.mimeType??"").toLowerCase(),a=e.filename??e.id;return t.jsxs("figure",{className:"rounded-md border border-border bg-card p-3",children:[t.jsxs("figcaption",{className:"mb-2 flex items-baseline justify-between gap-3",children:[t.jsx("span",{className:"truncate font-mono text-xs text-fg-muted",children:a}),typeof e.size=="number"?t.jsx("span",{className:"shrink-0 text-xs text-fg-dim",children:re(e.size)}):null]}),t.jsx(te,{attachment:e,mime:s,filename:a})]})}function te({attachment:e,mime:s,filename:a}){const n=v(),[i,d]=c.useState(null),[r,o]=c.useState(null),l=se(s,a),m=l!=="other",u=e.url;if(c.useEffect(()=>{if(!m||!u||!n)return;let h=!1,b=null;return o(null),n.fetchAttachmentBlob(u).then(g=>{h||(b=URL.createObjectURL(g),d(b))}).catch(g=>{h||o(g instanceof Error?g.message:"Failed to load attachment")}),()=>{h=!0,b&&URL.revokeObjectURL(b)}},[m,u,n]),!u)return t.jsx("p",{className:"text-sm text-fg-dim",children:"(no URL)"});if(r)return t.jsx("p",{className:"text-sm text-red-400",children:r});if(m&&!i)return t.jsx("div",{className:"h-32 animate-pulse rounded bg-border/40","aria-busy":"true"});const x=i??u;return l==="image"?t.jsx("img",{src:x,alt:a,className:"max-h-[32rem] rounded"}):l==="audio"?t.jsx("audio",{controls:!0,src:x,className:"w-full"}):l==="video"?t.jsx("video",{controls:!0,src:x,className:"w-full rounded"}):l==="pdf"?t.jsxs(t.Fragment,{children:[t.jsx("iframe",{src:x,title:a,className:"h-[40rem] w-full rounded border border-border"}),t.jsxs("a",{href:x,download:a,className:"mt-2 inline-block text-sm text-accent hover:underline",children:["Download ",a]})]}):t.jsxs("a",{href:x,download:a,className:"text-sm text-accent hover:underline",children:["Download ",a]})}function se(e,s){if(e.startsWith("image/"))return"image";if(e.startsWith("audio/"))return"audio";if(e.startsWith("video/"))return"video";if(e==="application/pdf")return"pdf";const a=s.toLowerCase().split(".").pop()??"";return["png","jpg","jpeg","gif","webp","svg"].includes(a)?"image":["mp3","wav","ogg","m4a","flac"].includes(a)?"audio":["mp4","webm","mov"].includes(a)?"video":a==="pdf"?"pdf":"other"}function re(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:e<1024*1024*1024?`${(e/(1024*1024)).toFixed(1)} MB`:`${(e/(1024*1024*1024)).toFixed(2)} GB`}function ne(){return t.jsxs("div",{className:"grid gap-10 lg:grid-cols-[minmax(0,1fr)_18rem]","aria-busy":"true",children:[t.jsxs("div",{className:"min-w-0 space-y-3",children:[t.jsx("div",{className:"h-3 w-32 animate-pulse rounded bg-border/40"}),t.jsx("div",{className:"h-8 w-2/3 animate-pulse rounded bg-border/60"}),t.jsx("div",{className:"h-4 w-full animate-pulse rounded bg-border/30"}),t.jsx("div",{className:"mt-6 space-y-2",children:[0,1,2,3,4,5].map(e=>t.jsx("div",{className:"h-3 animate-pulse rounded bg-border/30",style:{width:`${70+e*13%25}%`}},e))})]}),t.jsxs("div",{className:"space-y-4",children:[t.jsx("div",{className:"h-32 animate-pulse rounded bg-border/30"}),t.jsx("div",{className:"h-24 animate-pulse rounded bg-border/30"})]})]})}function ae({id:e}){return t.jsxs("div",{className:"rounded-md border border-border bg-card p-10 text-center",children:[t.jsx("p",{className:"mb-2 font-serif text-xl",children:"Note not found"}),t.jsxs("p",{className:"mb-4 text-sm text-fg-muted",children:["No note with id ",t.jsx("span",{className:"font-mono",children:e})," in this vault."]}),t.jsx(p,{to:"/",className:"text-sm text-accent hover:underline",children:"Back to all notes"})]})}function oe({error:e}){const s=e instanceof L;return t.jsxs("div",{className:"rounded-md border border-red-500/30 bg-red-500/5 p-6",children:[t.jsx("p",{className:"mb-2 font-medium text-red-400",children:s?"Session expired":"Could not load note"}),t.jsx("p",{className:"mb-4 text-sm text-fg-muted",children:e.message}),s?t.jsx(p,{to:"/add",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Reconnect vault"}):null]})}export{ce as NoteView};
import{a3 as y,Q as j,aa as N,x as l,l as w,B as E,A as V,G as S,b as C,r as e}from"./index-BDPMEkxL.js";function R(){const[a]=y(),s=j(),d=N(c=>c.addVault),[n,o]=l.useState({kind:"working"}),u=l.useRef(!1);return l.useEffect(()=>{if(u.current)return;u.current=!0;const c=a.get("code"),p=a.get("state"),x=a.get("error");if(x){o({kind:"error",message:`Vault returned: ${x}`});return}if(!c||!p){o({kind:"error",message:"Missing code or state in callback URL."});return}(async()=>{var m,h,g,v;try{const{pending:t,token:r}=await w(c,p),f=r.vault?`vault:${r.vault}`:void 0,k=(f?(h=(m=r.services)==null?void 0:m[f])==null?void 0:h.url:void 0)??((v=(g=r.services)==null?void 0:g.vault)==null?void 0:v.url)??t.issuerUrl,i=d({url:k,name:r.vault??t.issuer,issuer:t.issuer,tokenEndpoint:t.tokenEndpoint,clientId:t.clientId,scope:r.scope},E(r));r.services&&V(i,r.services);const b=S.getState();b.clearHalt(i),t.priorHaltedVaultId&&t.priorHaltedVaultId!==i&&b.clearHalt(t.priorHaltedVaultId),s("/",{replace:!0})}catch(t){if(t instanceof C){o({kind:"pending-approval",approveUrl:t.approveUrl});return}o({kind:"error",message:t.message})}})()},[a,s,d]),n.kind==="working"?e.jsxs("div",{className:"mx-auto max-w-xl px-6 py-24 text-center",children:[e.jsx("h1",{className:"mb-3 font-serif text-3xl",children:"Connecting…"}),e.jsx("p",{className:"text-fg-muted",children:"Exchanging the authorization code with your vault."})]}):n.kind==="pending-approval"?e.jsxs("div",{className:"mx-auto max-w-xl px-6 py-24 text-center",children:[e.jsx("h1",{className:"mb-3 font-serif text-3xl",children:"Waiting for hub approval"}),e.jsx("p",{className:"mb-8 text-fg-muted",children:"Your hub admin needs to approve this app before sign-in can complete. Open the approval page in your hub, approve, then try again."}),e.jsxs("div",{className:"flex flex-wrap items-center justify-center gap-3",children:[e.jsx("a",{href:n.approveUrl,target:"_blank",rel:"noopener noreferrer",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm text-white hover:bg-accent-hover",children:"Open approval page"}),e.jsx("button",{type:"button",onClick:()=>s("/add",{replace:!0}),className:"inline-block rounded-md border border-border bg-card px-4 py-2 text-sm text-fg-muted hover:text-accent",children:"Retry now"})]})]}):e.jsxs("div",{className:"mx-auto max-w-xl px-6 py-24 text-center",children:[e.jsx("h1",{className:"mb-3 font-serif text-3xl text-red-400",children:"Connection failed"}),e.jsx("p",{className:"mb-8 text-fg-muted",children:n.message}),e.jsx("button",{type:"button",onClick:()=>s("/add",{replace:!0}),className:"rounded-md bg-accent px-4 py-2 text-sm text-white hover:bg-accent-hover",children:"Try again"})]})}export{R as OAuthCallback};
import{x as c,r as t,Q as v,a7 as g,K as w,V as y,aa as j,a5 as E,a8 as N}from"./index-BDPMEkxL.js";function P({note:a,className:i,label:l="Delete"}){const[r,d]=c.useState(!1);return t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",onClick:()=>d(!0),className:i??"min-h-11 rounded-md border border-red-500/40 bg-transparent px-3 py-1.5 text-sm text-red-400 hover:bg-red-500/10",title:"Delete this note",children:l}),r?t.jsx(k,{note:a,onClose:()=>d(!1)}):null]})}function k({note:a,onClose:i}){const l=v(),r=g(e=>e.push),d=w(),o=a.path??a.id,[m,p]=c.useState(""),[u,b]=c.useState(null),x=c.useRef(null),s=m===o&&!d.isPending;c.useEffect(()=>{var e;(e=x.current)==null||e.focus()},[]),c.useEffect(()=>{const e=f=>{f.key==="Escape"&&i()};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[i]);const n=c.useCallback(()=>{s&&(b(null),d.mutate(a.id,{onSuccess:()=>{r(`Deleted ${o}`,"success"),l("/")},onError:e=>{e instanceof y?b("Session expired. Reconnect to delete."):b(e instanceof Error?e.message:"Delete failed")}}))},[s,o,d,l,a.id,r]);return t.jsx("dialog",{open:!0,"aria-labelledby":"confirm-delete-title",className:"fixed inset-0 z-40 m-0 flex h-full max-h-full w-full max-w-full items-center justify-center bg-black/60 p-4",onMouseDown:e=>{e.target===e.currentTarget&&i()},children:t.jsxs("div",{className:"w-full max-w-md rounded-md border border-border bg-card p-6 shadow-xl",children:[t.jsx("h2",{id:"confirm-delete-title",className:"mb-2 font-serif text-xl text-red-400",children:"Delete this note?"}),t.jsx("p",{className:"mb-3 text-sm text-fg-muted",children:"This permanently removes the note, its tags, and its links. This cannot be undone."}),t.jsxs("p",{className:"mb-3 text-sm text-fg-muted",children:["Type"," ",t.jsx("span",{className:"rounded bg-bg/60 px-1 py-0.5 font-mono text-xs text-fg",children:o})," ","to confirm:"]}),t.jsx("input",{ref:x,type:"text",value:m,onChange:e=>p(e.target.value),onKeyDown:e=>{e.key==="Enter"&&s&&n()},"aria-label":"Type note path to confirm",className:"mb-3 w-full rounded-md border border-border bg-bg/40 px-2.5 py-1.5 font-mono text-sm text-fg focus:border-red-400 focus:outline-none",placeholder:o,autoComplete:"off",spellCheck:!1}),u?t.jsx("p",{role:"alert",className:"mb-3 text-sm text-red-400",children:u}):null,t.jsxs("div",{className:"flex justify-end gap-2",children:[t.jsx("button",{type:"button",onClick:i,className:"min-h-11 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg-muted hover:text-fg",children:"Cancel"}),t.jsx("button",{type:"button",onClick:n,disabled:!s,className:"min-h-11 rounded-md bg-red-500 px-4 py-1.5 text-sm font-medium text-white hover:bg-red-600 disabled:opacity-40",children:d.isPending?"Deleting…":"Delete permanently"})]})]})})}function C({note:a,keyboard:i=!1}){var b,x;const l=j(s=>s.getActiveVault()),{roles:r}=E((l==null?void 0:l.id)??null),d=g(s=>s.push),o=N(a.id),m=((b=a.tags)==null?void 0:b.includes(r.pinned))??!1,p=((x=a.tags)==null?void 0:x.includes(r.archived))??!1,u=c.useCallback(s=>{var f;if(o.isPending)return;const n=r[s],e=((f=a.tags)==null?void 0:f.includes(n))??!1;o.mutate({tags:e?{remove:[n]}:{add:[n]}},{onSuccess:()=>{d(s==="pinned"?e?"Unpinned":"Pinned":e?"Unarchived":"Archived","success")},onError:h=>{h instanceof y?d("Session expired. Reconnect.","error"):d(h instanceof Error?h.message:"Update failed","error")}})},[o,a.tags,d,r]);return c.useEffect(()=>{if(!i)return;const s=n=>{if(n.defaultPrevented)return;const e=n.target;if(e){const f=e.tagName;if(f==="INPUT"||f==="TEXTAREA"||e.isContentEditable)return}n.metaKey||n.ctrlKey||n.altKey||(n.key==="p"||n.key==="P"?(n.preventDefault(),u("pinned")):(n.key==="a"||n.key==="A")&&(n.preventDefault(),u("archived")))};return window.addEventListener("keydown",s),()=>window.removeEventListener("keydown",s)},[i,u]),t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",onClick:()=>u("pinned"),disabled:o.isPending,"aria-pressed":m,title:m?`Unpin (${r.pinned})`:`Pin as #${r.pinned} (P)`,className:m?"min-h-11 rounded-md border border-accent/60 bg-accent/10 px-3 py-1.5 text-sm text-accent hover:bg-accent/20 disabled:opacity-40":"min-h-11 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg-muted hover:text-accent disabled:opacity-40",children:m?"★ Pinned":"☆ Pin"}),t.jsx("button",{type:"button",onClick:()=>u("archived"),disabled:o.isPending,"aria-pressed":p,title:p?`Unarchive (${r.archived})`:`Archive as #${r.archived} (A)`,className:p?"min-h-11 rounded-md border border-amber-500/40 bg-amber-500/10 px-3 py-1.5 text-sm text-amber-500 hover:bg-amber-500/20 disabled:opacity-40":"min-h-11 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg-muted hover:text-accent disabled:opacity-40",children:p?"Archived":"Archive"})]})}export{P as D,C as P};

Sorry, the diff of this file is too big to display

import{aa as T,r as e,N as E,L as k,a1 as b,a2 as C,E as A,a7 as S,x as o,y as R,d as D,C as L,Z as _,P as z,a5 as P,a6 as V,T as v,D as j,q as M,o as O,ab as F,i as I}from"./index-BDPMEkxL.js";function K(){const t=T(s=>s.getActiveVault());return t?e.jsxs("div",{className:"mx-auto max-w-2xl px-4 py-7 md:px-6 md:py-12",children:[e.jsxs("header",{className:"mb-8",children:[e.jsx("nav",{className:"mb-3 text-sm text-fg-dim",children:e.jsx(k,{to:"/",className:"hover:text-accent",children:"← Home"})}),e.jsx("h1",{className:"font-serif text-2xl tracking-tight md:text-3xl",children:"Settings"}),e.jsxs("p",{className:"mt-1 text-sm text-fg-muted",children:["Configuring ",e.jsx("span",{className:"text-fg",children:t.name}),"."]})]}),e.jsx($,{vaultId:t.id}),e.jsx(q,{}),e.jsx(U,{vaultId:t.id}),e.jsx(Y,{vaultId:t.id}),e.jsx(G,{})]}):e.jsx(E,{to:"/",replace:!0})}function $({vaultId:t}){const s=b(l=>l.byVault[t]??null),r=b(l=>l.refresh),n=b(l=>l.set),h=C(l=>l.clearDismissed),i=A(),d=S(l=>l.push),[x,u]=o.useState(!1),f=async()=>{i&&await r(t,i)},g=async()=>{var l;if(i){u(!0);try{await O(t,i);const m=(l=s==null?void 0:s.result)==null?void 0:l.rows.map(w=>({...w,status:"ok",differences:[]}));m&&n(t,{ok:!0,missing:[],misaligned:[],rows:m}),h(t),d("Schema updated.","success")}catch(m){d(m instanceof Error?`Schema fix failed: ${m.message}`:"Schema fix failed.","error")}finally{u(!1)}}},p=(s==null?void 0:s.loading)??!s,a=(s==null?void 0:s.result)??null,c=(s==null?void 0:s.error)??null;return e.jsxs("section",{className:"mt-6 space-y-4 rounded-xl border border-border bg-card p-6",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"font-serif text-xl text-fg",children:"Vault schema"}),e.jsxs("p",{className:"mt-1 text-xs text-fg-dim",children:["Notes declares three tags it uses to classify captures: ",e.jsx("code",{children:"capture"}),","," ",e.jsx("code",{children:"capture/text"}),", ",e.jsx("code",{children:"capture/voice"}),". This panel confirms the active vault has them set up; one click writes any missing or misaligned rows. Doesn't touch your Tag Role choices below."]})]}),e.jsx("button",{type:"button",onClick:()=>void f(),disabled:p||!i,className:"shrink-0 text-xs text-fg-dim hover:text-accent disabled:cursor-not-allowed disabled:opacity-60",children:p?"Checking…":"Refresh"})]}),c?e.jsxs("p",{className:"rounded-md border border-red-500/30 bg-red-500/5 px-3 py-2 text-xs text-red-300",children:["Audit failed: ",c]}):null,!a&&!c?e.jsx("p",{className:"text-xs text-fg-dim",children:"Loading audit…"}):null,a?e.jsxs(e.Fragment,{children:[e.jsx(H,{ok:a.ok}),e.jsx("ul",{className:"space-y-2",children:a.rows.map(l=>e.jsx(B,{row:l},l.name))}),a.ok?null:e.jsx("button",{type:"button",onClick:()=>void g(),disabled:x||!i,className:"min-h-11 rounded-md bg-accent px-3 py-1.5 text-xs font-medium text-white hover:bg-accent-hover disabled:cursor-not-allowed disabled:opacity-60",children:x?"Setting up…":"Set up missing tags"})]}):null]})}function H({ok:t}){return e.jsxs("p",{className:`inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs ${t?"bg-emerald-500/20 text-emerald-300":"bg-amber-500/20 text-amber-300"}`,children:[e.jsx("span",{"aria-hidden":!0,className:`h-1.5 w-1.5 rounded-full ${t?"bg-emerald-400":"bg-amber-400"}`}),t?"Matches Notes' schema":"Needs setup"]})}function B({row:t}){const s=t.status==="ok"?"ok":t.status==="missing"?"missing":"misaligned",r=t.status==="ok"?"text-emerald-300":"text-amber-300";return e.jsxs("li",{className:"rounded-md border border-border bg-bg/40 px-3 py-2 text-xs",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("code",{className:"font-mono text-sm text-fg",children:t.name}),e.jsx("span",{className:`text-xs ${r}`,children:s})]}),t.status==="misaligned"?e.jsxs("p",{className:"mt-1 text-fg-dim",children:["Differs in: ",t.differences.join(", ")]}):null,e.jsx("p",{className:"mt-1 text-fg-dim",children:t.expected.description}),t.expected.parent_names?e.jsxs("p",{className:"text-fg-dim",children:["Parent: ",e.jsx("code",{className:"font-mono",children:t.expected.parent_names.join(", ")})]}):null]})}function q(){const[t,s]=o.useState(()=>R()),r=n=>{s(n),F(n),I(n)};return e.jsxs("section",{className:"mt-6 space-y-4 rounded-xl border border-border bg-card p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"font-serif text-xl text-fg",children:"Text size"}),e.jsx("p",{className:"mt-1 text-xs text-fg-dim",children:"Affects the editor and rendered notes on this device. Your markdown isn't changed."})]}),e.jsxs("fieldset",{className:"space-y-2",children:[e.jsx("legend",{className:"sr-only",children:"View text size"}),D.map(n=>e.jsxs("label",{className:"flex items-start gap-2 text-sm",children:[e.jsx("input",{type:"radio",name:"text-size",value:n,checked:t===n,onChange:()=>r(n),className:"mt-1 accent-accent"}),e.jsx("span",{className:"text-fg",children:L(n)})]},n))]})]})}function G(){const[t,s]=o.useState(!1);return o.useEffect(()=>{s(M())},[]),t?e.jsx("section",{className:"mt-6 rounded-md border border-border bg-card p-4 text-sm",children:e.jsxs("p",{className:"text-fg-muted",children:[e.jsx("span",{className:"mr-2 inline-block rounded-full bg-emerald-500/20 px-2 py-0.5 text-xs font-medium text-emerald-300",children:"Installed"}),"Parachute Notes is running as an installed app on this device."]})}):null}const y={auto:{title:"Auto",help:"Show the tree only when the vault has enough folders to make it worth the space."},always:{title:"Always",help:"Always show the tree, even on a tag-flat vault."},never:{title:"Never",help:"Hide the tree. The path-prefix text input still works."}};function U({vaultId:t}){const{mode:s,setMode:r}=_(t);return e.jsxs("section",{className:"mt-6 space-y-4 rounded-xl border border-border bg-card p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"font-serif text-xl text-fg",children:"Folder tree (Notes sidebar)"}),e.jsx("p",{className:"mt-1 text-xs text-fg-dim",children:"Controls the collapsible folder tree on the notes list page. Auto-detect renders the tree when the vault has at least five top-level folders or twenty notes in folders."})]}),e.jsxs("fieldset",{className:"space-y-2",children:[e.jsx("legend",{className:"sr-only",children:"Path tree visibility"}),z.map(n=>e.jsxs("label",{className:"flex items-start gap-2 text-sm",children:[e.jsx("input",{type:"radio",name:"path-tree-mode",value:n,checked:s===n,onChange:()=>r(n),className:"mt-1 accent-accent"}),e.jsxs("span",{children:[e.jsx("span",{className:"text-fg",children:y[n].title}),e.jsx("span",{className:"ml-2 text-xs text-fg-dim",children:y[n].help})]})]},n))]})]})}const N={pinned:{title:"Pinned",help:"Tag for notes you want at the top of views."},archived:{title:"Archived",help:"Tag for notes you've moved out of the way."},captureVoice:{title:"Voice capture",help:"Default tag for new voice memos."},captureText:{title:"Text capture",help:"Default tag for quick typed notes."},view:{title:"Saved view",help:"Tag the saved-view notes carry. Used to list them in the notes sidebar."}};function Y({vaultId:t}){const{roles:s,setRoles:r}=P(t),n=V(),h=S(a=>a.push),i=o.useId(),[d,x]=o.useState(s);o.useEffect(()=>x(s),[s]);const u=o.useMemo(()=>{const a=(n.data??[]).map(c=>c.name);return[...new Set(a)].sort((c,l)=>c.localeCompare(l))},[n.data]),f=v.some(a=>d[a].trim()!==s[a]),g=()=>{r(d),h("Tag roles saved.","success")},p=()=>{r(null),x(j),h("Tag roles reset to defaults.","success")};return e.jsxs("section",{className:"mt-6 space-y-4 rounded-xl border border-border bg-card p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"font-serif text-xl text-fg",children:"Tag roles"}),e.jsx("p",{className:"mt-1 text-xs text-fg-dim",children:"Point each role at whatever tag your vault already uses. Changes apply to future notes only — existing notes keep their current tags."})]}),e.jsx("datalist",{id:i,children:u.map(a=>e.jsx("option",{value:a},a))}),e.jsx("div",{className:"space-y-3",children:v.map(a=>e.jsxs("label",{className:"block text-sm",children:[e.jsxs("span",{className:"mb-1 flex items-baseline justify-between gap-2",children:[e.jsx("span",{className:"text-fg-muted",children:N[a].title}),e.jsxs("span",{className:"text-xs text-fg-dim",children:["default: #",j[a]]})]}),e.jsx("input",{type:"text",value:d[a],onChange:c=>x(l=>({...l,[a]:c.target.value})),list:i,placeholder:j[a],"aria-label":`${N[a].title} tag role`,spellCheck:!1,autoCapitalize:"none",autoCorrect:"off",className:"w-full rounded-md border border-border bg-bg px-3 py-2 text-sm text-fg placeholder:text-fg-dim focus:border-accent focus:outline-none"}),e.jsx("span",{className:"mt-1 block text-xs text-fg-dim",children:N[a].help})]},a))}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3 pt-2",children:[e.jsx("button",{type:"button",onClick:g,disabled:!f,className:"rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover disabled:opacity-40",children:"Save"}),e.jsx("button",{type:"button",onClick:p,className:"text-sm text-fg-muted hover:text-accent",children:"Reset to defaults"})]})]})}export{K as Settings};
import{a7 as P,x as l,h as O,V as R,r as e,aa as L,a6 as F,a4 as I,$ as V,a0 as z,O as D,N as B,L as E}from"./index-BDPMEkxL.js";const $=a=>Object.values(a).reduce((n,x)=>n+x,0);function A({mode:a,sources:n,tagOptions:x,onClose:c,onRun:d,onRunMerge:o,pending:i,offline:m}){const p=P(t=>t.push),g=l.useId(),[S,j]=l.useState(a==="rename"?n[0]??"":""),[T,h]=l.useState(null),[u,y]=l.useState(null),[b,N]=l.useState(!1),v=l.useRef(null);l.useEffect(()=>{var t,r;(t=v.current)==null||t.focus(),(r=v.current)==null||r.select()},[]),l.useEffect(()=>{const t=r=>{r.key==="Escape"&&c()};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[c]);const w=S.trim().replace(/^#/,""),f=!i&&!m&&!b&&w.length>0&&!(a==="rename"&&w===n[0]),C=l.useCallback(async()=>{if(f){h(null),y(null);try{const t=await d(w);if("renamed"in t)p(`Renamed on ${t.renamed} note${t.renamed===1?"":"s"}.`,"success");else{const r=$(t.merged);p(`Merged into #${t.target} on ${r} note${r===1?"":"s"}.`,"success")}c()}catch(t){if(t instanceof O&&a==="rename"&&o){y(t.target);return}t instanceof R?h("Session expired. Reconnect to retry."):h(t instanceof Error?t.message:"Operation failed.")}}},[f,w,a,c,d,o,p]),k=l.useCallback(async()=>{if(!(!u||!o)){h(null),N(!0);try{const t=await o(u),r=$(t.merged);p(`Merged into #${t.target} on ${r} note${r===1?"":"s"}.`,"success"),c()}catch(t){t instanceof R?h("Session expired. Reconnect to retry."):h(t instanceof Error?t.message:"Merge failed."),N(!1)}}},[u,c,o,p]),s=a==="rename"?"Rename tag":`Merge ${n.length} tags`;return e.jsx("dialog",{open:!0,"aria-labelledby":"tag-op-title",className:"fixed inset-0 z-40 m-0 flex h-full max-h-full w-full max-w-full items-center justify-center bg-black/60 p-4",onMouseDown:t=>{t.target===t.currentTarget&&c()},children:e.jsxs("div",{className:"w-full max-w-md rounded-md border border-border bg-card p-6 shadow-xl",children:[e.jsx("h2",{id:"tag-op-title",className:"mb-2 font-serif text-xl text-fg",children:s}),e.jsxs("p",{className:"mb-3 text-sm text-fg-muted",children:[a==="rename"?e.jsxs(e.Fragment,{children:["Rename ",e.jsx(M,{children:n[0]})," on every note that carries it. Notes that already have the new tag will end up with one copy."]}):e.jsxs(e.Fragment,{children:["Combine"," ",n.map((t,r)=>e.jsxs("span",{children:[e.jsx(M,{children:t}),r<n.length-1?", ":""]},t))," ","into one tag. The originals are removed."]})," ","Changes apply atomically on the vault."]}),e.jsxs("label",{className:"mb-3 block text-sm",children:[e.jsx("span",{className:"mb-1 block text-fg-muted",children:a==="rename"?"New tag name":"Target tag"}),e.jsx("input",{ref:v,type:"text",value:S,onChange:t=>{j(t.target.value),u&&y(null)},onKeyDown:t=>{t.key==="Enter"&&f&&C()},list:g,"aria-label":a==="rename"?"New tag name":"Merge target tag",spellCheck:!1,autoCapitalize:"none",autoCorrect:"off",className:"w-full rounded-md border border-border bg-bg/40 px-2.5 py-1.5 font-mono text-sm text-fg focus:border-accent focus:outline-none",autoComplete:"off"}),e.jsx("datalist",{id:g,children:x.map(t=>e.jsx("option",{value:t},t))})]}),m?e.jsx("p",{className:"mb-3 text-sm text-amber-300",children:"Offline — tag operations need a live vault connection."}):null,u?e.jsxs("div",{role:"alert",className:"mb-3 rounded-md border border-amber-500/40 bg-amber-500/5 p-3 text-sm",children:[e.jsxs("p",{className:"mb-2 text-amber-300",children:["A tag named ",e.jsx(M,{children:u})," already exists."]}),e.jsxs("p",{className:"mb-3 text-fg-muted",children:["Merge ",e.jsx(M,{children:n[0]})," into ",e.jsx(M,{children:u})," instead? Notes that carry both end up with one copy."]}),e.jsx("button",{type:"button",onClick:()=>void k(),disabled:b,className:"rounded-md bg-accent px-3 py-1.5 text-xs font-medium text-white hover:bg-accent-hover disabled:opacity-40",children:b?"Merging…":`Merge into #${u}`})]}):null,T?e.jsx("p",{role:"alert",className:"mb-3 text-sm text-red-400",children:T}):null,e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:c,className:"min-h-11 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg-muted hover:text-fg",children:"Cancel"}),e.jsx("button",{type:"button",onClick:()=>void C(),disabled:!f,className:"min-h-11 rounded-md bg-accent px-4 py-1.5 text-sm font-medium text-white hover:bg-accent-hover disabled:opacity-40",children:i?a==="rename"?"Renaming…":"Merging…":a==="rename"?"Rename":"Merge"})]})]})})}function M({children:a}){return e.jsxs("span",{className:"rounded bg-bg/60 px-1 py-0.5 font-mono text-xs text-fg",children:["#",a]})}function J(){const a=L(s=>s.getActiveVault()),n=F(),{isOnline:x}=I(),{isPinned:c,togglePin:d}=V((a==null?void 0:a.id)??null),[o,i]=l.useState(""),[m,p]=l.useState("count"),[g,S]=l.useState(new Set),[j,T]=l.useState(null),[h,u]=l.useState(!1),y=z(),b=D(),N=l.useMemo(()=>U(n.data??[],o,m),[n.data,o,m]),v=l.useMemo(()=>(n.data??[]).map(s=>s.name),[n.data]),w=s=>{S(t=>{const r=new Set(t);return r.has(s)?r.delete(s):r.add(s),r})},f=()=>S(new Set);if(!a)return e.jsx(B,{to:"/",replace:!0});const C=g.size,k=!x;return e.jsxs("div",{className:"mx-auto max-w-4xl px-4 py-6 md:px-6 md:py-10",children:[e.jsxs("header",{className:"mb-5 flex flex-wrap items-baseline justify-between gap-x-4 gap-y-3 md:mb-6",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-xs uppercase tracking-wider text-fg-dim",children:a.name}),e.jsx("h1",{className:"font-serif text-2xl tracking-tight md:text-3xl",children:"Tags"})]}),e.jsxs("button",{type:"button",onClick:()=>p(s=>s==="count"?"alpha":"count"),className:"text-sm text-fg-muted hover:text-accent","aria-label":"Toggle tag sort",children:["Sort: ",m==="count"?"most used":"A–Z"]})]}),e.jsx("input",{type:"search",placeholder:"Filter tags…",value:o,onChange:s=>i(s.target.value),"aria-label":"Filter tags",className:"mb-4 w-full rounded-md border border-border bg-card px-3 py-2 text-sm text-fg focus:border-accent focus:outline-none"}),C>0?e.jsxs("div",{className:"mb-4 flex flex-wrap items-center gap-3 rounded-md border border-accent/30 bg-accent/5 px-3 py-2 text-sm","aria-label":"Tag selection actions",children:[e.jsxs("span",{className:"text-fg-muted",children:[C," selected: ",Array.from(g).join(", ")]}),e.jsx("button",{type:"button",onClick:()=>u(!0),disabled:C<2||k,className:"rounded-md bg-accent px-3 py-1 text-xs font-medium text-white hover:bg-accent-hover disabled:opacity-40",children:"Merge into…"}),e.jsx("button",{type:"button",onClick:f,className:"text-xs text-fg-muted hover:text-accent",children:"Clear"})]}):null,n.isPending?e.jsx(Z,{}):n.isError?e.jsx(q,{error:n.error}):N.length===0?e.jsx(G,{filtering:o.trim().length>0,hasAny:(n.data??[]).length>0}):e.jsx("ul",{className:"divide-y divide-border rounded-md border border-border bg-card","aria-label":"Tag list",children:N.map(s=>e.jsx(K,{tag:s,selected:g.has(s.name),onToggle:()=>w(s.name),onRename:()=>T(s.name),pinned:c(s.name),onTogglePin:()=>d(s.name),offline:k},s.name))}),n.data&&n.data.length>0?e.jsxs("p",{className:"mt-6 text-xs text-fg-dim",children:[N.length," / ",n.data.length," tag",n.data.length===1?"":"s"]}):null,j!==null?e.jsx(A,{mode:"rename",sources:[j],tagOptions:v,onClose:()=>T(null),pending:y.isPending||b.isPending,offline:k,onRun:s=>y.mutateAsync({oldName:j,newName:s}),onRunMerge:s=>b.mutateAsync({sources:[j],target:s})}):null,h?e.jsx(A,{mode:"merge",sources:Array.from(g),tagOptions:v,onClose:()=>u(!1),pending:b.isPending,offline:k,onRun:async s=>{const t=await b.mutateAsync({sources:Array.from(g),target:s});return f(),t}}):null]})}function K({tag:a,selected:n,onToggle:x,onRename:c,pinned:d,onTogglePin:o,offline:i}){return e.jsxs("li",{className:"flex items-center gap-3 px-3 py-2 text-sm",children:[e.jsx("input",{type:"checkbox",checked:n,onChange:x,"aria-label":`Select tag ${a.name}`,className:"accent-accent"}),e.jsxs(E,{to:`/?tag=${encodeURIComponent(a.name)}`,className:"flex flex-1 items-baseline gap-2 text-fg hover:text-accent focus-visible:outline-2 focus-visible:outline-accent",children:[e.jsxs("span",{className:"font-mono",children:["#",a.name]}),e.jsx("span",{className:"text-xs text-fg-dim",children:a.count})]}),e.jsx("button",{type:"button",onClick:o,className:d?"text-xs font-medium text-accent hover:text-accent-hover":"text-xs text-fg-muted hover:text-accent","aria-label":d?`Unpin tag ${a.name}`:`Pin tag ${a.name}`,"aria-pressed":d,title:d?"Pinned to home strip — click to unpin":"Pin to home strip",children:d?"★ Pinned":"☆ Pin"}),e.jsx("button",{type:"button",onClick:c,disabled:i,className:"text-xs text-fg-muted hover:text-accent disabled:opacity-40","aria-label":`Rename tag ${a.name}`,children:"Rename"})]})}function U(a,n,x){const c=n.trim().toLowerCase(),o=[...c?a.filter(i=>i.name.toLowerCase().includes(c)):a];return x==="alpha"?o.sort((i,m)=>i.name.localeCompare(m.name)):o.sort((i,m)=>m.count-i.count||i.name.localeCompare(m.name)),o}function Z(){return e.jsx("div",{className:"divide-y divide-border rounded-md border border-border bg-card","aria-busy":"true",children:[0,1,2,3,4].map(a=>e.jsx("div",{className:"h-10 animate-pulse bg-card/60"},a))})}function q({error:a}){const n=a instanceof R;return e.jsxs("div",{className:"rounded-md border border-red-500/30 bg-red-500/5 p-6",children:[e.jsx("p",{className:"mb-2 font-medium text-red-400",children:n?"Session expired":"Could not load tags"}),e.jsx("p",{className:"mb-4 text-sm text-fg-muted",children:a.message}),n?e.jsx(E,{to:"/add",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Reconnect vault"}):null]})}function G({filtering:a,hasAny:n}){return a&&n?e.jsx("div",{className:"rounded-md border border-border bg-card p-10 text-center",children:e.jsx("p",{className:"text-fg-muted",children:"No tags match your filter."})}):e.jsxs("div",{className:"rounded-md border border-border bg-card p-10 text-center",children:[e.jsx("p",{className:"mb-3 text-fg-muted",children:"No tags in this vault yet."}),e.jsx(E,{to:"/new",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Create a note"})]})}export{J as Tags};
import{aa as w,a3 as $,W as A,x as D,r as e,N as E,L as d,z as C,V as S}from"./index-BDPMEkxL.js";import{e as V,b as N,t as g,f as K,p as f}from"./dates-BGZoWpL2.js";function F(){const a=w(i=>i.getActiveVault()),[s]=$(),t=s.get("date"),u=V(),r=t??u,x=N(r),n=A(),c=D.useMemo(()=>{const i=[],m=[];if(!n.data||!x)return{created:i,edited:m};for(const l of n.data){const b=g(l.createdAt),k=g(l.updatedAt??l.createdAt);b===r&&i.push(l),k===r&&b!==r&&m.push(l)}return{created:i,edited:m}},[n.data,x,r]);if(!a)return e.jsx(E,{to:"/",replace:!0});if(!x)return e.jsxs("div",{className:"mx-auto max-w-3xl px-4 py-6 md:px-6 md:py-10",children:[e.jsxs("p",{className:"text-sm text-red-400",children:["Invalid date in URL: ",r]}),e.jsx(d,{to:"/today",className:"text-sm text-accent hover:underline",children:"Back to today"})]});const o=r===u,p=j(r,-1),h=j(r,1),v=r.slice(0,7);return e.jsxs("div",{className:"mx-auto max-w-3xl px-4 py-6 md:px-6 md:py-10",children:[e.jsxs("header",{className:"mb-6 flex flex-wrap items-baseline justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-xs uppercase tracking-wider text-fg-dim",children:o?"Today":"On"}),e.jsx("h1",{className:"font-serif text-2xl tracking-tight md:text-3xl",children:K(r)})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm",children:[e.jsxs(d,{to:`/today?date=${p}`,className:"rounded-md border border-border bg-card px-3 py-1.5 text-fg-muted hover:text-accent","aria-label":"Previous day",children:["← ",p]}),o?null:e.jsx(d,{to:"/today",className:"rounded-md border border-border bg-card px-3 py-1.5 text-fg-muted hover:text-accent",children:"Today"}),e.jsxs(d,{to:`/today?date=${h}`,className:"rounded-md border border-border bg-card px-3 py-1.5 text-fg-muted hover:text-accent","aria-label":"Next day",children:[h," →"]}),e.jsx(d,{to:`/calendar?month=${v}`,className:"rounded-md border border-border bg-card px-3 py-1.5 text-fg-muted hover:text-accent",children:"Calendar"}),e.jsx(d,{to:"/capture",className:"rounded-md bg-accent px-3 py-1.5 font-medium text-white hover:bg-accent-hover",children:"+ Capture"})]})]}),n.isPending?e.jsx(L,{}):n.isError?e.jsx(R,{error:n.error}):c.created.length===0&&c.edited.length===0?e.jsx(P,{isToday:o,targetKey:r}):e.jsxs("div",{className:"space-y-8",children:[c.created.length>0?e.jsx(y,{title:o?"Created today":`Created on ${r}`,notes:c.created}):null,c.edited.length>0?e.jsx(y,{title:o?"Edited today":`Edited on ${r}`,notes:c.edited}):null]})]})}function j(a,s){const t=N(a);return t?(t.setDate(t.getDate()+s),`${t.getFullYear()}-${f(t.getMonth()+1)}-${f(t.getDate())}`):a}function y({title:a,notes:s}){return e.jsxs("section",{children:[e.jsxs("h2",{className:"mb-2 text-xs uppercase tracking-wider text-fg-dim",children:[a," (",s.length,")"]}),e.jsx("ol",{className:"divide-y divide-border rounded-md border border-border bg-card",children:s.map(t=>e.jsx("li",{children:e.jsxs(d,{to:`/n/${encodeURIComponent(t.id)}`,className:"block px-4 py-3 hover:bg-bg/60 focus:bg-bg/60 focus:outline-none",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-4",children:[e.jsx("span",{className:"truncate font-mono text-sm text-fg",children:t.path??t.id}),e.jsx("span",{className:"shrink-0 text-xs text-fg-dim",children:C(t.updatedAt??t.createdAt)})]}),t.preview?e.jsx("p",{className:"mt-1 truncate text-sm text-fg-muted",children:t.preview}):null]})},t.id))})]})}function P({isToday:a,targetKey:s}){return e.jsxs("div",{className:"rounded-md border border-border bg-card p-10 text-center",children:[e.jsx("p",{className:"mb-4 text-fg-muted",children:a?"Nothing yet today — start capturing.":`Nothing on ${s}.`}),a?e.jsx(d,{to:"/capture",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Open capture"}):null]})}function L(){return e.jsx("div",{className:"space-y-3","aria-busy":"true",children:[0,1,2,3].map(a=>e.jsx("div",{className:"h-14 animate-pulse rounded-md bg-border/30"},a))})}function R({error:a}){const s=a instanceof S;return e.jsxs("div",{className:"rounded-md border border-red-500/30 bg-red-500/5 p-6",children:[e.jsx("p",{className:"mb-2 font-medium text-red-400",children:s?"Session expired":"Could not load notes"}),e.jsx("p",{className:"mb-4 text-sm text-fg-muted",children:a.message}),s?e.jsx(d,{to:"/add",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Reconnect vault"}):null]})}export{F as Today};

Sorry, the diff of this file is too big to display

const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/react-force-graph-2d-CokIfB0T.js","assets/index-BDPMEkxL.js","assets/index-D_L2igjK.css"])))=>i.map(i=>d[i]);
import{aa as w,F as N,x as f,r as s,N as k,L as v,Q as C,V as I,_ as M}from"./index-BDPMEkxL.js";const S={search:"",tags:[]};function T(e){const t=new Map;for(const i of e)t.set(i.id,i);const a=new Map,o=new Map;for(const i of e)for(const n of i.links??[]){if(n.sourceId===n.targetId||!t.has(n.sourceId)||!t.has(n.targetId))continue;const c=`${n.sourceId}|${n.targetId}|${n.relationship}`;a.has(c)||(a.set(c,{source:n.sourceId,target:n.targetId,relationship:n.relationship}),o.set(n.sourceId,(o.get(n.sourceId)??0)+1),o.set(n.targetId,(o.get(n.targetId)??0)+1))}return{nodes:e.map(i=>{var c;const n=i.tags??[];return{id:i.id,path:i.path,title:A(i),tags:n,topTag:n[0],degree:o.get(i.id)??0,summary:typeof((c=i.metadata)==null?void 0:c.summary)=="string"?i.metadata.summary:void 0}}),edges:[...a.values()]}}function A(e){return e.path?(e.path.split("/").pop()??e.path).replace(/\.md$/i,""):e.id}function R(e,t){const a=t.search.trim().toLowerCase();return!(a&&![e.path??"",e.title,e.id].join(" ").toLowerCase().includes(a)||t.tags.length>0&&!t.tags.some(d=>e.tags.includes(d)))}function E(e){const t=new Map;for(const a of e)for(const o of a.tags)t.set(o,(t.get(o)??0)+1);return[...t.entries()].sort((a,o)=>o[1]-a[1]||a[0].localeCompare(o[0])).map(([a])=>a)}function F(e){if(!e)return"#8a9a7a";let t=0;for(let o=0;o<e.length;o++)t=t*31+e.charCodeAt(o)&16777215;return`hsl(${t%360}, 40%, 55%)`}const _=f.lazy(()=>M(()=>import("./react-force-graph-2d-CokIfB0T.js"),__vite__mapDeps([0,1,2]))),L=20;function O(){const e=w(c=>c.getActiveVault()),t=N(),[a,o]=f.useState(S),d=f.useMemo(()=>t.data?T(t.data):null,[t.data]),i=f.useMemo(()=>d?E(d.nodes):[],[d]),n=f.useMemo(()=>d?new Set(d.nodes.filter(c=>R(c,a)).map(c=>c.id)):new Set,[d,a]);return e?s.jsxs("div",{className:"flex h-[calc(100dvh-5rem)] flex-col",children:[s.jsx("div",{className:"border-b border-border bg-card/40 px-6 py-3",children:s.jsxs("div",{className:"mx-auto flex max-w-6xl flex-wrap items-center gap-4",children:[s.jsx("input",{type:"search",value:a.search,onChange:c=>o(m=>({...m,search:c.target.value})),placeholder:"Search nodes…","aria-label":"Search graph nodes",className:"min-w-48 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg focus:border-accent focus:outline-none"}),s.jsx($,{allTags:i,selected:a.tags,onChange:c=>o(m=>({...m,tags:c}))}),d?s.jsxs("span",{className:"text-xs text-fg-dim",children:[n.size," / ",d.nodes.length," notes"]}):null]})}),s.jsx("div",{className:"min-h-0 flex-1",children:s.jsx(P,{query:t,graph:d,matched:n})})]}):s.jsx(k,{to:"/",replace:!0})}function P({query:e,graph:t,matched:a}){return e.isPending?s.jsx(y,{message:"Loading vault…"}):e.isError?s.jsx(B,{error:e.error}):!t||t.nodes.length===0?s.jsx("div",{className:"flex h-full items-center justify-center p-10",children:s.jsxs("div",{className:"max-w-sm rounded-md border border-border bg-card p-8 text-center",children:[s.jsx("p",{className:"mb-2 font-serif text-xl",children:"No notes yet"}),s.jsx("p",{className:"mb-4 text-sm text-fg-muted",children:"This vault is empty. Start by creating the first note."}),s.jsx(v,{to:"/new",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Create a note"})]})}):s.jsx(z,{graph:t,matched:a})}function $({allTags:e,selected:t,onChange:a}){const o=e.slice(0,L);if(o.length===0)return null;const d=i=>a(t.includes(i)?t.filter(n=>n!==i):[...t,i]);return s.jsxs("fieldset",{"aria-label":"Filter by tag",className:"flex flex-wrap items-center gap-1 text-xs text-fg-dim",children:[s.jsx("legend",{className:"mr-1 inline-block",children:"Tags"}),o.map(i=>{const n=t.includes(i);return s.jsx("button",{type:"button","aria-pressed":n,onClick:()=>d(i),className:n?"max-w-full break-all rounded-full border border-accent bg-accent/10 px-2 py-0.5 text-accent":"max-w-full break-all rounded-full border border-border bg-card px-2 py-0.5 hover:text-accent",children:i},i)}),t.length>0?s.jsx("button",{type:"button",onClick:()=>a([]),className:"ml-1 text-xs text-fg-dim hover:text-accent",children:"Clear"}):null]})}function y({message:e}){return s.jsx("div",{"aria-busy":"true",className:"flex h-full animate-pulse items-center justify-center bg-card/30 text-sm text-fg-dim",children:e})}function z({graph:e,matched:t}){const a=C(),o=f.useRef(null),d=f.useRef(null),[i,n]=f.useState({w:800,h:600});f.useEffect(()=>{const r=o.current;if(!r)return;const l=()=>{const u=r.getBoundingClientRect();n({w:Math.max(320,Math.floor(u.width)),h:Math.max(320,Math.floor(u.height))})};l();const h=new ResizeObserver(l);return h.observe(r),()=>h.disconnect()},[]);const c=()=>{var r,l;(l=(r=d.current)==null?void 0:r.zoomToFit)==null||l.call(r,400,40)},m=f.useMemo(()=>({nodes:e.nodes.map(r=>({...r})),links:e.edges.map(r=>({source:r.source,target:r.target,rel:r.relationship}))}),[e]),g=t.size!==e.nodes.length,j=r=>!g||t.has(r)?1:.15;return s.jsxs("div",{ref:o,"data-testid":"vault-graph-canvas",className:"relative h-full w-full touch-none",children:[s.jsx(f.Suspense,{fallback:s.jsx(y,{message:"Rendering graph…"}),children:s.jsx(_,{ref:d,graphData:m,width:i.w,height:i.h,backgroundColor:"rgba(0,0,0,0)",nodeLabel:r=>V(r),nodeRelSize:5,nodeVal:r=>2+Math.min(r.degree,12),nodeColor:r=>{const l=r,h=F(l.topTag);return g&&!t.has(l.id)?G(h):h},nodePointerAreaPaint:(r,l,h)=>{const u=r;if(u.x==null||u.y==null)return;const x=2+Math.min(u.degree,12),p=Math.max(Math.sqrt(x)*5,10);h.fillStyle=l,h.beginPath(),h.arc(u.x,u.y,p,0,2*Math.PI),h.fill()},linkColor:r=>{const l=r,h=b(l.source),u=b(l.target);return g&&(!t.has(h)||!t.has(u))?"rgba(160, 160, 160, 0.08)":"rgba(160, 160, 160, 0.35)"},linkDirectionalArrowLength:2.5,linkDirectionalArrowRelPos:1,cooldownTicks:100,onEngineStop:()=>c(),nodeCanvasObjectMode:()=>"after",nodeCanvasObject:(r,l,h)=>{const u=r;if(u.x==null||u.y==null||j(u.id)<.5)return;const p=10/h;l.font=`${p}px sans-serif`,l.fillStyle="rgba(220, 220, 220, 0.8)",l.textAlign="left",l.textBaseline="middle",l.fillText(u.title,u.x+6,u.y)},onNodeClick:r=>{a(`/n/${encodeURIComponent(r.id)}`)}})}),s.jsx("button",{type:"button",onClick:c,className:"absolute right-3 bottom-3 rounded-md border border-border bg-card/90 px-3 py-1.5 text-xs text-fg-muted shadow-sm backdrop-blur hover:text-accent",children:"Fit to screen"})]})}function V(e){const t=[e.path??e.id,`${e.degree} link${e.degree===1?"":"s"}`];return e.tags.length>0&&t.push(`tags: ${e.tags.join(", ")}`),e.summary&&t.push(e.summary),t.join(`
`)}function G(e){return e.startsWith("hsl(")?e.replace("hsl(","hsla(").replace(")",", 0.2)"):e}function b(e){return typeof e=="string"?e:e&&typeof e=="object"&&"id"in e?String(e.id):""}function B({error:e}){const t=e instanceof I;return s.jsx("div",{className:"flex h-full items-center justify-center p-10",children:s.jsxs("div",{className:"max-w-md rounded-md border border-red-500/30 bg-red-500/5 p-6",children:[s.jsx("p",{className:"mb-2 font-medium text-red-400",children:t?"Session expired":"Could not load vault"}),s.jsx("p",{className:"mb-4 text-sm text-fg-muted",children:e.message}),t?s.jsx(v,{to:"/add",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Reconnect vault"}):null]})})}export{O as VaultGraph};
import{aa as r,r as e,L as i}from"./index-BDPMEkxL.js";function m(c){let s;try{s=new URL(c)}catch{return!1}const a=s.pathname.split("/").filter(Boolean);return!(a.length>=2&&a[0]==="vault")}function u(){const c=r(t=>t.vaults),s=r(t=>t.activeVaultId),a=r(t=>t.removeVault),o=r(t=>t.setActiveVault),l=Object.values(c).sort((t,n)=>t.name.localeCompare(n.name));return e.jsxs("div",{className:"mx-auto max-w-3xl px-6 py-16",children:[e.jsxs("div",{className:"mb-8 flex items-center justify-between",children:[e.jsx("h1",{className:"font-serif text-4xl tracking-tight",children:"Vaults"}),e.jsx(i,{to:"/add",className:"rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Add vault"})]}),l.length===0?e.jsx("p",{className:"text-fg-muted",children:"No vaults connected yet."}):e.jsx("ul",{className:"space-y-3",children:l.map(t=>{const n=t.id===s,d=m(t.url);return e.jsxs("li",{className:"rounded-lg border border-border bg-card p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"font-serif text-lg text-fg",children:t.name}),n?e.jsx("span",{className:"rounded bg-accent/10 px-2 py-0.5 text-xs text-accent",children:"active"}):null,e.jsx("span",{className:"rounded border border-border px-2 py-0.5 text-xs text-fg-dim",children:t.scope}),d?e.jsx("span",{className:"rounded border border-amber-500/40 bg-amber-500/10 px-2 py-0.5 text-xs text-amber-500",children:"needs reconnect"}):null]}),e.jsx("p",{className:"mt-1 truncate font-mono text-xs text-fg-muted",children:t.url})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-4 text-sm",children:[n?null:e.jsx("button",{type:"button",onClick:()=>o(t.id),className:"text-fg-muted hover:text-accent",children:"Make active"}),e.jsx("button",{type:"button",onClick:()=>{confirm(`Remove ${t.name}? The access token will be deleted.`)&&a(t.id)},className:"text-red-400 hover:text-red-300",children:"Remove"})]})]}),d?e.jsxs("p",{className:"mt-3 rounded border border-amber-500/30 bg-amber-500/5 px-3 py-2 text-xs text-amber-500",children:["Vault now serves under ",e.jsx("code",{children:"/vault/<name>/"}),". This stored URL is from the older scheme and won't reach the new endpoints. Remove this entry and"," ",e.jsx(i,{to:"/add",className:"underline",children:"add it again"})," ","— discovery will pick the right URL automatically."]}):null]},t.id)})})]})}export{u as Vaults};
try{self["workbox:window:7.4.0"]&&_()}catch{}function b(t,r){return new Promise((function(n){var u=new MessageChannel;u.port1.onmessage=function(s){n(s.data)},t.postMessage(r,[u.port2])}))}function P(t,r){(r==null||r>t.length)&&(r=t.length);for(var n=0,u=Array(r);n<r;n++)u[n]=t[n];return u}function j(t,r,n){return r&&(function(u,s){for(var c=0;c<s.length;c++){var o=s[c];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(u,W(o.key),o)}})(t.prototype,r),Object.defineProperty(t,"prototype",{writable:!1}),t}function S(t,r){var n=typeof Symbol<"u"&&t[Symbol.iterator]||t["@@iterator"];if(n)return(n=n.call(t)).next.bind(n);if(Array.isArray(t)||(n=(function(s,c){if(s){if(typeof s=="string")return P(s,c);var o={}.toString.call(s).slice(8,-1);return o==="Object"&&s.constructor&&(o=s.constructor.name),o==="Map"||o==="Set"?Array.from(s):o==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(o)?P(s,c):void 0}})(t))||r){n&&(t=n);var u=0;return function(){return u>=t.length?{done:!0}:{done:!1,value:t[u++]}}}throw new TypeError(`Invalid attempt to iterate non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function w(t,r){return w=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(n,u){return n.__proto__=u,n},w(t,r)}function W(t){var r=(function(n,u){if(typeof n!="object"||!n)return n;var s=n[Symbol.toPrimitive];if(s!==void 0){var c=s.call(n,u);if(typeof c!="object")return c;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(n)})(t,"string");return typeof r=="symbol"?r:r+""}try{self["workbox:core:7.4.0"]&&_()}catch{}var m=function(){var t=this;this.promise=new Promise((function(r,n){t.resolve=r,t.reject=n}))};function y(t,r){var n=location.href;return new URL(t,n).href===new URL(r,n).href}var d=function(t,r){this.type=t,Object.assign(this,r)};function l(t,r,n){return t&&t.then||(t=Promise.resolve(t)),r?t.then(r):t}function k(){}var L={type:"SKIP_WAITING"};function E(t,r){return t&&t.then?t.then(k):Promise.resolve()}var O=(function(t){function r(c,o){var e,i;return o===void 0&&(o={}),(e=t.call(this)||this).nn={},e.tn=0,e.rn=new m,e.en=new m,e.on=new m,e.un=0,e.an=new Set,e.cn=function(){var f=e.fn,a=f.installing;e.tn>0||!y(a.scriptURL,e.sn.toString())||performance.now()>e.un+6e4?(e.vn=a,f.removeEventListener("updatefound",e.cn)):(e.hn=a,e.an.add(a),e.rn.resolve(a)),++e.tn,a.addEventListener("statechange",e.ln)},e.ln=function(f){var a=e.fn,v=f.target,h=v.state,p=v===e.vn,g={sw:v,isExternal:p,originalEvent:f};!p&&e.mn&&(g.isUpdate=!0),e.dispatchEvent(new d(h,g)),h==="installed"?e.wn=self.setTimeout((function(){h==="installed"&&a.waiting===v&&e.dispatchEvent(new d("waiting",g))}),200):h==="activating"&&(clearTimeout(e.wn),p||e.en.resolve(v))},e.yn=function(f){var a=e.hn,v=a!==navigator.serviceWorker.controller;e.dispatchEvent(new d("controlling",{isExternal:v,originalEvent:f,sw:a,isUpdate:e.mn})),v||e.on.resolve(a)},e.gn=(i=function(f){var a=f.data,v=f.ports,h=f.source;return l(e.getSW(),(function(){e.an.has(h)&&e.dispatchEvent(new d("message",{data:a,originalEvent:f,ports:v,sw:h}))}))},function(){for(var f=[],a=0;a<arguments.length;a++)f[a]=arguments[a];try{return Promise.resolve(i.apply(this,f))}catch(v){return Promise.reject(v)}}),e.sn=c,e.nn=o,navigator.serviceWorker.addEventListener("message",e.gn),e}var n,u;u=t,(n=r).prototype=Object.create(u.prototype),n.prototype.constructor=n,w(n,u);var s=r.prototype;return s.register=function(c){var o=(c===void 0?{}:c).immediate,e=o!==void 0&&o;try{var i=this;return l((function(f,a){var v=f();return v&&v.then?v.then(a):a(v)})((function(){if(!e&&document.readyState!=="complete")return E(new Promise((function(f){return window.addEventListener("load",f)})))}),(function(){return i.mn=!!navigator.serviceWorker.controller,i.dn=i.pn(),l(i.bn(),(function(f){i.fn=f,i.dn&&(i.hn=i.dn,i.en.resolve(i.dn),i.on.resolve(i.dn),i.dn.addEventListener("statechange",i.ln,{once:!0}));var a=i.fn.waiting;return a&&y(a.scriptURL,i.sn.toString())&&(i.hn=a,Promise.resolve().then((function(){i.dispatchEvent(new d("waiting",{sw:a,wasWaitingBeforeRegister:!0}))})).then((function(){}))),i.hn&&(i.rn.resolve(i.hn),i.an.add(i.hn)),i.fn.addEventListener("updatefound",i.cn),navigator.serviceWorker.addEventListener("controllerchange",i.yn),i.fn}))})))}catch(f){return Promise.reject(f)}},s.update=function(){try{return this.fn?l(E(this.fn.update())):l()}catch(c){return Promise.reject(c)}},s.getSW=function(){return this.hn!==void 0?Promise.resolve(this.hn):this.rn.promise},s.messageSW=function(c){try{return l(this.getSW(),(function(o){return b(o,c)}))}catch(o){return Promise.reject(o)}},s.messageSkipWaiting=function(){this.fn&&this.fn.waiting&&b(this.fn.waiting,L)},s.pn=function(){var c=navigator.serviceWorker.controller;return c&&y(c.scriptURL,this.sn.toString())?c:void 0},s.bn=function(){try{var c=this;return l((function(o,e){try{var i=o()}catch(f){return e(f)}return i&&i.then?i.then(void 0,e):i})((function(){return l(navigator.serviceWorker.register(c.sn,c.nn),(function(o){return c.un=performance.now(),o}))}),(function(o){throw o})))}catch(o){return Promise.reject(o)}},j(r,[{key:"active",get:function(){return this.en.promise}},{key:"controlling",get:function(){return this.on.promise}}])})((function(){function t(){this.Pn=new Map}var r=t.prototype;return r.addEventListener=function(n,u){this.jn(n).add(u)},r.removeEventListener=function(n,u){this.jn(n).delete(u)},r.dispatchEvent=function(n){n.target=this;for(var u,s=S(this.jn(n.type));!(u=s()).done;)(0,u.value)(n)},r.jn=function(n){return this.Pn.has(n)||this.Pn.set(n,new Set),this.Pn.get(n)},t})());export{O as Workbox,d as WorkboxEvent,b as messageSW};
define(["exports"],function(t){"use strict";try{self["workbox:core:7.4.0"]&&_()}catch(t){}const e=(t,...e)=>{let s=t;return e.length>0&&(s+=` :: ${JSON.stringify(e)}`),s};class s extends Error{constructor(t,s){super(e(t,s)),this.name=t,this.details=s}}try{self["workbox:routing:7.4.0"]&&_()}catch(t){}const n=t=>t&&"object"==typeof t?t:{handle:t};class i{constructor(t,e,s="GET"){this.handler=n(e),this.match=t,this.method=s}setCatchHandler(t){this.catchHandler=n(t)}}class r extends i{constructor(t,e,s){super(({url:e})=>{const s=t.exec(e.href);if(s&&(e.origin===location.origin||0===s.index))return s.slice(1)},e,s)}}class a{constructor(){this.t=new Map,this.i=new Map}get routes(){return this.t}addFetchListener(){self.addEventListener("fetch",t=>{const{request:e}=t,s=this.handleRequest({request:e,event:t});s&&t.respondWith(s)})}addCacheListener(){self.addEventListener("message",t=>{if(t.data&&"CACHE_URLS"===t.data.type){const{payload:e}=t.data,s=Promise.all(e.urlsToCache.map(e=>{"string"==typeof e&&(e=[e]);const s=new Request(...e);return this.handleRequest({request:s,event:t})}));t.waitUntil(s),t.ports&&t.ports[0]&&s.then(()=>t.ports[0].postMessage(!0))}})}handleRequest({request:t,event:e}){const s=new URL(t.url,location.href);if(!s.protocol.startsWith("http"))return;const n=s.origin===location.origin,{params:i,route:r}=this.findMatchingRoute({event:e,request:t,sameOrigin:n,url:s});let a=r&&r.handler;const o=t.method;if(!a&&this.i.has(o)&&(a=this.i.get(o)),!a)return;let c;try{c=a.handle({url:s,request:t,event:e,params:i})}catch(t){c=Promise.reject(t)}const h=r&&r.catchHandler;return c instanceof Promise&&(this.o||h)&&(c=c.catch(async n=>{if(h)try{return await h.handle({url:s,request:t,event:e,params:i})}catch(t){t instanceof Error&&(n=t)}if(this.o)return this.o.handle({url:s,request:t,event:e});throw n})),c}findMatchingRoute({url:t,sameOrigin:e,request:s,event:n}){const i=this.t.get(s.method)||[];for(const r of i){let i;const a=r.match({url:t,sameOrigin:e,request:s,event:n});if(a)return i=a,(Array.isArray(i)&&0===i.length||a.constructor===Object&&0===Object.keys(a).length||"boolean"==typeof a)&&(i=void 0),{route:r,params:i}}return{}}setDefaultHandler(t,e="GET"){this.i.set(e,n(t))}setCatchHandler(t){this.o=n(t)}registerRoute(t){this.t.has(t.method)||this.t.set(t.method,[]),this.t.get(t.method).push(t)}unregisterRoute(t){if(!this.t.has(t.method))throw new s("unregister-route-but-not-found-with-method",{method:t.method});const e=this.t.get(t.method).indexOf(t);if(!(e>-1))throw new s("unregister-route-route-not-registered");this.t.get(t.method).splice(e,1)}}let o;const c=()=>(o||(o=new a,o.addFetchListener(),o.addCacheListener()),o);function h(t,e,n){let a;if("string"==typeof t){const s=new URL(t,location.href);a=new i(({url:t})=>t.href===s.href,e,n)}else if(t instanceof RegExp)a=new r(t,e,n);else if("function"==typeof t)a=new i(t,e,n);else{if(!(t instanceof i))throw new s("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});a=t}return c().registerRoute(a),a}const u={googleAnalytics:"googleAnalytics",precache:"precache-v2",prefix:"workbox",runtime:"runtime",suffix:"undefined"!=typeof registration?registration.scope:""},l=t=>[u.prefix,t,u.suffix].filter(t=>t&&t.length>0).join("-"),f=t=>t||l(u.precache),w=t=>t||l(u.runtime);function d(t){t.then(()=>{})}const p=new Set;function y(){return y=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var s=arguments[e];for(var n in s)({}).hasOwnProperty.call(s,n)&&(t[n]=s[n])}return t},y.apply(null,arguments)}let m,g;const R=new WeakMap,v=new WeakMap,b=new WeakMap,q=new WeakMap,D=new WeakMap;let U={get(t,e,s){if(t instanceof IDBTransaction){if("done"===e)return v.get(t);if("objectStoreNames"===e)return t.objectStoreNames||b.get(t);if("store"===e)return s.objectStoreNames[1]?void 0:s.objectStore(s.objectStoreNames[0])}return I(t[e])},set:(t,e,s)=>(t[e]=s,!0),has:(t,e)=>t instanceof IDBTransaction&&("done"===e||"store"===e)||e in t};function x(t){return t!==IDBDatabase.prototype.transaction||"objectStoreNames"in IDBTransaction.prototype?(g||(g=[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey])).includes(t)?function(...e){return t.apply(C(this),e),I(R.get(this))}:function(...e){return I(t.apply(C(this),e))}:function(e,...s){const n=t.call(C(this),e,...s);return b.set(n,e.sort?e.sort():[e]),I(n)}}function L(t){return"function"==typeof t?x(t):(t instanceof IDBTransaction&&function(t){if(v.has(t))return;const e=new Promise((e,s)=>{const n=()=>{t.removeEventListener("complete",i),t.removeEventListener("error",r),t.removeEventListener("abort",r)},i=()=>{e(),n()},r=()=>{s(t.error||new DOMException("AbortError","AbortError")),n()};t.addEventListener("complete",i),t.addEventListener("error",r),t.addEventListener("abort",r)});v.set(t,e)}(t),e=t,(m||(m=[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction])).some(t=>e instanceof t)?new Proxy(t,U):t);var e}function I(t){if(t instanceof IDBRequest)return function(t){const e=new Promise((e,s)=>{const n=()=>{t.removeEventListener("success",i),t.removeEventListener("error",r)},i=()=>{e(I(t.result)),n()},r=()=>{s(t.error),n()};t.addEventListener("success",i),t.addEventListener("error",r)});return e.then(e=>{e instanceof IDBCursor&&R.set(e,t)}).catch(()=>{}),D.set(e,t),e}(t);if(q.has(t))return q.get(t);const e=L(t);return e!==t&&(q.set(t,e),D.set(e,t)),e}const C=t=>D.get(t);const E=["get","getKey","getAll","getAllKeys","count"],N=["put","add","delete","clear"],O=new Map;function B(t,e){if(!(t instanceof IDBDatabase)||e in t||"string"!=typeof e)return;if(O.get(e))return O.get(e);const s=e.replace(/FromIndex$/,""),n=e!==s,i=N.includes(s);if(!(s in(n?IDBIndex:IDBObjectStore).prototype)||!i&&!E.includes(s))return;const r=async function(t,...e){const r=this.transaction(t,i?"readwrite":"readonly");let a=r.store;return n&&(a=a.index(e.shift())),(await Promise.all([a[s](...e),i&&r.done]))[0]};return O.set(e,r),r}U=(t=>y({},t,{get:(e,s,n)=>B(e,s)||t.get(e,s,n),has:(e,s)=>!!B(e,s)||t.has(e,s)}))(U);try{self["workbox:expiration:7.4.0"]&&_()}catch(t){}const k="cache-entries",M=t=>{const e=new URL(t,location.href);return e.hash="",e.href};class T{constructor(t){this.h=null,this.u=t}l(t){const e=t.createObjectStore(k,{keyPath:"id"});e.createIndex("cacheName","cacheName",{unique:!1}),e.createIndex("timestamp","timestamp",{unique:!1})}p(t){this.l(t),this.u&&function(t,{blocked:e}={}){const s=indexedDB.deleteDatabase(t);e&&s.addEventListener("blocked",t=>e(t.oldVersion,t)),I(s).then(()=>{})}(this.u)}async setTimestamp(t,e){const s={url:t=M(t),timestamp:e,cacheName:this.u,id:this.m(t)},n=(await this.getDb()).transaction(k,"readwrite",{durability:"relaxed"});await n.store.put(s),await n.done}async getTimestamp(t){const e=await this.getDb(),s=await e.get(k,this.m(t));return null==s?void 0:s.timestamp}async expireEntries(t,e){const s=await this.getDb();let n=await s.transaction(k).store.index("timestamp").openCursor(null,"prev");const i=[];let r=0;for(;n;){const s=n.value;s.cacheName===this.u&&(t&&s.timestamp<t||e&&r>=e?i.push(n.value):r++),n=await n.continue()}const a=[];for(const t of i)await s.delete(k,t.id),a.push(t.url);return a}m(t){return this.u+"|"+M(t)}async getDb(){return this.h||(this.h=await function(t,e,{blocked:s,upgrade:n,blocking:i,terminated:r}={}){const a=indexedDB.open(t,e),o=I(a);return n&&a.addEventListener("upgradeneeded",t=>{n(I(a.result),t.oldVersion,t.newVersion,I(a.transaction),t)}),s&&a.addEventListener("blocked",t=>s(t.oldVersion,t.newVersion,t)),o.then(t=>{r&&t.addEventListener("close",()=>r()),i&&t.addEventListener("versionchange",t=>i(t.oldVersion,t.newVersion,t))}).catch(()=>{}),o}("workbox-expiration",1,{upgrade:this.p.bind(this)})),this.h}}class j{constructor(t,e={}){this.R=!1,this.v=!1,this.q=e.maxEntries,this.D=e.maxAgeSeconds,this.U=e.matchOptions,this.u=t,this._=new T(t)}async expireEntries(){if(this.R)return void(this.v=!0);this.R=!0;const t=this.D?Date.now()-1e3*this.D:0,e=await this._.expireEntries(t,this.q),s=await self.caches.open(this.u);for(const t of e)await s.delete(t,this.U);this.R=!1,this.v&&(this.v=!1,d(this.expireEntries()))}async updateTimestamp(t){await this._.setTimestamp(t,Date.now())}async isURLExpired(t){if(this.D){const e=await this._.getTimestamp(t),s=Date.now()-1e3*this.D;return void 0===e||e<s}return!1}async delete(){this.v=!1,await this._.expireEntries(1/0)}}try{self["workbox:cacheable-response:7.4.0"]&&_()}catch(t){}class W{constructor(t={}){this.L=t.statuses,this.I=t.headers}isResponseCacheable(t){let e=!0;return this.L&&(e=this.L.includes(t.status)),this.I&&e&&(e=Object.keys(this.I).some(e=>t.headers.get(e)===this.I[e])),e}}try{self["workbox:strategies:7.4.0"]&&_()}catch(t){}const P={cacheWillUpdate:async({response:t})=>200===t.status||0===t.status?t:null};function S(t,e){const s=new URL(t);for(const t of e)s.searchParams.delete(t);return s.href}class K{constructor(){this.promise=new Promise((t,e)=>{this.resolve=t,this.reject=e})}}function A(t){return"string"==typeof t?new Request(t):t}class F{constructor(t,e){this.C={},Object.assign(this,e),this.event=e.event,this.N=t,this.O=new K,this.B=[],this.k=[...t.plugins],this.M=new Map;for(const t of this.k)this.M.set(t,{});this.event.waitUntil(this.O.promise)}async fetch(t){const{event:e}=this;let n=A(t);if("navigate"===n.mode&&e instanceof FetchEvent&&e.preloadResponse){const t=await e.preloadResponse;if(t)return t}const i=this.hasCallback("fetchDidFail")?n.clone():null;try{for(const t of this.iterateCallbacks("requestWillFetch"))n=await t({request:n.clone(),event:e})}catch(t){if(t instanceof Error)throw new s("plugin-error-request-will-fetch",{thrownErrorMessage:t.message})}const r=n.clone();try{let t;t=await fetch(n,"navigate"===n.mode?void 0:this.N.fetchOptions);for(const s of this.iterateCallbacks("fetchDidSucceed"))t=await s({event:e,request:r,response:t});return t}catch(t){throw i&&await this.runCallbacks("fetchDidFail",{error:t,event:e,originalRequest:i.clone(),request:r.clone()}),t}}async fetchAndCachePut(t){const e=await this.fetch(t),s=e.clone();return this.waitUntil(this.cachePut(t,s)),e}async cacheMatch(t){const e=A(t);let s;const{cacheName:n,matchOptions:i}=this.N,r=await this.getCacheKey(e,"read"),a=Object.assign(Object.assign({},i),{cacheName:n});s=await caches.match(r,a);for(const t of this.iterateCallbacks("cachedResponseWillBeUsed"))s=await t({cacheName:n,matchOptions:i,cachedResponse:s,request:r,event:this.event})||void 0;return s}async cachePut(t,e){const n=A(t);var i;await(i=0,new Promise(t=>setTimeout(t,i)));const r=await this.getCacheKey(n,"write");if(!e)throw new s("cache-put-with-no-response",{url:(a=r.url,new URL(String(a),location.href).href.replace(new RegExp(`^${location.origin}`),""))});var a;const o=await this.T(e);if(!o)return!1;const{cacheName:c,matchOptions:h}=this.N,u=await self.caches.open(c),l=this.hasCallback("cacheDidUpdate"),f=l?await async function(t,e,s,n){const i=S(e.url,s);if(e.url===i)return t.match(e,n);const r=Object.assign(Object.assign({},n),{ignoreSearch:!0}),a=await t.keys(e,r);for(const e of a)if(i===S(e.url,s))return t.match(e,n)}(u,r.clone(),["__WB_REVISION__"],h):null;try{await u.put(r,l?o.clone():o)}catch(t){if(t instanceof Error)throw"QuotaExceededError"===t.name&&await async function(){for(const t of p)await t()}(),t}for(const t of this.iterateCallbacks("cacheDidUpdate"))await t({cacheName:c,oldResponse:f,newResponse:o.clone(),request:r,event:this.event});return!0}async getCacheKey(t,e){const s=`${t.url} | ${e}`;if(!this.C[s]){let n=t;for(const t of this.iterateCallbacks("cacheKeyWillBeUsed"))n=A(await t({mode:e,request:n,event:this.event,params:this.params}));this.C[s]=n}return this.C[s]}hasCallback(t){for(const e of this.N.plugins)if(t in e)return!0;return!1}async runCallbacks(t,e){for(const s of this.iterateCallbacks(t))await s(e)}*iterateCallbacks(t){for(const e of this.N.plugins)if("function"==typeof e[t]){const s=this.M.get(e),n=n=>{const i=Object.assign(Object.assign({},n),{state:s});return e[t](i)};yield n}}waitUntil(t){return this.B.push(t),t}async doneWaiting(){for(;this.B.length;){const t=this.B.splice(0),e=(await Promise.allSettled(t)).find(t=>"rejected"===t.status);if(e)throw e.reason}}destroy(){this.O.resolve(null)}async T(t){let e=t,s=!1;for(const t of this.iterateCallbacks("cacheWillUpdate"))if(e=await t({request:this.request,response:e,event:this.event})||void 0,s=!0,!e)break;return s||e&&200!==e.status&&(e=void 0),e}}class H{constructor(t={}){this.cacheName=w(t.cacheName),this.plugins=t.plugins||[],this.fetchOptions=t.fetchOptions,this.matchOptions=t.matchOptions}handle(t){const[e]=this.handleAll(t);return e}handleAll(t){t instanceof FetchEvent&&(t={event:t,request:t.request});const e=t.event,s="string"==typeof t.request?new Request(t.request):t.request,n="params"in t?t.params:void 0,i=new F(this,{event:e,request:s,params:n}),r=this.j(i,s,e);return[r,this.W(r,i,s,e)]}async j(t,e,n){let i;await t.runCallbacks("handlerWillStart",{event:n,request:e});try{if(i=await this.P(e,t),!i||"error"===i.type)throw new s("no-response",{url:e.url})}catch(s){if(s instanceof Error)for(const r of t.iterateCallbacks("handlerDidError"))if(i=await r({error:s,event:n,request:e}),i)break;if(!i)throw s}for(const s of t.iterateCallbacks("handlerWillRespond"))i=await s({event:n,request:e,response:i});return i}async W(t,e,s,n){let i,r;try{i=await t}catch(r){}try{await e.runCallbacks("handlerDidRespond",{event:n,request:s,response:i}),await e.doneWaiting()}catch(t){t instanceof Error&&(r=t)}if(await e.runCallbacks("handlerDidComplete",{event:n,request:s,response:i,error:r}),e.destroy(),r)throw r}}function $(t,e){const s=e();return t.waitUntil(s),s}try{self["workbox:precaching:7.4.0"]&&_()}catch(t){}function G(t){if(!t)throw new s("add-to-cache-list-unexpected-type",{entry:t});if("string"==typeof t){const e=new URL(t,location.href);return{cacheKey:e.href,url:e.href}}const{revision:e,url:n}=t;if(!n)throw new s("add-to-cache-list-unexpected-type",{entry:t});if(!e){const t=new URL(n,location.href);return{cacheKey:t.href,url:t.href}}const i=new URL(n,location.href),r=new URL(n,location.href);return i.searchParams.set("__WB_REVISION__",e),{cacheKey:i.href,url:r.href}}class V{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:t,state:e})=>{e&&(e.originalRequest=t)},this.cachedResponseWillBeUsed=async({event:t,state:e,cachedResponse:s})=>{if("install"===t.type&&e&&e.originalRequest&&e.originalRequest instanceof Request){const t=e.originalRequest.url;s?this.notUpdatedURLs.push(t):this.updatedURLs.push(t)}return s}}}class J{constructor({precacheController:t}){this.cacheKeyWillBeUsed=async({request:t,params:e})=>{const s=(null==e?void 0:e.cacheKey)||this.S.getCacheKeyForURL(t.url);return s?new Request(s,{headers:t.headers}):t},this.S=t}}let Q,z;async function X(t,e){let n=null;if(t.url){n=new URL(t.url).origin}if(n!==self.location.origin)throw new s("cross-origin-copy-response",{origin:n});const i=t.clone(),r={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},a=function(){if(void 0===Q){const t=new Response("");if("body"in t)try{new Response(t.body),Q=!0}catch(t){Q=!1}Q=!1}return Q}()?i.body:await i.blob();return new Response(a,r)}class Y extends H{constructor(t={}){t.cacheName=f(t.cacheName),super(t),this.K=!1!==t.fallbackToNetwork,this.plugins.push(Y.copyRedirectedCacheableResponsesPlugin)}async P(t,e){const s=await e.cacheMatch(t);return s||(e.event&&"install"===e.event.type?await this.A(t,e):await this.F(t,e))}async F(t,e){let n;const i=e.params||{};if(!this.K)throw new s("missing-precache-entry",{cacheName:this.cacheName,url:t.url});{const s=i.integrity,r=t.integrity,a=!r||r===s;n=await e.fetch(new Request(t,{integrity:"no-cors"!==t.mode?r||s:void 0})),s&&a&&"no-cors"!==t.mode&&(this.H(),await e.cachePut(t,n.clone()))}return n}async A(t,e){this.H();const n=await e.fetch(t);if(!await e.cachePut(t,n.clone()))throw new s("bad-precaching-response",{url:t.url,status:n.status});return n}H(){let t=null,e=0;for(const[s,n]of this.plugins.entries())n!==Y.copyRedirectedCacheableResponsesPlugin&&(n===Y.defaultPrecacheCacheabilityPlugin&&(t=s),n.cacheWillUpdate&&e++);0===e?this.plugins.push(Y.defaultPrecacheCacheabilityPlugin):e>1&&null!==t&&this.plugins.splice(t,1)}}Y.defaultPrecacheCacheabilityPlugin={cacheWillUpdate:async({response:t})=>!t||t.status>=400?null:t},Y.copyRedirectedCacheableResponsesPlugin={cacheWillUpdate:async({response:t})=>t.redirected?await X(t):t};class Z{constructor({cacheName:t,plugins:e=[],fallbackToNetwork:s=!0}={}){this.$=new Map,this.G=new Map,this.V=new Map,this.N=new Y({cacheName:f(t),plugins:[...e,new J({precacheController:this})],fallbackToNetwork:s}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this.N}precache(t){this.addToCacheList(t),this.J||(self.addEventListener("install",this.install),self.addEventListener("activate",this.activate),this.J=!0)}addToCacheList(t){const e=[];for(const n of t){"string"==typeof n?e.push(n):n&&void 0===n.revision&&e.push(n.url);const{cacheKey:t,url:i}=G(n),r="string"!=typeof n&&n.revision?"reload":"default";if(this.$.has(i)&&this.$.get(i)!==t)throw new s("add-to-cache-list-conflicting-entries",{firstEntry:this.$.get(i),secondEntry:t});if("string"!=typeof n&&n.integrity){if(this.V.has(t)&&this.V.get(t)!==n.integrity)throw new s("add-to-cache-list-conflicting-integrities",{url:i});this.V.set(t,n.integrity)}if(this.$.set(i,t),this.G.set(i,r),e.length>0){const t=`Workbox is precaching URLs without revision info: ${e.join(", ")}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(t)}}}install(t){return $(t,async()=>{const e=new V;this.strategy.plugins.push(e);for(const[e,s]of this.$){const n=this.V.get(s),i=this.G.get(e),r=new Request(e,{integrity:n,cache:i,credentials:"same-origin"});await Promise.all(this.strategy.handleAll({params:{cacheKey:s},request:r,event:t}))}const{updatedURLs:s,notUpdatedURLs:n}=e;return{updatedURLs:s,notUpdatedURLs:n}})}activate(t){return $(t,async()=>{const t=await self.caches.open(this.strategy.cacheName),e=await t.keys(),s=new Set(this.$.values()),n=[];for(const i of e)s.has(i.url)||(await t.delete(i),n.push(i.url));return{deletedURLs:n}})}getURLsToCacheKeys(){return this.$}getCachedURLs(){return[...this.$.keys()]}getCacheKeyForURL(t){const e=new URL(t,location.href);return this.$.get(e.href)}getIntegrityForCacheKey(t){return this.V.get(t)}async matchPrecache(t){const e=t instanceof Request?t.url:t,s=this.getCacheKeyForURL(e);if(s){return(await self.caches.open(this.strategy.cacheName)).match(s)}}createHandlerBoundToURL(t){const e=this.getCacheKeyForURL(t);if(!e)throw new s("non-precached-url",{url:t});return s=>(s.request=new Request(t),s.params=Object.assign({cacheKey:e},s.params),this.strategy.handle(s))}}const tt=()=>(z||(z=new Z),z);class et extends i{constructor(t,e){super(({request:s})=>{const n=t.getURLsToCacheKeys();for(const i of function*(t,{ignoreURLParametersMatching:e=[/^utm_/,/^fbclid$/],directoryIndex:s="index.html",cleanURLs:n=!0,urlManipulation:i}={}){const r=new URL(t,location.href);r.hash="",yield r.href;const a=function(t,e=[]){for(const s of[...t.searchParams.keys()])e.some(t=>t.test(s))&&t.searchParams.delete(s);return t}(r,e);if(yield a.href,s&&a.pathname.endsWith("/")){const t=new URL(a.href);t.pathname+=s,yield t.href}if(n){const t=new URL(a.href);t.pathname+=".html",yield t.href}if(i){const t=i({url:r});for(const e of t)yield e.href}}(s.url,e)){const e=n.get(i);if(e){return{cacheKey:e,integrity:t.getIntegrityForCacheKey(e)}}}},t.strategy)}}t.CacheableResponsePlugin=class{constructor(t){this.cacheWillUpdate=async({response:t})=>this.X.isResponseCacheable(t)?t:null,this.X=new W(t)}},t.ExpirationPlugin=class{constructor(t={}){this.cachedResponseWillBeUsed=async({event:t,request:e,cacheName:s,cachedResponse:n})=>{if(!n)return null;const i=this.Y(n),r=this.Z(s);d(r.expireEntries());const a=r.updateTimestamp(e.url);if(t)try{t.waitUntil(a)}catch(t){}return i?n:null},this.cacheDidUpdate=async({cacheName:t,request:e})=>{const s=this.Z(t);await s.updateTimestamp(e.url),await s.expireEntries()},this.tt=t,this.D=t.maxAgeSeconds,this.et=new Map,t.purgeOnQuotaError&&function(t){p.add(t)}(()=>this.deleteCacheAndMetadata())}Z(t){if(t===w())throw new s("expire-custom-caches-only");let e=this.et.get(t);return e||(e=new j(t,this.tt),this.et.set(t,e)),e}Y(t){if(!this.D)return!0;const e=this.st(t);if(null===e)return!0;return e>=Date.now()-1e3*this.D}st(t){if(!t.headers.has("date"))return null;const e=t.headers.get("date"),s=new Date(e).getTime();return isNaN(s)?null:s}async deleteCacheAndMetadata(){for(const[t,e]of this.et)await self.caches.delete(t),await e.delete();this.et=new Map}},t.NavigationRoute=class extends i{constructor(t,{allowlist:e=[/./],denylist:s=[]}={}){super(t=>this.nt(t),t),this.it=e,this.rt=s}nt({url:t,request:e}){if(e&&"navigate"!==e.mode)return!1;const s=t.pathname+t.search;for(const t of this.rt)if(t.test(s))return!1;return!!this.it.some(t=>t.test(s))}},t.StaleWhileRevalidate=class extends H{constructor(t={}){super(t),this.plugins.some(t=>"cacheWillUpdate"in t)||this.plugins.unshift(P)}async P(t,e){const n=e.fetchAndCachePut(t).catch(()=>{});e.waitUntil(n);let i,r=await e.cacheMatch(t);if(r);else try{r=await n}catch(t){t instanceof Error&&(i=t)}if(!r)throw new s("no-response",{url:t.url,error:i});return r}},t.cleanupOutdatedCaches=function(){self.addEventListener("activate",t=>{const e=f();t.waitUntil((async(t,e="-precache-")=>{const s=(await self.caches.keys()).filter(s=>s.includes(e)&&s.includes(self.registration.scope)&&s!==t);return await Promise.all(s.map(t=>self.caches.delete(t))),s})(e).then(t=>{}))})},t.createHandlerBoundToURL=function(t){return tt().createHandlerBoundToURL(t)},t.precacheAndRoute=function(t,e){!function(t){tt().precache(t)}(t),function(t){const e=tt();h(new et(e,t))}(e)},t.registerRoute=h});
+2
-2

@@ -22,4 +22,4 @@ <!doctype html>

</script>
<script type="module" crossorigin src="/notes/assets/index-DKKYWfqC.js"></script>
<link rel="stylesheet" crossorigin href="/notes/assets/index-BU6cVU21.css">
<script type="module" crossorigin src="/notes/assets/index-BDPMEkxL.js"></script>
<link rel="stylesheet" crossorigin href="/notes/assets/index-D_L2igjK.css">
<link rel="manifest" href="/notes/manifest.webmanifest"></head>

@@ -26,0 +26,0 @@ <body>

@@ -1,1 +0,1 @@

if(!self.define){let e,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e}));self.define=(n,l)=>{const r=e||("document"in self?document.currentScript.src:"")||location.href;if(s[r])return;let a={};const o=e=>i(e,r),t={module:{uri:r},exports:a,require:o};s[r]=Promise.all(n.map(e=>t[e]||o(e))).then(e=>(l(...e),a))}}define(["./workbox-d24cdb67"],function(e){"use strict";self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.precacheAndRoute([{url:"pwa-64x64.png",revision:"52bb73fe0f7c4274aa55047dc0d5479d"},{url:"pwa-512x512.png",revision:"ebdabf19d41be24e3f47062e89399c09"},{url:"pwa-192x192.png",revision:"ec3f52a07bade7b8a295997c236dac75"},{url:"maskable-icon-512x512.png",revision:"e0d671a48eed68b28f8e7ded8a86ef88"},{url:"manifest.webmanifest",revision:"4e69789fa00f6df17850c3426d2041a9"},{url:"index.html",revision:"64fa908326b71b0a23b8793334255ad8"},{url:"icon.svg",revision:"899549fbb9d379c3b78ab012abe72061"},{url:"favicon.ico",revision:"01d978be2c7b93a7348d91107b5bf8ad"},{url:"apple-touch-icon-180x180.png",revision:"dd71bb172b849f6328130ba825ae606d"},{url:"assets/workbox-window.prod.es5-BIl4cyR9.js",revision:null},{url:"assets/useAttachmentUploader-vNDFzDKT.js",revision:null},{url:"assets/react-force-graph-2d-YVoN3oXw.js",revision:null},{url:"assets/index-DKKYWfqC.js",revision:null},{url:"assets/index-BU6cVU21.css",revision:null},{url:"assets/dates-DfXc2iZW.js",revision:null},{url:"assets/Vaults-5R2-DK5a.js",revision:null},{url:"assets/VaultGraph-DqP0DsuL.js",revision:null},{url:"assets/Today-C2Kb8hh1.js",revision:null},{url:"assets/Tags-6zA2UpSB.js",revision:null},{url:"assets/Settings-BSqpi3KX.js",revision:null},{url:"assets/PinArchiveButtons-CCZolBUN.js",revision:null},{url:"assets/OAuthCallback-CdZpQ983.js",revision:null},{url:"assets/NoteView-BRQa1cQ-.js",revision:null},{url:"assets/NoteRenderer-BuDmZBkP.js",revision:null},{url:"assets/NoteNew-BQJfAS3F.js",revision:null},{url:"assets/NoteEditor-DABNXYJR.js",revision:null},{url:"assets/Capture-ClHlAbHb.js",revision:null},{url:"assets/Calendar-Bbh8ywV0.js",revision:null},{url:"assets/AddVault-CE0_abUh.js",revision:null},{url:"assets/Activity-DEE2UNMC.js",revision:null},{url:"apple-touch-icon-180x180.png",revision:"dd71bb172b849f6328130ba825ae606d"},{url:"favicon.ico",revision:"01d978be2c7b93a7348d91107b5bf8ad"},{url:"icon.svg",revision:"899549fbb9d379c3b78ab012abe72061"},{url:"maskable-icon-512x512.png",revision:"e0d671a48eed68b28f8e7ded8a86ef88"},{url:"pwa-192x192.png",revision:"ec3f52a07bade7b8a295997c236dac75"},{url:"pwa-512x512.png",revision:"ebdabf19d41be24e3f47062e89399c09"},{url:"pwa-64x64.png",revision:"52bb73fe0f7c4274aa55047dc0d5479d"},{url:"manifest.webmanifest",revision:"4e69789fa00f6df17850c3426d2041a9"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/notes/index.html"),{denylist:[/^\/api\//,/^\/oauth\//,/^\/\.well-known\//]})),e.registerRoute(/^https:\/\/fonts\.(googleapis|gstatic)\.com\/.*/i,new e.StaleWhileRevalidate({cacheName:"google-fonts",plugins:[new e.ExpirationPlugin({maxEntries:30,maxAgeSeconds:2592e3}),new e.CacheableResponsePlugin({statuses:[0,200]})]}),"GET")});
if(!self.define){let e,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e}));self.define=(n,l)=>{const r=e||("document"in self?document.currentScript.src:"")||location.href;if(s[r])return;let a={};const o=e=>i(e,r),t={module:{uri:r},exports:a,require:o};s[r]=Promise.all(n.map(e=>t[e]||o(e))).then(e=>(l(...e),a))}}define(["./workbox-b9acee4e"],function(e){"use strict";self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.precacheAndRoute([{url:"pwa-64x64.png",revision:"52bb73fe0f7c4274aa55047dc0d5479d"},{url:"pwa-512x512.png",revision:"ebdabf19d41be24e3f47062e89399c09"},{url:"pwa-192x192.png",revision:"ec3f52a07bade7b8a295997c236dac75"},{url:"maskable-icon-512x512.png",revision:"e0d671a48eed68b28f8e7ded8a86ef88"},{url:"manifest.webmanifest",revision:"4e69789fa00f6df17850c3426d2041a9"},{url:"index.html",revision:"d074b242ddc4950517bca2c97eabb6b5"},{url:"icon.svg",revision:"899549fbb9d379c3b78ab012abe72061"},{url:"favicon.ico",revision:"01d978be2c7b93a7348d91107b5bf8ad"},{url:"apple-touch-icon-180x180.png",revision:"dd71bb172b849f6328130ba825ae606d"},{url:"assets/workbox-window.prod.es5-BBnX5xw4.js",revision:null},{url:"assets/useAttachmentUploader-CRSqlwYK.js",revision:null},{url:"assets/react-force-graph-2d-CokIfB0T.js",revision:null},{url:"assets/index-D_L2igjK.css",revision:null},{url:"assets/index-BDPMEkxL.js",revision:null},{url:"assets/dates-BGZoWpL2.js",revision:null},{url:"assets/Vaults-GFmUZ3tT.js",revision:null},{url:"assets/VaultGraph-9bEHl7fl.js",revision:null},{url:"assets/Today-Co3rl2Tl.js",revision:null},{url:"assets/Tags-C2seZlc0.js",revision:null},{url:"assets/Settings-DpNYPt6E.js",revision:null},{url:"assets/PinArchiveButtons-DogtDLiB.js",revision:null},{url:"assets/OAuthCallback-CHpF2exs.js",revision:null},{url:"assets/NoteView-B8BN-Dm4.js",revision:null},{url:"assets/NoteRenderer-cz03kLyS.js",revision:null},{url:"assets/NoteNew-CTTJ_2cU.js",revision:null},{url:"assets/NoteEditor-CxoH85Is.js",revision:null},{url:"assets/Capture-C_s94G98.js",revision:null},{url:"assets/Calendar-Dgd0dTEM.js",revision:null},{url:"assets/AddVault-DA_s9Ua2.js",revision:null},{url:"assets/Activity-B6k-9wWy.js",revision:null},{url:"apple-touch-icon-180x180.png",revision:"dd71bb172b849f6328130ba825ae606d"},{url:"favicon.ico",revision:"01d978be2c7b93a7348d91107b5bf8ad"},{url:"icon.svg",revision:"899549fbb9d379c3b78ab012abe72061"},{url:"maskable-icon-512x512.png",revision:"e0d671a48eed68b28f8e7ded8a86ef88"},{url:"pwa-192x192.png",revision:"ec3f52a07bade7b8a295997c236dac75"},{url:"pwa-512x512.png",revision:"ebdabf19d41be24e3f47062e89399c09"},{url:"pwa-64x64.png",revision:"52bb73fe0f7c4274aa55047dc0d5479d"},{url:"manifest.webmanifest",revision:"4e69789fa00f6df17850c3426d2041a9"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/notes/index.html"),{denylist:[/^\/api\//,/^\/oauth\//,/^\/\.well-known\//]})),e.registerRoute(/^https:\/\/fonts\.(googleapis|gstatic)\.com\/.*/i,new e.StaleWhileRevalidate({cacheName:"google-fonts",plugins:[new e.ExpirationPlugin({maxEntries:30,maxAgeSeconds:2592e3}),new e.CacheableResponsePlugin({statuses:[0,200]})]}),"GET")});
{
"name": "@openparachute/notes",
"version": "0.3.16-rc.6",
"version": "0.3.17-rc.2",
"private": false,

@@ -8,60 +8,17 @@ "type": "module",

"license": "AGPL-3.0-only",
"deprecated": "@openparachute/notes is deprecated. Use @openparachute/app + @openparachute/notes-ui via parachute-app. See https://github.com/ParachuteComputer/parachute-notes/blob/main/packages/notes-daemon/DEPRECATED.md",
"repository": {
"type": "git",
"url": "https://github.com/ParachuteComputer/parachute-notes.git"
"url": "https://github.com/ParachuteComputer/parachute-notes.git",
"directory": "packages/notes-daemon"
},
"files": ["dist", ".parachute/module.json", "README.md", "LICENSE"],
"files": ["dist", ".parachute/module.json", "README.md", "LICENSE", "CHANGELOG.md", "DEPRECATED.md"],
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"preview": "vite preview",
"test": "vitest run",
"test:watch": "vitest",
"lint": "biome check .",
"lint:fix": "biome check --write .",
"format": "biome format --write .",
"typecheck": "tsc -b --noEmit",
"build": "node scripts/build.mjs",
"test": "node scripts/build.test.mjs",
"prepublishOnly": "bun run build"
},
"dependencies": {
"@codemirror/commands": "^6.10.3",
"@codemirror/lang-markdown": "^6.5.0",
"@codemirror/language": "^6.12.3",
"@codemirror/state": "^6.6.0",
"@codemirror/view": "^6.41.1",
"@tanstack/react-query": "^5",
"highlight.js": "^11.11.1",
"idb": "^8.0.3",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-force-graph-2d": "^1.29.1",
"react-markdown": "^10.1.0",
"react-router": "^7",
"rehype-highlight": "^7.0.2",
"remark-gfm": "^4.0.1",
"zustand": "^5"
},
"devDependencies": {
"@biomejs/biome": "^1.9.4",
"@tailwindcss/vite": "^4.1.0",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.1.0",
"@types/node": "^22",
"@types/react": "^19.1.0",
"@types/react-dom": "^19.1.0",
"@vite-pwa/assets-generator": "^1.0.2",
"@vitejs/plugin-react": "^4.3.0",
"fake-indexeddb": "^6.2.5",
"jsdom": "^25.0.1",
"remark-parse": "^11.0.0",
"remark-stringify": "^11.0.0",
"tailwindcss": "^4.1.0",
"typescript": "~5.6.0",
"unified": "^11.0.5",
"vite": "^6.0.0",
"vite-plugin-pwa": "^1.2.0",
"vitest": "^3",
"workbox-window": "^7.4.0"
"@openparachute/notes-ui": "workspace:*"
}
}

@@ -1,3 +0,7 @@

# Parachute Notes
> ⚠️ **DEPRECATED** — this daemon is deprecated as of 2026-05-22.
> Notes ships as a UI bundle (`@openparachute/notes-ui`) hosted by [parachute-app](https://github.com/ParachuteComputer/parachute-app).
> See [DEPRECATED.md](./DEPRECATED.md) for the migration path.
# Parachute Notes (`@openparachute/notes`)
The default frontend for [Parachute](https://parachute.computer). Browse, edit, and capture in any [Parachute Vault](https://github.com/ParachuteComputer/parachute-vault).

@@ -7,2 +11,9 @@

> **Monorepo note.** This package (`@openparachute/notes`) is the module-shaped wrapper hub installs via `parachute install notes`. The SPA source lives in [`../notes-ui`](../notes-ui), which also publishes as `@openparachute/notes-ui` for installation under [parachute-app][app]. Both packages ship the same `dist/`. Source code edits happen in `../notes-ui/src/`; this package's build step (`scripts/build.mjs`) copies notes-ui's `dist/` into its own publish payload.
>
> The migration arc retiring this package in favor of notes-ui-under-parachute-app is documented in [design Section 16][s16]. This is Phase 1 (additive). Phase 2 deprecates the module form; Phase 3 retires it.
>
> [app]: https://github.com/ParachuteComputer/parachute-app
> [s16]: https://github.com/ParachuteComputer/parachute.computer/blob/main/design/2026-05-21-parachute-apps-design.md#16-notes-migration-to-app
## Status

@@ -28,2 +39,4 @@

From the workspace root (`parachute-notes/`):
```sh

@@ -34,3 +47,3 @@ bun install

Open the dev URL, paste your vault URL, connect.
Open the dev URL, paste your vault URL, connect. `bun run dev` dispatches to `notes-ui`'s Vite dev server.

@@ -55,16 +68,19 @@ ## What it gives you

bun run build
# static output in dist/ — host anywhere
# notes-ui builds first into packages/notes-ui/dist/;
# this package's build step copies that into packages/notes-daemon/dist/.
```
The output `dist/` here is what hub serves via `parachute start notes` — host that directory anywhere if you want to bypass hub.
## Development
Vite + React 19 + TypeScript (strict), Tailwind CSS v4, Biome for lint/format, Vitest + Testing Library for tests.
Vite + React 19 + TypeScript (strict), Tailwind CSS v4, Biome for lint/format, Vitest + Testing Library for tests. All scripts are workspace-rooted; they dispatch to the right sub-package via `bun --filter`.
```sh
bun run dev # dev server
bun run typecheck # tsc --noEmit across the project references
bun run lint # biome check
bun run dev # notes-ui dev server (port 1942)
bun run typecheck # tsc --noEmit across notes-ui's project references
bun run lint # biome check over notes-ui
bun run lint:fix # biome check --write
bun run test # vitest run
bun run build # tsc -b && vite build
bun run test # notes-ui vitest suite, then daemon smoke test
bun run build # notes-ui vite build, then daemon dist-copy step
```

@@ -81,4 +97,15 @@

### Local-link development against hub
Aaron's `parachute` binary resolves `@openparachute/notes` via the bun-linked global. Re-establish the link after the monorepo move:
```sh
cd packages/notes-daemon
bun link
```
Then from any consumer (hub, in particular), `bun link @openparachute/notes` references the local `packages/notes-daemon/` checkout. `parachute start notes` will then serve the locally-built `dist/`.
## License
AGPL-3.0 — same as Parachute Vault.
import{u as h,a as g,r as l,j as e,N as f,L as m,b,V as y}from"./index-DKKYWfqC.js";const p=1440*60*1e3,j=5e3;function N(n,r=30,s=new Date){const d=s.getTime()-r*p,a=[];for(const t of n){const c=t.path??t.id,o=Date.parse(t.createdAt);if(Number.isFinite(o)&&o>=d&&a.push({id:`${t.id}:created`,noteId:t.id,noteName:c,kind:"created",at:t.createdAt,preview:t.preview,tags:t.tags}),t.updatedAt){const i=Date.parse(t.updatedAt);Number.isFinite(i)&&i>=d&&Number.isFinite(o)&&i-o>j&&a.push({id:`${t.id}:updated`,noteId:t.id,noteName:c,kind:"updated",at:t.updatedAt,preview:t.preview,tags:t.tags})}}return a.sort((t,c)=>Date.parse(c.at)-Date.parse(t.at)),a}const v=["today","yesterday","thisWeek","older"],k={today:"Today",yesterday:"Yesterday",thisWeek:"This week",older:"Older"};function w(n,r=new Date){const s=Date.parse(n);if(!Number.isFinite(s))return null;const d=u(r),a=u(new Date(s)),t=Math.round((d.getTime()-a.getTime())/p);return t<0||t===0?"today":t===1?"yesterday":t<7?"thisWeek":"older"}function u(n){return new Date(n.getFullYear(),n.getMonth(),n.getDate())}function D(n,r=new Date){const s={today:[],yesterday:[],thisWeek:[],older:[]};for(const d of n){const a=w(d.at,r);a&&s[a].push(d)}return s}const x=50;function F(){const n=h(i=>i.getActiveVault()),r=g(),[s,d]=l.useState(x),a=l.useMemo(()=>r.data?N(r.data):[],[r.data]),t=l.useMemo(()=>a.slice(0,s),[a,s]),c=l.useMemo(()=>D(t),[t]),o=a.length-t.length;return n?e.jsxs("div",{className:"mx-auto max-w-3xl px-4 py-6 md:px-6 md:py-10",children:[e.jsxs("header",{className:"mb-5 md:mb-6",children:[e.jsx("p",{className:"text-xs uppercase tracking-wider text-fg-dim",children:"Activity"}),e.jsx("h1",{className:"font-serif text-2xl tracking-tight md:text-3xl",children:"Recent changes"}),e.jsx("p",{className:"mt-1 text-sm text-fg-muted",children:"Last 30 days, newest first. Deletions aren't tracked yet."})]}),r.isPending?e.jsx(T,{}):r.isError?e.jsx(B,{error:r.error}):a.length===0?e.jsx(S,{}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"space-y-8",children:v.map(i=>c[i].length>0?e.jsx(E,{title:k[i],events:c[i]},i):null)}),o>0?e.jsx("div",{className:"mt-8 flex justify-center",children:e.jsxs("button",{type:"button",onClick:()=>d(i=>i+x),className:"rounded-md border border-border bg-card px-4 py-2 text-sm text-fg-muted hover:text-accent",children:["Load more (",o," remaining)"]})}):null]})]}):e.jsx(f,{to:"/",replace:!0})}function E({title:n,events:r}){return e.jsxs("section",{children:[e.jsxs("h2",{className:"mb-2 text-xs uppercase tracking-wider text-fg-dim",children:[n," (",r.length,")"]}),e.jsx("ol",{className:"divide-y divide-border rounded-md border border-border bg-card",children:r.map(s=>e.jsx("li",{children:e.jsxs(m,{to:`/n/${encodeURIComponent(s.noteId)}`,className:"block px-4 py-3 hover:bg-bg/60 focus:bg-bg/60 focus:outline-none",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-4",children:[e.jsxs("div",{className:"flex min-w-0 items-baseline gap-2",children:[e.jsx(A,{kind:s.kind}),e.jsx("span",{className:"truncate font-mono text-sm text-fg",children:s.noteName})]}),e.jsx("span",{className:"shrink-0 text-xs text-fg-dim",children:b(s.at)})]}),s.preview?e.jsx("p",{className:"mt-1 truncate text-sm text-fg-muted",children:s.preview}):null,s.tags&&s.tags.length>0?e.jsx("div",{className:"mt-2 flex flex-wrap gap-1",children:s.tags.map(d=>e.jsxs("span",{className:"rounded-md bg-border/40 px-1.5 py-0.5 text-xs text-fg-dim",children:["#",d]},d))}):null]})},s.id))})]})}function A({kind:n}){return n==="created"?e.jsx("span",{className:"shrink-0 rounded-md bg-accent/10 px-1.5 py-0.5 text-xs text-accent",children:"Created"}):e.jsx("span",{className:"shrink-0 rounded-md bg-border/40 px-1.5 py-0.5 text-xs text-fg-muted",children:"Edited"})}function S(){return e.jsxs("div",{className:"rounded-md border border-border bg-card p-10 text-center",children:[e.jsx("p",{className:"mb-4 text-fg-muted",children:"No activity in the last 30 days."}),e.jsx(m,{to:"/capture",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Open capture"})]})}function T(){return e.jsx("div",{className:"space-y-3","aria-busy":"true",children:[0,1,2,3,4].map(n=>e.jsx("div",{className:"h-16 animate-pulse rounded-md bg-border/30"},n))})}function B({error:n}){const r=n instanceof y;return e.jsxs("div",{className:"rounded-md border border-red-500/30 bg-red-500/5 p-6",children:[e.jsx("p",{className:"mb-2 font-medium text-red-400",children:r?"Session expired":"Could not load activity"}),e.jsx("p",{className:"mb-4 text-sm text-fg-muted",children:n.message}),r?e.jsx(m,{to:"/add",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Reconnect vault"}):null]})}export{F as Activity};
import{c as j,r as t,d as v,j as e,I as y,n as w,e as N,f as S}from"./index-DKKYWfqC.js";function R(){const[b]=j(),u=b.get("url")??"",[a,c]=t.useState(u),[i,l]=t.useState(null),[g,d]=t.useState(!1),[o,m]=t.useState(!1),h=t.useRef(null),x=t.useRef(u.length>0),n=v();t.useEffect(()=>{var s;(s=h.current)==null||s.focus()},[]),t.useEffect(()=>{x.current||n.status==="found"&&n.origin&&a===""&&(c(n.origin),x.current=!0)},[n.status,n.origin,a]);async function p(s){s.preventDefault(),l(null),d(!1);let f;try{f=w(a)}catch(r){l(r.message);return}m(!0);try{const{authorizeUrl:r}=await N(f);window.location.assign(r)}catch(r){r instanceof S?d(!0):l(r.message),m(!1)}}return e.jsxs("div",{className:"mx-auto max-w-xl px-6 py-16",children:[e.jsx("h1",{className:"mb-2 font-serif text-4xl tracking-tight",children:"Connect a vault"}),e.jsx("p",{className:"mb-8 text-fg-muted",children:"Paste your Parachute hub URL. You'll be taken to its consent page to authorize Parachute Notes."}),e.jsxs("form",{onSubmit:p,className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:"vault-url",className:"mb-1.5 block text-sm font-medium text-fg",children:"Hub URL"}),e.jsx("input",{id:"vault-url",ref:h,type:"url",required:!0,placeholder:"http://localhost:1939",value:a,onChange:s=>c(s.target.value),disabled:o,className:"w-full rounded-md border border-border bg-card px-3 py-2 font-mono text-sm text-fg focus:border-accent focus:outline-none"}),e.jsxs("p",{className:"mt-1.5 text-xs text-fg-dim",children:["For a local install the hub lives at ",e.jsx("code",{children:"http://localhost:1939"}),". A standalone vault URL (e.g. ",e.jsx("code",{children:"https://host/vault/default"}),") also works — Notes will OAuth against whichever issuer answers."]})]}),g?e.jsx(y,{}):null,i?e.jsx("div",{className:"rounded-md border border-red-400/30 bg-red-400/5 px-3 py-2 text-sm text-red-400",children:i}):null,e.jsx("button",{type:"submit",disabled:o||!a,className:"w-full rounded-md bg-accent px-4 py-2.5 text-sm font-medium text-white hover:bg-accent-hover disabled:cursor-not-allowed disabled:opacity-60",children:o?"Starting OAuth…":"Continue"})]})]})}export{R as AddVault};
import{u as k,c as E,a as A,r as f,j as e,N as K,L as d,V as S}from"./index-DKKYWfqC.js";import{p as y,c as j,t as P,m as T,a as V,s as N,b as i,f as C}from"./dates-DfXc2iZW.js";const _=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],x=5;function B(){const a=k(t=>t.getActiveVault()),[o]=E(),l=o.get("month"),r=y(l)??y(j()),s=A(),h=P(),v=f.useMemo(()=>T(r.year,r.month),[r.year,r.month]),$=f.useMemo(()=>{const t=new Map;if(!s.data)return t;for(const n of s.data){const c=V(n.createdAt);c&&t.set(c,(t.get(c)??0)+1)}return t},[s.data]);if(!a)return e.jsx(K,{to:"/",replace:!0});const u=N(r.year,r.month,-1),p=N(r.year,r.month,1),b=`${u.year}-${i(u.month)}`,g=`${p.year}-${i(p.month)}`,M=j(),w=`${r.year}-${i(r.month)}`===M;return e.jsxs("div",{className:"mx-auto max-w-4xl px-4 py-6 md:px-6 md:py-10",children:[e.jsxs("header",{className:"mb-6 flex flex-wrap items-baseline justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-xs uppercase tracking-wider text-fg-dim",children:"Calendar"}),e.jsx("h1",{className:"font-serif text-3xl tracking-tight",children:C(r.year,r.month)})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm",children:[e.jsxs(d,{to:`/calendar?month=${b}`,className:"rounded-md border border-border bg-card px-3 py-1.5 text-fg-muted hover:text-accent","aria-label":"Previous month",children:["← ",b]}),w?null:e.jsx(d,{to:"/calendar",className:"rounded-md border border-border bg-card px-3 py-1.5 text-fg-muted hover:text-accent",children:"This month"}),e.jsxs(d,{to:`/calendar?month=${g}`,className:"rounded-md border border-border bg-card px-3 py-1.5 text-fg-muted hover:text-accent","aria-label":"Next month",children:[g," →"]}),e.jsx(d,{to:`/today?date=${h}`,className:"rounded-md border border-border bg-card px-3 py-1.5 text-fg-muted hover:text-accent",children:"Today"})]})]}),s.isError?e.jsx(L,{error:s.error}):e.jsxs("div",{className:"rounded-md border border-border bg-card","aria-busy":s.isPending,children:[e.jsx("div",{className:"grid grid-cols-7 border-b border-border text-xs uppercase tracking-wider text-fg-dim",children:_.map(t=>e.jsx("div",{className:"px-2 py-2 text-center",children:t},t))}),e.jsx("div",{className:"grid grid-cols-7",children:v.map(t=>{const n=`${t.getFullYear()}-${i(t.getMonth()+1)}-${i(t.getDate())}`,c=t.getMonth()+1===r.month,m=$.get(n)??0,D=n===h;return e.jsxs(d,{to:`/today?date=${n}`,className:`flex min-h-20 flex-col border-b border-r border-border p-1.5 text-xs hover:bg-bg/60 focus:bg-bg/60 focus:outline-none ${c?"":"opacity-40"}`,"aria-label":`${n} — ${m} notes`,children:[e.jsx("span",{className:`mb-1 inline-flex h-6 w-6 items-center justify-center rounded-full ${D?"bg-accent text-white":"text-fg"}`,children:t.getDate()}),m>0?e.jsx(F,{count:m}):e.jsx("span",{className:"sr-only",children:"no notes"})]},n)})})]}),e.jsx("p",{className:"mt-3 text-xs text-fg-dim",children:"Each dot is a note created on that day. Click any day to open /today."})]})}function F({count:a}){const o=Math.min(a,x),l=a>x?a-x:0;return e.jsxs("span",{className:"flex flex-wrap items-center gap-0.5",children:[Array.from({length:o}).map((r,s)=>e.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-accent","aria-hidden":"true"},s)),l>0?e.jsxs("span",{className:"ml-0.5 text-[10px] text-fg-dim",children:["+",l]}):null]})}function L({error:a}){const o=a instanceof S;return e.jsxs("div",{className:"rounded-md border border-red-500/30 bg-red-500/5 p-6",children:[e.jsx("p",{className:"mb-2 font-medium text-red-400",children:o?"Session expired":"Could not load notes"}),e.jsx("p",{className:"mb-4 text-sm text-fg-muted",children:a.message}),o?e.jsx(d,{to:"/add",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Reconnect vault"}):null]})}export{B as Calendar};
import{u as xe,g as be,h as ye,i as ve,k as we,r as i,l as Y,m as ke,o as Te,p as S,q as Re,j as a,N as Se,b as je,T as Ne,s as oe,L as Ee}from"./index-DKKYWfqC.js";const Ie=["audio/webm;codecs=opus","audio/mp4","audio/ogg;codecs=opus"];function Ce(r=Ie){if(typeof MediaRecorder>"u")return null;for(const t of r)if(MediaRecorder.isTypeSupported(t))return t;return null}function Me(r){return r.startsWith("audio/webm")?"webm":r.startsWith("audio/mp4")?"m4a":r.startsWith("audio/ogg")?"ogg":r.startsWith("audio/wav")?"wav":"bin"}function Ae(r){const t=r.now??(()=>Date.now()),d=r.MediaRecorderCtor??MediaRecorder,n=new d(r.stream,{mimeType:r.mimeType}),l=[];let s="idle",m=0,A=0;n.ondataavailable=k=>{k.data&&k.data.size>0&&l.push(k.data)};const p=()=>{for(const k of r.stream.getTracks())k.stop()};return{get state(){return s},get mimeType(){return r.mimeType},start(){if(s!=="idle")throw new Error(`Cannot start from ${s}`);n.start(),m=t(),s="recording"},pause(){s==="recording"&&(n.pause(),A+=t()-m,s="paused")},resume(){s==="paused"&&(n.resume(),m=t(),s="recording")},async stop(){if(s==="idle"||s==="stopped")throw new Error(`Cannot stop from ${s}`);s==="recording"&&(A+=t()-m);const k=new Promise(x=>{n.onstop=async()=>{const L=await $e(l);x({data:L,mimeType:r.mimeType,durationMs:A})}});return n.stop(),s="stopped",p(),k},cancel(){if(s==="recording"||s==="paused")try{n.stop()}catch{}s="stopped",l.length=0,p()}}}async function De(r){const t=r;return typeof t.arrayBuffer=="function"?t.arrayBuffer():new Promise((d,n)=>{const l=new FileReader;l.onload=()=>d(l.result),l.onerror=()=>n(l.error??new Error("FileReader error")),l.readAsArrayBuffer(r)})}async function $e(r){if(r.length===0)return new ArrayBuffer(0);const t=await Promise.all(r.map(s=>De(s))),d=t.reduce((s,m)=>s+m.byteLength,0),n=new Uint8Array(d);let l=0;for(const s of t)n.set(new Uint8Array(s),l),l+=s.byteLength;return n.buffer}async function Oe(){var r;if(typeof navigator>"u"||!((r=navigator.mediaDevices)!=null&&r.getUserMedia)){const t=new Error("Microphone is not available in this browser.");throw t.kind="unavailable",t}try{return await navigator.mediaDevices.getUserMedia({audio:!0})}catch(t){const d=new Error(t instanceof Error?t.message:"Microphone permission denied."),n=t instanceof DOMException?t.name:"";throw d.kind=n==="NotFoundError"||n==="OverconstrainedError"?"no-device":"permission-denied",d}}function Le(r,t=new Date){return`memo-${t.toISOString().replace(/[:.]/g,"-").replace(/Z$/,"")}.${Me(r)}`}function se(r=new Date){const t=r.getFullYear(),d=String(r.getMonth()+1).padStart(2,"0"),n=String(r.getDate()).padStart(2,"0"),l=String(r.getHours()).padStart(2,"0"),s=String(r.getMinutes()).padStart(2,"0"),m=String(r.getSeconds()).padStart(2,"0");return`Notes/${t}/${d}-${n}/${l}-${s}-${m}`}const Pe=/(?:^|\s)#([a-zA-Z][\w-]*)/g;function Z(r){const t=new Set;for(const d of r.matchAll(Pe)){const n=oe(d[1]??"");n&&t.add(n)}return[...t]}function G(r){const t=Math.floor(r/1e3),d=Math.floor(t/60),n=t%60;return`${String(d).padStart(2,"0")}:${String(n).padStart(2,"0")}`}function Fe({moreFieldsOpenDefault:r=!1}={}){const t=xe(e=>e.getActiveVault()),d=be(e=>e.push),{db:n,blobStore:l,engine:s}=ye(),{roles:m}=ve((t==null?void 0:t.id)??null),A=we(),[p,k]=i.useState(""),[x,L]=i.useState([]),[ie,F]=i.useState(""),[ce,de]=i.useState(r),D=i.useRef(se()),J=i.useRef(!1),[j,Q]=i.useState(()=>D.current),le=i.useCallback(e=>{J.current=e.trim()!==""&&e!==D.current,Q(e)},[]),[N,ue]=i.useState(""),[c,b]=i.useState({kind:"idle"}),[me,B]=i.useState(0),$=i.useRef(null),[q,X]=i.useState(null),[pe,fe]=i.useState(0),V=i.useRef(null),E=i.useRef(null),W=i.useRef(null),P=i.useRef(!1);i.useEffect(()=>{if(c.kind!=="recording")return;const e=setInterval(()=>B(Date.now()-c.startedAt),250);return()=>clearInterval(e)},[c]),i.useEffect(()=>()=>{E.current&&URL.revokeObjectURL(E.current)},[]),i.useEffect(()=>{var e;(e=W.current)==null||e.focus()},[]);const ge=i.useCallback(async()=>{if(!(c.kind==="recording"||c.kind==="requesting")){b({kind:"requesting"});try{const e=Ce();if(!e){b({kind:"denied",message:"This browser can't record audio in a format we can save."});return}const o=await Oe(),u=Ae({stream:o,mimeType:e});V.current=u,u.start(),B(0),b({kind:"recording",startedAt:Date.now()})}catch(e){const o=e,u=o.kind==="permission-denied"?"Microphone access was denied. Update your browser's site settings to record.":o.kind==="no-device"?"No microphone was found on this device.":o instanceof Error?o.message:"Microphone is not available in this browser.";b({kind:"denied",message:u})}}},[c]),ee=i.useCallback(async()=>{const e=V.current;if(!(!e||c.kind!=="recording"))try{const o=await e.stop();V.current=null;const u=new Blob([o.data],{type:o.mimeType}),y=URL.createObjectURL(u);E.current&&URL.revokeObjectURL(E.current),E.current=y,b({kind:"have-audio",data:o.data,mimeType:o.mimeType,url:y,durationMs:o.durationMs})}catch(o){d(o instanceof Error?`Recording failed: ${o.message}`:"Recording failed.","error"),b({kind:"idle"})}},[c,d]);i.useEffect(()=>{if(c.kind!=="recording")return;const e=()=>{ee()};return window.addEventListener("pointerup",e),window.addEventListener("pointercancel",e),()=>{window.removeEventListener("pointerup",e),window.removeEventListener("pointercancel",e)}},[c,ee]);const _=i.useCallback(()=>{E.current&&(URL.revokeObjectURL(E.current),E.current=null),b({kind:"idle"}),B(0)},[]),te=i.useCallback(()=>{var e;if($.current=null,X(null),k(""),L([]),F(""),!J.current){const o=se();D.current=o,Q(o)}_(),(e=W.current)==null||e.focus()},[_]),U=c.kind==="have-audio",T=p.trim().length>0,H=(T||U)&&c.kind!=="saving",z=i.useCallback(async()=>{if(!H||!n||!t)return;if(U&&!l){d("Sync queue not ready — try again in a moment.","error");return}const e=c.kind==="have-audio"?c:null;P.current=!0,b({kind:"saving"});const o=x.filter(g=>g.length>0),u=Z(p),y=[];T&&y.push(m.captureText),e&&y.push(m.captureVoice);const v=Array.from(new Set([...y,...o,...u].filter(g=>g.length>0))),f=$.current,w=(f==null?void 0:f.localId)??Y(),I=j.trim()||D.current,C=N.trim(),h=C?{summary:C}:void 0;A&&ke(t.id,A);try{if(e){const g=new Date,O=Le(e.mimeType,g),M=Te(),R=T?`${p.trim()}
_Transcript pending._
![[${O}]]
`:`_Transcript pending._
![[${O}]]
`,ae=I;if(!l)throw new Error("blob store missing");await l.put(M,e.data,e.mimeType,t.id),await S(n,{kind:"create-note",localId:w,payload:{content:R,path:ae,...v.length?{tags:v}:{},...h?{metadata:h}:{}}},{vaultId:t.id}),await S(n,{kind:"upload-attachment",blobId:M,filename:O,mimeType:e.mimeType},{vaultId:t.id}),await S(n,{kind:"link-attachment",noteId:w,pathRef:Re(M),mimeType:e.mimeType,transcribe:!0},{vaultId:t.id})}else f!=null&&f.createCommitted?await S(n,{kind:"update-note",targetId:w,payload:{content:p,path:I,...v.length?{tags:{add:v}}:{},...h?{metadata:h}:{}}},{vaultId:t.id}):await S(n,{kind:"create-note",localId:w,payload:{content:p,path:I,...v.length?{tags:v}:{},...h?{metadata:h}:{}}},{vaultId:t.id});s==null||s.runOnce(),d(e?"Captured — syncing audio.":"Captured.","success"),te(),b({kind:"idle"}),P.current=!1}catch(g){d(g instanceof Error?`Capture failed: ${g.message}`:"Capture failed.","error"),P.current=!1,b(e?{kind:"have-audio",data:e.data,mimeType:e.mimeType,url:e.url,durationMs:e.durationMs}:{kind:"idle"})}},[H,n,t,l,A,c,U,T,x,p,j,N,m.captureText,m.captureVoice,s,d,te]),re=i.useCallback(async()=>{if(!n||!t||c.kind!=="idle"||!T)return;const e=x.filter(h=>h.length>0),o=Z(p),u=Array.from(new Set([m.captureText,...e,...o].filter(h=>h.length>0))),y=j.trim()||D.current,v=N.trim(),f=v?{summary:v}:void 0,w=$.current,I=!w,C=(w==null?void 0:w.localId)??Y();I&&($.current={localId:C,createCommitted:!0});try{I?await S(n,{kind:"create-note",localId:C,payload:{content:p,path:y,...u.length?{tags:u}:{},...f?{metadata:f}:{}}},{vaultId:t.id}):await S(n,{kind:"update-note",targetId:C,payload:{content:p,path:y,...u.length?{tags:{add:u}}:{},...f?{metadata:f}:{}}},{vaultId:t.id}),s==null||s.runOnce(),X(Date.now())}catch{I&&($.current=null)}},[n,t,c.kind,T,p,x,j,N,m.captureText,s]),he=i.useCallback(e=>{(e.metaKey||e.ctrlKey)&&e.key==="Enter"&&(e.preventDefault(),z())},[z]),ne=i.useRef({db:n,activeVaultId:(t==null?void 0:t.id)??null,content:p,tags:x,pathOverride:j,summary:N,roles:m});return ne.current={db:n,activeVaultId:(t==null?void 0:t.id)??null,content:p,tags:x,pathOverride:j,summary:N,roles:m},i.useEffect(()=>()=>{if(P.current)return;const{db:e,activeVaultId:o,content:u,tags:y,pathOverride:v,summary:f,roles:w}=ne.current;if(!u.trim()||!e||!o)return;const C=y.filter(K=>K.length>0),h=Z(u),g=Array.from(new Set([w.captureText,...C,...h].filter(K=>K.length>0))),O=v.trim()||D.current,M=f.trim(),R=$.current;(R!=null&&R.createCommitted?S(e,{kind:"update-note",targetId:R.localId,payload:{content:u,path:O,...g.length?{tags:{add:g}}:{},...M?{metadata:{summary:M}}:{}}},{vaultId:o}):S(e,{kind:"create-note",localId:(R==null?void 0:R.localId)??Y(),payload:{content:u,path:O,...g.length?{tags:g}:{},...M?{metadata:{summary:M}}:{}}},{vaultId:o})).catch(()=>{})},[]),i.useEffect(()=>{if(q===null)return;const e=setInterval(()=>{fe(o=>o+1)},15e3);return()=>clearInterval(e)},[q]),i.useEffect(()=>{if(c.kind==="recording"||c.kind==="requesting"||c.kind==="saving"||c.kind==="have-audio"||!T)return;const e=setTimeout(()=>{P.current||re()},5e3);return()=>clearTimeout(e)},[c.kind,T,p,x,j,N,re]),t?a.jsxs("div",{className:"mx-auto max-w-2xl px-4 py-5 md:px-6 md:py-8",children:[a.jsxs("header",{className:"mb-5",children:[a.jsx("h1",{className:"font-serif text-2xl text-fg md:text-3xl",children:"Capture"}),a.jsxs("p",{className:"mt-1 text-xs text-fg-dim",children:["Type a thought, hold the mic to record, or both."," ",a.jsx("kbd",{className:"rounded bg-bg/60 px-1",children:"⌘"}),a.jsx("kbd",{className:"rounded bg-bg/60 px-1",children:"↵"})," to send."]})]}),a.jsxs("section",{className:"flex flex-col gap-4 rounded-xl border border-border bg-card p-5 md:p-6",children:[a.jsx("textarea",{ref:W,value:p,onChange:e=>k(e.target.value),onKeyDown:he,placeholder:"What are you thinking?","aria-label":"Capture content",rows:8,disabled:c.kind==="saving",className:"min-h-[30vh] w-full resize-y rounded-md border border-border bg-bg px-3 py-2 text-sm text-fg placeholder:text-fg-dim focus:border-accent focus:outline-none disabled:opacity-60"}),q!==null?a.jsxs("p",{className:"-mt-2 text-right text-[11px] text-fg-dim","aria-live":"polite","data-indicator-tick":pe,children:["Draft saved · ",je(new Date(q).toISOString())]}):null,c.kind==="have-audio"?a.jsxs("div",{className:"flex flex-col gap-2 rounded-md border border-accent/30 bg-accent/5 p-3",children:[a.jsxs("div",{className:"flex items-center justify-between gap-3",children:[a.jsxs("span",{className:"text-sm text-fg-muted",children:["🎙 Recorded ",G(c.durationMs)]}),a.jsx("button",{type:"button",onClick:_,className:"text-xs text-fg-dim hover:text-red-400",children:"Discard"})]}),a.jsx("audio",{controls:!0,src:c.url,className:"w-full",children:a.jsx("track",{kind:"captions"})}),a.jsx("p",{className:"text-xs text-fg-dim",children:"Transcript will be appended once your vault processes it."})]}):null,c.kind==="denied"?a.jsx("p",{className:"rounded-md border border-red-500/30 bg-red-500/5 px-3 py-2 text-xs text-red-400",children:c.message}):null,a.jsx(Ne,{tags:x,input:ie,onInputChange:F,onAdd:e=>{const o=oe(e);!o||x.includes(o)||(L(u=>[...u,o]),F(""))},onRemove:e=>L(o=>o.filter(u=>u!==e))}),a.jsxs("details",{className:"group rounded-md border border-border bg-bg/50",open:ce,onToggle:e=>de(e.currentTarget.open),children:[a.jsx("summary",{className:"cursor-pointer select-none px-3 py-2 text-xs text-fg-muted hover:text-accent",children:"More fields"}),a.jsxs("div",{className:"space-y-3 px-3 pb-3 pt-1",children:[a.jsxs("label",{className:"flex flex-col gap-1 text-xs",children:[a.jsx("span",{className:"text-fg-dim",children:"Path"}),a.jsx("input",{type:"text",value:j,onChange:e=>le(e.target.value),placeholder:"(blank → uses generated path)","aria-label":"Path override",className:"rounded-md border border-border bg-card px-2.5 py-1.5 font-mono text-xs text-fg focus:border-accent focus:outline-none"})]}),a.jsxs("label",{className:"flex flex-col gap-1 text-xs",children:[a.jsx("span",{className:"text-fg-dim",children:"Summary"}),a.jsx("input",{type:"text",value:N,onChange:e=>ue(e.target.value),placeholder:"(optional one-line description)","aria-label":"Summary",className:"rounded-md border border-border bg-card px-2.5 py-1.5 text-xs text-fg focus:border-accent focus:outline-none"})]}),a.jsxs("p",{className:"text-xs text-fg-dim",children:["Need to attach a file?"," ",a.jsx(Ee,{to:"/new",className:"text-accent hover:underline",children:"Open the full editor"}),"."]})]})]}),a.jsxs("div",{className:"flex items-center justify-between gap-3 pt-2",children:[a.jsx(Ue,{phase:c,elapsedMs:me,onPointerDown:()=>void ge()}),a.jsxs("div",{className:"flex flex-col items-end gap-1",children:[a.jsx("button",{type:"button",onClick:()=>void z(),disabled:!H,className:"min-h-11 rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover disabled:opacity-40",children:c.kind==="saving"?"Saving…":"Capture"}),a.jsx("span",{className:"text-[11px] text-fg-dim",children:U&&T?"Will save as a note with audio attached.":U?"Will save as a voice memo.":T?"Will save as a text note.":"Type or record to capture."})]})]})]})]}):a.jsx(Se,{to:"/",replace:!0})}function Ue({phase:r,elapsedMs:t,onPointerDown:d}){const n=r.kind==="recording",l=r.kind==="requesting",s=n?`Recording — release to stop (${G(t)})`:l?"Requesting microphone…":"Hold to record";return a.jsxs("button",{type:"button",onPointerDown:m=>{m.preventDefault(),d()},"aria-label":s,"aria-pressed":n,disabled:r.kind==="saving",className:`flex min-h-11 items-center gap-2 rounded-full border px-4 py-2 text-sm font-medium transition select-none ${n?"border-red-500/40 bg-red-500/10 text-red-400":"border-accent/30 bg-accent/10 text-accent hover:bg-accent/15"} disabled:opacity-40`,children:[a.jsx("span",{"aria-hidden":"true",className:n?"animate-pulse":"",children:"🎙"}),a.jsx("span",{children:n?`Rec ${G(t)}`:l?"Requesting…":"Hold to record"})]})}export{Fe as Capture,Z as extractHashtags};
function u(t){return t<10?`0${t}`:String(t)}function s(t=new Date){return`${t.getFullYear()}-${u(t.getMonth()+1)}-${u(t.getDate())}`}function l(t){if(!t)return null;const e=new Date(t);return Number.isNaN(e.getTime())?null:s(e)}function c(t){if(!t||!/^\d{4}-\d{2}-\d{2}$/.test(t))return null;const[e,n,r]=t.split("-").map(Number),a=new Date(e,n-1,r);return Number.isNaN(a.getTime())?null:a}function f(t=new Date){return`${t.getFullYear()}-${u(t.getMonth()+1)}`}function d(t){if(!t||!/^\d{4}-\d{2}$/.test(t))return null;const[e,n]=t.split("-").map(Number);return n<1||n>12?null:{year:e,month:n}}function g(t,e,n){const r=t*12+(e-1)+n;return{year:Math.floor(r/12),month:r%12+1}}function m(t,e){const r=new Date(t,e-1,1).getDay(),a=new Date(t,e-1,1-r),i=[];for(let o=0;o<42;o++)i.push(new Date(a.getFullYear(),a.getMonth(),a.getDate()+o));return i}function D(t){const e=c(t);return e?e.toLocaleDateString(void 0,{weekday:"long",year:"numeric",month:"long",day:"numeric"}):t}function h(t,e){return new Date(t,e-1,1).toLocaleDateString(void 0,{year:"numeric",month:"long"})}export{l as a,u as b,f as c,c as d,D as e,h as f,m,d as p,g as s,s as t};
@import"https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;1,9..40,300;1,9..40,400&family=JetBrains+Mono:wght@400;500&display=swap";/*! tailwindcss v4.2.4 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial}}}@layer theme{:root,:host{--font-sans:"DM Sans", -apple-system, BlinkMacSystemFont, sans-serif;--font-serif:"Instrument Serif", Georgia, serif;--font-mono:"JetBrains Mono", "SF Mono", Monaco, monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-100:oklch(96.2% .059 95.617);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-700:oklch(55.5% .163 48.998);--color-emerald-300:oklch(84.5% .143 164.978);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-sky-300:oklch(82.8% .111 230.318);--color-sky-400:oklch(74.6% .16 232.661);--color-sky-500:oklch(68.5% .169 237.323);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--text-5xl:3rem;--text-5xl--line-height:1;--font-weight-medium:500;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-bg:#faf8f4;--color-bg-soft:#f3f0ea;--color-fg:#2c2a26;--color-fg-muted:#6b6860;--color-fg-dim:#9a9690;--color-accent:#4a7c59;--color-accent-hover:#3d6849;--color-accent-light:#6a9b77;--color-border:#e4e0d8;--color-card:#fff;--font-size-prose:18px;--font-size-editor:15px}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.inset-x-0{inset-inline:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.top-0{top:calc(var(--spacing) * 0)}.top-full{top:100%}.right-0{right:calc(var(--spacing) * 0)}.right-3{right:calc(var(--spacing) * 3)}.bottom-0{bottom:calc(var(--spacing) * 0)}.bottom-3{bottom:calc(var(--spacing) * 3)}.bottom-4{bottom:calc(var(--spacing) * 4)}.bottom-6{bottom:calc(var(--spacing) * 6)}.left-1\/2{left:50%}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.m-0{margin:calc(var(--spacing) * 0)}.m-auto{margin:auto}.mx-1{margin-inline:calc(var(--spacing) * 1)}.mx-auto{margin-inline:auto}.-mt-2{margin-top:calc(var(--spacing) * -2)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-10{margin-top:calc(var(--spacing) * 10)}.mr-1{margin-right:calc(var(--spacing) * 1)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.mb-10{margin-bottom:calc(var(--spacing) * 10)}.ml-0\.5{margin-left:calc(var(--spacing) * .5)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-auto{margin-left:auto}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1{height:calc(var(--spacing) * 1)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-14{height:calc(var(--spacing) * 14)}.h-16{height:calc(var(--spacing) * 16)}.h-24{height:calc(var(--spacing) * 24)}.h-28{height:calc(var(--spacing) * 28)}.h-32{height:calc(var(--spacing) * 32)}.h-\[24rem\]{height:24rem}.h-\[40rem\]{height:40rem}.h-\[calc\(100dvh-5rem\)\]{height:calc(100dvh - 5rem)}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-56{max-height:calc(var(--spacing) * 56)}.max-h-\[32rem\]{max-height:32rem}.max-h-\[50vh\]{max-height:50vh}.max-h-\[60vh\]{max-height:60vh}.max-h-full{max-height:100%}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-11{min-height:calc(var(--spacing) * 11)}.min-h-20{min-height:calc(var(--spacing) * 20)}.min-h-\[30vh\]{min-height:30vh}.min-h-\[60vh\]{min-height:60vh}.min-h-dvh{min-height:100dvh}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-1\/3{width:33.3333%}.w-2{width:calc(var(--spacing) * 2)}.w-2\/3{width:66.6667%}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-10{width:calc(var(--spacing) * 10)}.w-32{width:calc(var(--spacing) * 32)}.w-40{width:calc(var(--spacing) * 40)}.w-44{width:calc(var(--spacing) * 44)}.w-48{width:calc(var(--spacing) * 48)}.w-72{width:calc(var(--spacing) * 72)}.w-80{width:calc(var(--spacing) * 80)}.w-full{width:100%}.w-px{width:1px}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-\[12rem\]{max-width:12rem}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.max-w-xl{max-width:var(--container-xl)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-11{min-width:calc(var(--spacing) * 11)}.min-w-24{min-width:calc(var(--spacing) * 24)}.min-w-48{min-width:calc(var(--spacing) * 48)}.flex-1{flex:1}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.animate-pulse{animation:var(--animate-pulse)}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize-y{resize:vertical}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-around{justify-content:space-around}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-10{gap:calc(var(--spacing) * 10)}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * .5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 8) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 8) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}.gap-y-3{row-gap:calc(var(--spacing) * 3)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-border>:not(:last-child)){border-color:var(--color-border)}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t-md{border-top-left-radius:var(--radius-md);border-top-right-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-accent{border-color:var(--color-accent)}.border-accent\/30{border-color:#4a7c594d}@supports (color:color-mix(in lab,red,red)){.border-accent\/30{border-color:color-mix(in oklab,var(--color-accent) 30%,transparent)}}.border-accent\/40{border-color:#4a7c5966}@supports (color:color-mix(in lab,red,red)){.border-accent\/40{border-color:color-mix(in oklab,var(--color-accent) 40%,transparent)}}.border-accent\/60{border-color:#4a7c5999}@supports (color:color-mix(in lab,red,red)){.border-accent\/60{border-color:color-mix(in oklab,var(--color-accent) 60%,transparent)}}.border-amber-400\/40{border-color:#fcbb0066}@supports (color:color-mix(in lab,red,red)){.border-amber-400\/40{border-color:color-mix(in oklab,var(--color-amber-400) 40%,transparent)}}.border-amber-500\/30{border-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.border-amber-500\/30{border-color:color-mix(in oklab,var(--color-amber-500) 30%,transparent)}}.border-amber-500\/40{border-color:#f99c0066}@supports (color:color-mix(in lab,red,red)){.border-amber-500\/40{border-color:color-mix(in oklab,var(--color-amber-500) 40%,transparent)}}.border-border{border-color:var(--color-border)}.border-red-400\/30{border-color:#ff65684d}@supports (color:color-mix(in lab,red,red)){.border-red-400\/30{border-color:color-mix(in oklab,var(--color-red-400) 30%,transparent)}}.border-red-500\/30{border-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.border-red-500\/30{border-color:color-mix(in oklab,var(--color-red-500) 30%,transparent)}}.border-red-500\/40{border-color:#fb2c3666}@supports (color:color-mix(in lab,red,red)){.border-red-500\/40{border-color:color-mix(in oklab,var(--color-red-500) 40%,transparent)}}.border-sky-500\/30{border-color:#00a5ef4d}@supports (color:color-mix(in lab,red,red)){.border-sky-500\/30{border-color:color-mix(in oklab,var(--color-sky-500) 30%,transparent)}}.border-transparent{border-color:#0000}.bg-accent{background-color:var(--color-accent)}.bg-accent\/5{background-color:#4a7c590d}@supports (color:color-mix(in lab,red,red)){.bg-accent\/5{background-color:color-mix(in oklab,var(--color-accent) 5%,transparent)}}.bg-accent\/10{background-color:#4a7c591a}@supports (color:color-mix(in lab,red,red)){.bg-accent\/10{background-color:color-mix(in oklab,var(--color-accent) 10%,transparent)}}.bg-accent\/15{background-color:#4a7c5926}@supports (color:color-mix(in lab,red,red)){.bg-accent\/15{background-color:color-mix(in oklab,var(--color-accent) 15%,transparent)}}.bg-accent\/20{background-color:#4a7c5933}@supports (color:color-mix(in lab,red,red)){.bg-accent\/20{background-color:color-mix(in oklab,var(--color-accent) 20%,transparent)}}.bg-amber-400{background-color:var(--color-amber-400)}.bg-amber-400\/10{background-color:#fcbb001a}@supports (color:color-mix(in lab,red,red)){.bg-amber-400\/10{background-color:color-mix(in oklab,var(--color-amber-400) 10%,transparent)}}.bg-amber-500\/5{background-color:#f99c000d}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/5{background-color:color-mix(in oklab,var(--color-amber-500) 5%,transparent)}}.bg-amber-500\/10{background-color:#f99c001a}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/10{background-color:color-mix(in oklab,var(--color-amber-500) 10%,transparent)}}.bg-amber-500\/20{background-color:#f99c0033}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/20{background-color:color-mix(in oklab,var(--color-amber-500) 20%,transparent)}}.bg-amber-500\/30{background-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/30{background-color:color-mix(in oklab,var(--color-amber-500) 30%,transparent)}}.bg-bg{background-color:var(--color-bg)}.bg-bg\/40{background-color:#faf8f466}@supports (color:color-mix(in lab,red,red)){.bg-bg\/40{background-color:color-mix(in oklab,var(--color-bg) 40%,transparent)}}.bg-bg\/50{background-color:#faf8f480}@supports (color:color-mix(in lab,red,red)){.bg-bg\/50{background-color:color-mix(in oklab,var(--color-bg) 50%,transparent)}}.bg-bg\/60{background-color:#faf8f499}@supports (color:color-mix(in lab,red,red)){.bg-bg\/60{background-color:color-mix(in oklab,var(--color-bg) 60%,transparent)}}.bg-bg\/80{background-color:#faf8f4cc}@supports (color:color-mix(in lab,red,red)){.bg-bg\/80{background-color:color-mix(in oklab,var(--color-bg) 80%,transparent)}}.bg-bg\/90{background-color:#faf8f4e6}@supports (color:color-mix(in lab,red,red)){.bg-bg\/90{background-color:color-mix(in oklab,var(--color-bg) 90%,transparent)}}.bg-bg\/95{background-color:#faf8f4f2}@supports (color:color-mix(in lab,red,red)){.bg-bg\/95{background-color:color-mix(in oklab,var(--color-bg) 95%,transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab,red,red)){.bg-black\/60{background-color:color-mix(in oklab,var(--color-black) 60%,transparent)}}.bg-border{background-color:var(--color-border)}.bg-border\/30{background-color:#e4e0d84d}@supports (color:color-mix(in lab,red,red)){.bg-border\/30{background-color:color-mix(in oklab,var(--color-border) 30%,transparent)}}.bg-border\/40{background-color:#e4e0d866}@supports (color:color-mix(in lab,red,red)){.bg-border\/40{background-color:color-mix(in oklab,var(--color-border) 40%,transparent)}}.bg-border\/60{background-color:#e4e0d899}@supports (color:color-mix(in lab,red,red)){.bg-border\/60{background-color:color-mix(in oklab,var(--color-border) 60%,transparent)}}.bg-card{background-color:var(--color-card)}.bg-card\/30{background-color:#ffffff4d}@supports (color:color-mix(in lab,red,red)){.bg-card\/30{background-color:color-mix(in oklab,var(--color-card) 30%,transparent)}}.bg-card\/40{background-color:#fff6}@supports (color:color-mix(in lab,red,red)){.bg-card\/40{background-color:color-mix(in oklab,var(--color-card) 40%,transparent)}}.bg-card\/50{background-color:#ffffff80}@supports (color:color-mix(in lab,red,red)){.bg-card\/50{background-color:color-mix(in oklab,var(--color-card) 50%,transparent)}}.bg-card\/60{background-color:#fff9}@supports (color:color-mix(in lab,red,red)){.bg-card\/60{background-color:color-mix(in oklab,var(--color-card) 60%,transparent)}}.bg-card\/90{background-color:#ffffffe6}@supports (color:color-mix(in lab,red,red)){.bg-card\/90{background-color:color-mix(in oklab,var(--color-card) 90%,transparent)}}.bg-emerald-400{background-color:var(--color-emerald-400)}.bg-emerald-500\/20{background-color:#00bb7f33}@supports (color:color-mix(in lab,red,red)){.bg-emerald-500\/20{background-color:color-mix(in oklab,var(--color-emerald-500) 20%,transparent)}}.bg-red-400{background-color:var(--color-red-400)}.bg-red-400\/5{background-color:#ff65680d}@supports (color:color-mix(in lab,red,red)){.bg-red-400\/5{background-color:color-mix(in oklab,var(--color-red-400) 5%,transparent)}}.bg-red-500{background-color:var(--color-red-500)}.bg-red-500\/5{background-color:#fb2c360d}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/5{background-color:color-mix(in oklab,var(--color-red-500) 5%,transparent)}}.bg-red-500\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/10{background-color:color-mix(in oklab,var(--color-red-500) 10%,transparent)}}.bg-red-500\/20{background-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/20{background-color:color-mix(in oklab,var(--color-red-500) 20%,transparent)}}.bg-red-500\/30{background-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/30{background-color:color-mix(in oklab,var(--color-red-500) 30%,transparent)}}.bg-sky-400{background-color:var(--color-sky-400)}.bg-sky-500\/5{background-color:#00a5ef0d}@supports (color:color-mix(in lab,red,red)){.bg-sky-500\/5{background-color:color-mix(in oklab,var(--color-sky-500) 5%,transparent)}}.bg-transparent{background-color:#0000}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.p-10{padding:calc(var(--spacing) * 10)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-7{padding-block:calc(var(--spacing) * 7)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-16{padding-block:calc(var(--spacing) * 16)}.py-20{padding-block:calc(var(--spacing) * 20)}.py-24{padding-block:calc(var(--spacing) * 24)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pt-\[10vh\]{padding-top:10vh}.pr-1{padding-right:calc(var(--spacing) * 1)}.pb-1\.5{padding-bottom:calc(var(--spacing) * 1.5)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pb-16{padding-bottom:calc(var(--spacing) * 16)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-5{padding-left:calc(var(--spacing) * 5)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.font-serif{font-family:var(--font-serif)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-none{--tw-leading:1;line-height:1}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.text-accent{color:var(--color-accent)}.text-accent\/70{color:#4a7c59b3}@supports (color:color-mix(in lab,red,red)){.text-accent\/70{color:color-mix(in oklab,var(--color-accent) 70%,transparent)}}.text-amber-50{color:var(--color-amber-50)}.text-amber-100{color:var(--color-amber-100)}.text-amber-100\/70{color:#fef3c6b3}@supports (color:color-mix(in lab,red,red)){.text-amber-100\/70{color:color-mix(in oklab,var(--color-amber-100) 70%,transparent)}}.text-amber-100\/90{color:#fef3c6e6}@supports (color:color-mix(in lab,red,red)){.text-amber-100\/90{color:color-mix(in oklab,var(--color-amber-100) 90%,transparent)}}.text-amber-200{color:var(--color-amber-200)}.text-amber-200\/80{color:#fee685cc}@supports (color:color-mix(in lab,red,red)){.text-amber-200\/80{color:color-mix(in oklab,var(--color-amber-200) 80%,transparent)}}.text-amber-300{color:var(--color-amber-300)}.text-amber-500{color:var(--color-amber-500)}.text-amber-700{color:var(--color-amber-700)}.text-emerald-300{color:var(--color-emerald-300)}.text-fg{color:var(--color-fg)}.text-fg-dim{color:var(--color-fg-dim)}.text-fg-muted{color:var(--color-fg-muted)}.text-red-50{color:var(--color-red-50)}.text-red-100{color:var(--color-red-100)}.text-red-200{color:var(--color-red-200)}.text-red-200\/80{color:#ffcacacc}@supports (color:color-mix(in lab,red,red)){.text-red-200\/80{color:color-mix(in oklab,var(--color-red-200) 80%,transparent)}}.text-red-300{color:var(--color-red-300)}.text-red-400{color:var(--color-red-400)}.text-sky-300{color:var(--color-sky-300)}.text-white{color:var(--color-white)}.text-white\/80{color:#fffc}@supports (color:color-mix(in lab,red,red)){.text-white\/80{color:color-mix(in oklab,var(--color-white) 80%,transparent)}}.capitalize{text-transform:capitalize}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.decoration-dashed{text-decoration-style:dashed}.underline-offset-4{text-underline-offset:4px}.accent-accent{accent-color:var(--color-accent)}.opacity-40{opacity:.4}.opacity-60{opacity:.6}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.select-none{-webkit-user-select:none;user-select:none}.group-open\:rotate-90:is(:where(.group):is([open],:popover-open,:open) *){rotate:90deg}.placeholder\:text-fg-dim::placeholder{color:var(--color-fg-dim)}.backdrop\:bg-black\/40::backdrop{background-color:#0006}@supports (color:color-mix(in lab,red,red)){.backdrop\:bg-black\/40::backdrop{background-color:color-mix(in oklab,var(--color-black) 40%,transparent)}}@media(hover:hover){.hover\:border-accent:hover{border-color:var(--color-accent)}.hover\:border-accent\/50:hover{border-color:#4a7c5980}@supports (color:color-mix(in lab,red,red)){.hover\:border-accent\/50:hover{border-color:color-mix(in oklab,var(--color-accent) 50%,transparent)}}.hover\:border-border:hover{border-color:var(--color-border)}.hover\:border-red-500\/40:hover{border-color:#fb2c3666}@supports (color:color-mix(in lab,red,red)){.hover\:border-red-500\/40:hover{border-color:color-mix(in oklab,var(--color-red-500) 40%,transparent)}}.hover\:bg-accent-hover:hover{background-color:var(--color-accent-hover)}.hover\:bg-accent\/5:hover{background-color:#4a7c590d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-accent\/5:hover{background-color:color-mix(in oklab,var(--color-accent) 5%,transparent)}}.hover\:bg-accent\/10:hover{background-color:#4a7c591a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-accent\/10:hover{background-color:color-mix(in oklab,var(--color-accent) 10%,transparent)}}.hover\:bg-accent\/15:hover{background-color:#4a7c5926}@supports (color:color-mix(in lab,red,red)){.hover\:bg-accent\/15:hover{background-color:color-mix(in oklab,var(--color-accent) 15%,transparent)}}.hover\:bg-accent\/20:hover{background-color:#4a7c5933}@supports (color:color-mix(in lab,red,red)){.hover\:bg-accent\/20:hover{background-color:color-mix(in oklab,var(--color-accent) 20%,transparent)}}.hover\:bg-amber-500\/20:hover{background-color:#f99c0033}@supports (color:color-mix(in lab,red,red)){.hover\:bg-amber-500\/20:hover{background-color:color-mix(in oklab,var(--color-amber-500) 20%,transparent)}}.hover\:bg-amber-500\/50:hover{background-color:#f99c0080}@supports (color:color-mix(in lab,red,red)){.hover\:bg-amber-500\/50:hover{background-color:color-mix(in oklab,var(--color-amber-500) 50%,transparent)}}.hover\:bg-bg:hover{background-color:var(--color-bg)}.hover\:bg-bg\/50:hover{background-color:#faf8f480}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bg\/50:hover{background-color:color-mix(in oklab,var(--color-bg) 50%,transparent)}}.hover\:bg-bg\/60:hover{background-color:#faf8f499}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bg\/60:hover{background-color:color-mix(in oklab,var(--color-bg) 60%,transparent)}}.hover\:bg-card:hover{background-color:var(--color-card)}.hover\:bg-red-500\/10:hover{background-color:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/10:hover{background-color:color-mix(in oklab,var(--color-red-500) 10%,transparent)}}.hover\:bg-red-500\/40:hover{background-color:#fb2c3666}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/40:hover{background-color:color-mix(in oklab,var(--color-red-500) 40%,transparent)}}.hover\:bg-red-500\/50:hover{background-color:#fb2c3680}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/50:hover{background-color:color-mix(in oklab,var(--color-red-500) 50%,transparent)}}.hover\:bg-red-600:hover{background-color:var(--color-red-600)}.hover\:text-accent:hover{color:var(--color-accent)}.hover\:text-accent-hover:hover{color:var(--color-accent-hover)}.hover\:text-amber-100:hover{color:var(--color-amber-100)}.hover\:text-fg:hover{color:var(--color-fg)}.hover\:text-red-100:hover{color:var(--color-red-100)}.hover\:text-red-300:hover{color:var(--color-red-300)}.hover\:text-red-400:hover{color:var(--color-red-400)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:border-accent:focus{border-color:var(--color-accent)}.focus\:border-border:focus{border-color:var(--color-border)}.focus\:border-red-400:focus{border-color:var(--color-red-400)}.focus\:bg-bg\/60:focus{background-color:#faf8f499}@supports (color:color-mix(in lab,red,red)){.focus\:bg-bg\/60:focus{background-color:color-mix(in oklab,var(--color-bg) 60%,transparent)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:outline-accent:focus-visible{outline-color:var(--color-accent)}@media(hover:hover){.enabled\:hover\:text-accent:enabled:hover{color:var(--color-accent)}}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}@media(min-width:40rem){.sm\:inline{display:inline}}@media(min-width:48rem){.md\:sticky{position:sticky}.md\:top-6{top:calc(var(--spacing) * 6)}.md\:mb-6{margin-bottom:calc(var(--spacing) * 6)}.md\:block{display:block}.md\:flex{display:flex}.md\:hidden{display:none}.md\:min-h-0{min-height:calc(var(--spacing) * 0)}.md\:grid-cols-\[14rem_1fr\]{grid-template-columns:14rem 1fr}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:justify-between{justify-content:space-between}:where(.md\:space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.md\:self-auto{align-self:auto}.md\:self-start{align-self:flex-start}.md\:p-6{padding:calc(var(--spacing) * 6)}.md\:px-4{padding-inline:calc(var(--spacing) * 4)}.md\:px-6{padding-inline:calc(var(--spacing) * 6)}.md\:py-3{padding-block:calc(var(--spacing) * 3)}.md\:py-8{padding-block:calc(var(--spacing) * 8)}.md\:py-10{padding-block:calc(var(--spacing) * 10)}.md\:py-12{padding-block:calc(var(--spacing) * 12)}.md\:pb-0{padding-bottom:calc(var(--spacing) * 0)}.md\:text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}}@media(min-width:64rem){.lg\:sticky{position:sticky}.lg\:top-24{top:calc(var(--spacing) * 24)}.lg\:block{display:block}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-\[minmax\(0\,1fr\)_18rem\]{grid-template-columns:minmax(0,1fr) 18rem}.lg\:self-start{align-self:flex-start}.lg\:px-6{padding-inline:calc(var(--spacing) * 6)}.lg\:py-5{padding-block:calc(var(--spacing) * 5)}.lg\:text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}}@media(prefers-color-scheme:dark){.dark\:text-amber-300{color:var(--color-amber-300)}}}pre code.hljs{padding:1em;display:block;overflow-x:auto}code.hljs{padding:3px 5px}.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:#005cc5}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-comment,.hljs-code,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}:root[data-text-size=larger]{--font-size-prose:22px;--font-size-editor:18px;font-size:18px}:root[data-text-size=largest]{--font-size-prose:26px;--font-size-editor:22px;font-size:22px}@media(prefers-color-scheme:dark){:root:not([data-theme=light]){--color-bg:#1a1917;--color-bg-soft:#23221f;--color-fg:#e8e5de;--color-fg-muted:#a8a49b;--color-fg-dim:#706c64;--color-accent:#7ab087;--color-accent-hover:#8bc098;--color-accent-light:#5b8c6a;--color-sky:#7fb3cc;--color-border:#33312d;--color-border-light:#2a2926;--color-card:#23221f;--color-card-hover:#2a2926}}:root[data-theme=dark]{--color-bg:#1a1917;--color-bg-soft:#23221f;--color-fg:#e8e5de;--color-fg-muted:#a8a49b;--color-fg-dim:#706c64;--color-accent:#7ab087;--color-accent-hover:#8bc098;--color-accent-light:#5b8c6a;--color-sky:#7fb3cc;--color-border:#33312d;--color-border-light:#2a2926;--color-card:#23221f;--color-card-hover:#2a2926}html,body{font-family:var(--font-sans);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;line-height:1.65}body{padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right);padding-bottom:env(safe-area-inset-bottom)}.prose-note{color:var(--color-fg);font-size:var(--font-size-prose);line-height:1.7}.prose-note h1,.prose-note h2,.prose-note h3,.prose-note h4{font-family:var(--font-serif);color:var(--color-fg);letter-spacing:-.015em;margin-top:1.75em;margin-bottom:.5em;line-height:1.25}.prose-note h1{font-size:1.875rem}.prose-note h2{font-size:1.5rem}.prose-note h3{font-size:1.25rem}.prose-note h4{font-size:1.1rem}.prose-note p{margin:.75em 0}.prose-note ul,.prose-note ol{margin:.75em 0;padding-left:1.5rem}.prose-note ul{list-style:outside}.prose-note ol{list-style:decimal}.prose-note li,.prose-note li>p{margin:.25em 0}.prose-note blockquote{border-left:3px solid var(--color-border);color:var(--color-fg-muted);margin:1em 0;padding-left:1rem;font-style:italic}.prose-note code{font-family:var(--font-mono);background:var(--color-bg-soft);border-radius:3px;padding:.1em .35em;font-size:.875em}.prose-note pre{background:var(--color-bg-soft);border:1px solid var(--color-border);border-radius:6px;margin:1em 0;padding:.9rem 1rem;font-size:.875em;line-height:1.5;overflow-x:auto}.prose-note pre code{font-size:inherit;background:0 0;border-radius:0;padding:0}.prose-note table{border-collapse:collapse;width:100%;margin:1em 0;font-size:.9em}.prose-note th,.prose-note td{border:1px solid var(--color-border);text-align:left;padding:.5rem .75rem}.prose-note th{background:var(--color-bg-soft);font-weight:500}.prose-note hr{border:0;border-top:1px solid var(--color-border);margin:1.5em 0}.prose-note img{border-radius:6px;max-width:100%;height:auto}.prose-note input[type=checkbox]{margin-right:.4em}@media(prefers-color-scheme:dark){:root:not([data-theme=light]) .prose-note code,:root:not([data-theme=light]) .prose-note pre{border-color:var(--color-border);background:#1f1e1b}:root:not([data-theme=light]) .prose-note .hljs{color:var(--color-fg);background:#1f1e1b!important}}:root[data-theme=dark] .prose-note code,:root[data-theme=dark] .prose-note pre{border-color:var(--color-border);background:#1f1e1b}:root[data-theme=dark] .prose-note .hljs{color:var(--color-fg);background:#1f1e1b!important}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}

Sorry, the diff of this file is too big to display

import{r as d,j as e,g as T,t as V,V as C,v as _,w as z,u as O,x as K,N as W,L as R,y as Y,z as q,A as H,b as D,T as Z,s as G}from"./index-DKKYWfqC.js";import{u as J,A as Q,C as X,a as ee,b as te}from"./useAttachmentUploader-vNDFzDKT.js";import{P as se,D as ne}from"./PinArchiveButtons-CCZolBUN.js";import{b as re,N as ae}from"./NoteRenderer-BuDmZBkP.js";const oe=250;function de({noteId:t,attachment:n}){const[l,a]=d.useState(!1),o=ce(n);return e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",onClick:()=>a(!0),"aria-label":`Remove attachment ${o}`,className:"shrink-0 rounded border border-transparent px-1.5 py-0.5 text-fg-dim hover:border-red-500/40 hover:text-red-400",children:"✕"}),l?e.jsx(ie,{noteId:t,attachment:n,label:o,onClose:()=>a(!1)}):null]})}function ie({noteId:t,attachment:n,label:l,onClose:a}){const o=T(i=>i.push),m=V(),[s,h]=d.useState(!1),[w,p]=d.useState(null),N=d.useRef(null);d.useEffect(()=>{const i=setTimeout(()=>h(!0),oe);return()=>clearTimeout(i)},[]),d.useEffect(()=>{var i;(i=N.current)==null||i.focus()},[]),d.useEffect(()=>{const i=g=>{g.key==="Escape"&&a()};return window.addEventListener("keydown",i),()=>window.removeEventListener("keydown",i)},[a]);const b=d.useCallback(()=>{!s||m.isPending||(p(null),m.mutate({noteId:t,attachmentId:n.id},{onSuccess:()=>{o(`Removed ${l}`,"success"),a()},onError:i=>{if(i instanceof C){p("Session expired. Reconnect to remove attachments.");return}if(i instanceof _){o(`Already removed ${l}`,"info"),a();return}p(i instanceof Error?i.message:"Remove failed")}}))},[s,n.id,l,m,t,a,o]);return e.jsx("dialog",{open:!0,"aria-labelledby":"confirm-remove-attachment-title",className:"fixed inset-0 z-40 m-0 flex h-full max-h-full w-full max-w-full items-center justify-center bg-black/60 p-4",onMouseDown:i=>{i.target===i.currentTarget&&a()},children:e.jsxs("div",{className:"w-full max-w-md rounded-md border border-border bg-card p-6 shadow-xl",children:[e.jsx("h2",{id:"confirm-remove-attachment-title",className:"mb-2 font-serif text-lg text-red-400",children:"Remove attachment?"}),e.jsxs("p",{className:"mb-3 text-sm text-fg-muted",children:[e.jsx("span",{className:"rounded bg-bg/60 px-1 py-0.5 font-mono text-xs text-fg",children:l})," ","will be detached from this note. If no other note references the file, it will also be deleted from storage. Markdown referencing it will show a broken link until you update it."]}),w?e.jsx("p",{role:"alert",className:"mb-3 text-sm text-red-400",children:w}):null,e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{ref:N,type:"button",onClick:a,className:"min-h-11 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg-muted hover:text-fg",children:"Cancel"}),e.jsx("button",{type:"button",onClick:b,disabled:!s||m.isPending,className:"min-h-11 rounded-md bg-red-500 px-4 py-1.5 text-sm font-medium text-white hover:bg-red-600 disabled:opacity-40",children:m.isPending?"Removing…":"Remove"})]})]})})}function ce(t){if(t.filename)return t.filename;if(t.path){const n=t.path.split("/").pop();return n||t.path}return t.id}function we(){const{id:t}=z(),n=t?decodeURIComponent(t):void 0,l=O(o=>o.getActiveVault()),a=K(n);return l?e.jsxs("div",{className:"mx-auto max-w-6xl px-4 py-5 md:px-6 md:py-8",children:[e.jsx("nav",{className:"mb-4 text-sm text-fg-dim",children:e.jsx(R,{to:n?`/n/${encodeURIComponent(n)}`:"/",className:"hover:text-accent",children:"← Back to note"})}),a.isPending?e.jsx(xe,{}):a.isError?e.jsx(fe,{error:a.error}):a.data?e.jsx(le,{note:a.data}):e.jsx(he,{id:n??""})]}):e.jsx(W,{to:"/",replace:!0})}function S(t){return{content:t.content??"",path:t.path??"",tags:[...t.tags??[]]}}function le({note:t}){const n=Y(),l=T(r=>r.push),a=d.useMemo(()=>re(t),[t]),[o,m]=d.useState(()=>S(t)),[s,h]=d.useState(()=>S(t)),[w,p]=d.useState(""),[N,b]=d.useState(null),[i,g]=d.useState(null),[y,L]=d.useState("edit"),v=q(t.id),k=d.useRef(t),E=d.useRef(null),j=J({noteId:t.id,onInsert:r=>{E.current?E.current.insertAtCursor(r):h(c=>({...c,content:`${c.content}${r}`}))},onLinked:()=>{l("Attachment added","success")},onError:r=>l(r,"error")});d.useEffect(()=>{k.current=t},[t]);const u=s.content!==o.content||s.path!==o.path||!pe(s.tags,o.tags),A=d.useCallback(()=>{if(!u||v.isPending)return;const r={};s.content!==o.content&&(r.content=s.content),s.path!==o.path&&(r.path=s.path);const c=be(o.tags,s.tags);(c.add.length||c.remove.length)&&(r.tags=c);const f=k.current.updatedAt??k.current.createdAt;f&&(r.if_updated_at=f),g(null),b(null),v.mutate(r,{onSuccess:x=>{m(S(x)),h(S(x)),k.current=x,x.id!==t.id&&n(`/n/${encodeURIComponent(x.id)}/edit`,{replace:!0})},onError:x=>{x instanceof H?b(x):x instanceof C?g("Session expired. Reconnect to save."):g(x instanceof Error?x.message:"Save failed")}})},[o,s,u,v,n,t.id]),$=d.useCallback(()=>{u&&confirm("Discard all edits and revert to last saved version?")&&(h(o),b(null),g(null))},[o,u]),P=d.useCallback(()=>{u&&!confirm("Discard unsaved changes?")||n(`/n/${encodeURIComponent(t.id)}`)},[u,n,t.id]);d.useEffect(()=>{if(!u)return;const r=c=>{c.preventDefault(),c.returnValue=""};return window.addEventListener("beforeunload",r),()=>window.removeEventListener("beforeunload",r)},[u]);const B=s.path!==o.path,U=r=>{const c=G(r);c&&(s.tags.includes(c)||(h(f=>({...f,tags:[...f.tags,c]})),p("")))},F=r=>{h(c=>({...c,tags:c.tags.filter(f=>f!==r)}))},M=s.content;return e.jsxs("article",{children:[e.jsxs("header",{className:"mb-4 border-b border-border pb-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx("span",{className:"text-xs uppercase tracking-wider text-fg-dim",children:"Editing"}),u?e.jsxs("span",{className:"inline-flex items-center gap-1 text-xs text-accent","aria-label":"unsaved changes",children:[e.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-accent"}),"unsaved"]}):e.jsxs("span",{className:"text-xs text-fg-dim",children:["saved ",D(t.updatedAt)]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(se,{note:t}),e.jsx(ne,{note:t}),e.jsx("span",{className:"mx-1 h-5 w-px bg-border","aria-hidden":"true"}),e.jsx("button",{type:"button",onClick:$,disabled:!u||v.isPending,className:"min-h-11 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg-muted hover:text-accent disabled:opacity-40",children:"Revert"}),e.jsx("button",{type:"button",onClick:P,className:"min-h-11 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg-muted hover:text-accent",children:"Cancel"}),e.jsx("button",{type:"button",onClick:A,disabled:!u||v.isPending,className:"min-h-11 rounded-md bg-accent px-4 py-1.5 text-sm font-medium text-white hover:bg-accent-hover disabled:opacity-40",title:"Save (⌘S)",children:v.isPending?"Saving…":"Save"})]})]}),e.jsxs("div",{className:"mt-3 flex flex-col gap-2",children:[e.jsx(Z,{tags:s.tags,input:w,onInputChange:p,onAdd:U,onRemove:F}),e.jsxs("label",{className:"flex items-baseline gap-3 text-sm",children:[e.jsx("span",{className:"shrink-0 text-xs uppercase tracking-wider text-fg-dim",children:"Path"}),e.jsx("input",{type:"text",value:s.path,onChange:r=>h(c=>({...c,path:r.target.value})),className:"flex-1 rounded-md border border-border bg-card px-2.5 py-1 font-mono text-sm text-fg focus:border-accent focus:outline-none","aria-label":"Note path",placeholder:"(no path)"})]}),B?e.jsx("p",{className:"text-xs text-accent",children:"Renaming moves the note — its id may change."}):null]})]}),N?e.jsx(ue,{conflict:N,onReload:()=>{window.location.reload()},onDismiss:()=>b(null)}):null,i?e.jsx("div",{className:"mb-4 rounded-md border border-red-500/30 bg-red-500/5 p-3 text-sm text-red-400",children:i}):null,e.jsx("div",{role:"tablist","aria-label":"Editor view",className:"mb-3 inline-flex rounded-md border border-border bg-card p-0.5 text-sm lg:hidden",children:["edit","preview"].map(r=>e.jsx("button",{type:"button",role:"tab","aria-selected":y===r,onClick:()=>L(r),className:`rounded px-3 py-1.5 capitalize ${y===r?"bg-accent text-white":"text-fg-muted hover:text-accent"}`,children:r},r))}),e.jsxs("div",{className:"grid min-h-[60vh] gap-4 lg:grid-cols-2",children:[e.jsx(Q,{onDropFiles:j.start,className:`min-w-0 rounded-md border border-border bg-card ${y==="edit"?"":"hidden lg:block"}`,hint:I,children:e.jsx(X,{ref:E,value:s.content,onChange:r=>h(c=>({...c,content:r})),onSave:A,onCancel:P,onPasteFile:r=>(j.start(r),!0)})}),e.jsx("div",{className:`min-w-0 overflow-auto rounded-md border border-border bg-card p-4 ${y==="preview"?"":"hidden lg:block"}`,children:e.jsx(ae,{note:{path:s.path,content:M},resolve:a})})]}),e.jsx(me,{noteId:t.id,attachments:t.attachments??[],uploads:j.uploads,onPickFiles:j.start,onCancel:j.cancel,onDismiss:j.dismiss})]})}const I=e.jsxs(e.Fragment,{children:["Images, audio, webm video."," ",e.jsx("a",{href:"https://github.com/ParachuteComputer/parachute-vault/issues/127",target:"_blank",rel:"noreferrer",className:"underline",children:"PDF + mp4 coming"})]});function me({noteId:t,attachments:n,uploads:l,onPickFiles:a,onCancel:o,onDismiss:m}){return e.jsxs("section",{className:"mt-6 border-t border-border pt-4",children:[e.jsxs("div",{className:"mb-3 flex items-center justify-between",children:[e.jsx("h2",{className:"font-serif text-lg",children:"Attachments"}),e.jsx(ee,{onPickFiles:a})]}),e.jsxs("p",{className:"mb-3 text-xs text-fg-dim",children:["Drop or paste files into the editor. Max 100 MB each. ",I,"."]}),e.jsx(te,{uploads:l,onCancel:o,onDismiss:m}),n.length>0?e.jsx("ul",{className:"mt-3 space-y-1 text-sm",children:n.map(s=>e.jsxs("li",{className:"flex items-center justify-between gap-2 rounded border border-border bg-card/50 px-3 py-1.5 font-mono text-xs",children:[e.jsx("span",{className:"truncate",title:s.path??s.id,children:s.filename??s.path??s.id}),e.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[s.mimeType?e.jsx("span",{className:"text-fg-dim",children:s.mimeType}):null,e.jsx(de,{noteId:t,attachment:s})]})]},s.id))}):null]})}function ue({conflict:t,onReload:n,onDismiss:l}){return e.jsxs("div",{className:"mb-4 rounded-md border border-amber-500/40 bg-amber-500/10 p-4",children:[e.jsx("p",{className:"mb-1 font-medium text-amber-500",children:"This note was edited elsewhere."}),e.jsxs("p",{className:"mb-3 text-sm text-fg-muted",children:["Your save was rejected to avoid overwriting the other edit.",t.currentUpdatedAt?` Latest update ${D(t.currentUpdatedAt)}.`:""]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx("button",{type:"button",onClick:n,className:"rounded-md bg-accent px-3 py-1.5 text-sm font-medium text-white hover:bg-accent-hover",children:"Reload latest (discard my edits)"}),e.jsx("button",{type:"button",onClick:l,className:"rounded-md border border-border px-3 py-1.5 text-sm text-fg-muted hover:text-fg",children:"Keep editing"})]})]})}function xe(){return e.jsxs("div",{className:"grid min-h-[60vh] gap-4 lg:grid-cols-2","aria-busy":"true",children:[e.jsx("div",{className:"animate-pulse rounded-md border border-border bg-card"}),e.jsx("div",{className:"animate-pulse rounded-md border border-border bg-card"})]})}function he({id:t}){return e.jsxs("div",{className:"rounded-md border border-border bg-card p-10 text-center",children:[e.jsx("p",{className:"mb-2 font-serif text-xl",children:"Note not found"}),e.jsxs("p",{className:"mb-4 text-sm text-fg-muted",children:["No note with id ",e.jsx("span",{className:"font-mono",children:t})," in this vault."]}),e.jsx(R,{to:"/",className:"text-sm text-accent hover:underline",children:"Back to all notes"})]})}function fe({error:t}){const n=t instanceof C;return e.jsxs("div",{className:"rounded-md border border-red-500/30 bg-red-500/5 p-6",children:[e.jsx("p",{className:"mb-2 font-medium text-red-400",children:n?"Session expired":"Could not load note"}),e.jsx("p",{className:"mb-4 text-sm text-fg-muted",children:t.message}),n?e.jsx(R,{to:"/add",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Reconnect vault"}):null]})}function pe(t,n){if(t.length!==n.length)return!1;const l=new Set(t);for(const a of n)if(!l.has(a))return!1;return!0}function be(t,n){const l=new Set(t),a=new Set(n),o=n.filter(s=>!l.has(s)),m=t.filter(s=>!a.has(s));return{add:o,remove:m}}export{we as NoteEditor};
import{u as P,y as T,g as I,B as R,C as L,r as n,j as e,N as V,V as $,L as F,T as _,s as M}from"./index-DKKYWfqC.js";import{u as U,A as B,C as z,a as O,b as W}from"./useAttachmentUploader-vNDFzDKT.js";import{b as Y,N as Z}from"./NoteRenderer-BuDmZBkP.js";const q={content:"",path:"",tags:[],summary:""};function K(){const w=P(t=>t.getActiveVault()),l=T(),d=I(t=>t.push),c=R(),f=L(),[a,o]=n.useState(q),[C,b]=n.useState(""),[j,x]=n.useState(null),[m,k]=n.useState([]),p=n.useRef(null),i=U({noteId:null,onInsert:t=>{p.current?p.current.insertAtCursor(t):o(s=>({...s,content:`${s.content}${t}`}))},onStaged:t=>k(s=>[...s,t]),onError:t=>d(t,"error")});if(!w)return e.jsx(V,{to:"/",replace:!0});const u=a.content.length>0||a.path.length>0||a.tags.length>0||a.summary.length>0,h=a.content.trim().length>0&&a.path.trim().length>0,v=n.useCallback(()=>{if(!h||c.isPending)return;const t={content:a.content,path:a.path.trim()};a.tags.length&&(t.tags=a.tags);const s=a.summary.trim();s&&(t.metadata={summary:s}),x(null),c.mutate(t,{onSuccess:async r=>{for(const g of m)try{await f.mutateAsync({noteId:r.id,path:g.path,mimeType:g.mimeType})}catch(y){const D=y instanceof Error?y.message:"Link failed";d(`Failed to attach ${g.filename}: ${D}`,"error")}d(`Created ${r.path??r.id}`,"success"),l(`/n/${encodeURIComponent(r.id)}`)},onError:r=>{r instanceof $?x("Session expired. Reconnect to save."):x(r instanceof Error?`${r.message} — if the path is taken, try a different one.`:"Create failed")}})},[a,h,f,c,l,d,m]),N=n.useCallback(()=>{u&&!confirm("Discard this draft?")||l("/")},[u,l]);n.useEffect(()=>{if(!u)return;const t=s=>{s.preventDefault(),s.returnValue=""};return window.addEventListener("beforeunload",t),()=>window.removeEventListener("beforeunload",t)},[u]);const A=t=>{const s=M(t);!s||a.tags.includes(s)||(o(r=>({...r,tags:[...r.tags,s]})),b(""))},E=t=>{o(s=>({...s,tags:s.tags.filter(r=>r!==t)}))},S=Y({id:"__new__",createdAt:new Date().toISOString()});return e.jsxs("div",{className:"mx-auto max-w-6xl px-4 py-5 md:px-6 md:py-8",children:[e.jsx("nav",{className:"mb-4 text-sm text-fg-dim",children:e.jsx(F,{to:"/",className:"hover:text-accent",children:"← All notes"})}),e.jsxs("article",{children:[e.jsxs("header",{className:"mb-4 border-b border-border pb-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsx("div",{className:"flex items-center gap-2 text-sm",children:e.jsx("span",{className:"text-xs uppercase tracking-wider text-fg-dim",children:"New note"})}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{type:"button",onClick:N,className:"min-h-11 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg-muted hover:text-accent",children:"Cancel"}),e.jsx("button",{type:"button",onClick:v,disabled:!h||c.isPending,className:"min-h-11 rounded-md bg-accent px-4 py-1.5 text-sm font-medium text-white hover:bg-accent-hover disabled:opacity-40",title:"Create (⌘S)",children:c.isPending?"Creating…":"Create"})]})]}),e.jsxs("div",{className:"mt-3 flex flex-col gap-2",children:[e.jsxs("label",{className:"flex items-baseline gap-3 text-sm",children:[e.jsx("span",{className:"shrink-0 text-xs uppercase tracking-wider text-fg-dim",children:"Path"}),e.jsx("input",{type:"text",value:a.path,onChange:t=>o(s=>({...s,path:t.target.value})),className:"flex-1 rounded-md border border-border bg-card px-2.5 py-1 font-mono text-sm text-fg focus:border-accent focus:outline-none","aria-label":"Note path",placeholder:"e.g. Projects/README"})]}),e.jsxs("label",{className:"flex items-baseline gap-3 text-sm",children:[e.jsx("span",{className:"shrink-0 text-xs uppercase tracking-wider text-fg-dim",children:"Summary"}),e.jsx("input",{type:"text",value:a.summary,onChange:t=>o(s=>({...s,summary:t.target.value})),className:"flex-1 rounded-md border border-border bg-card px-2.5 py-1 text-sm text-fg focus:border-accent focus:outline-none","aria-label":"Note summary",placeholder:"(optional one-line description)"})]}),e.jsx(_,{tags:a.tags,input:C,onInputChange:b,onAdd:A,onRemove:E})]})]}),j?e.jsx("div",{role:"alert",className:"mb-4 rounded-md border border-red-500/30 bg-red-500/5 p-3 text-sm text-red-400",children:j}):null,e.jsxs("div",{className:"grid min-h-[60vh] gap-4 lg:grid-cols-2",children:[e.jsx(B,{onDropFiles:i.start,className:"min-w-0 rounded-md border border-border bg-card",hint:"Images, audio, webm video",children:e.jsx(z,{ref:p,value:a.content,onChange:t=>o(s=>({...s,content:t})),onSave:v,onCancel:N,onPasteFile:t=>(i.start(t),!0)})}),e.jsx("div",{className:"min-w-0 overflow-auto rounded-md border border-border bg-card p-4",children:a.content.trim()?e.jsx(Z,{note:{path:a.path,content:a.content},resolve:S}):e.jsx("p",{className:"text-sm text-fg-dim",children:"Preview appears here as you type."})})]}),e.jsxs("section",{className:"mt-6 border-t border-border pt-4",children:[e.jsxs("div",{className:"mb-3 flex items-center justify-between",children:[e.jsx("h2",{className:"font-serif text-lg",children:"Attachments"}),e.jsx(O,{onPickFiles:i.start})]}),e.jsxs("p",{className:"mb-3 text-xs text-fg-dim",children:["Drop or paste files into the editor. Attachments link to the note when you save. Max 100 MB each. Images, audio, webm video."," ",e.jsx("a",{href:"https://github.com/ParachuteComputer/parachute-vault/issues/127",target:"_blank",rel:"noreferrer",className:"underline",children:"PDF + mp4 coming"}),"."]}),e.jsx(W,{uploads:i.uploads,onCancel:i.cancel,onDismiss:i.dismiss}),m.length>0?e.jsx("ul",{className:"mt-3 space-y-1 text-sm",children:m.map(t=>e.jsxs("li",{className:"flex items-center justify-between gap-2 rounded border border-border bg-card/50 px-3 py-1.5 font-mono text-xs text-fg-muted",children:[e.jsx("span",{className:"truncate",children:t.filename}),e.jsx("span",{className:"shrink-0 text-fg-dim",children:"staged"})]},t.path))}):null]})]})]})}export{K as NoteNew};

Sorry, the diff of this file is too big to display

const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/react-force-graph-2d-YVoN3oXw.js","assets/index-DKKYWfqC.js","assets/index-BU6cVU21.css"])))=>i.map(i=>d[i]);
import{r as c,k as v,j as t,y as k,_ as y,w as I,u as R,x as A,F as E,N as C,L as p,V as L,b as j}from"./index-DKKYWfqC.js";import{P as _,D}from"./PinArchiveButtons-CCZolBUN.js";import{b as T,N as M}from"./NoteRenderer-BuDmZBkP.js";const S=1,U=3,$=1;function B(e,s){const a=new Map,n=new Map;for(const d of s.values())for(const r of d.links??[]){if(r.sourceId===r.targetId||!s.has(r.sourceId)||!s.has(r.targetId))continue;const o=`${r.sourceId}|${r.targetId}|${r.relationship}`;a.has(o)||(a.set(o,{source:r.sourceId,target:r.targetId,relationship:r.relationship}),n.set(r.sourceId,(n.get(r.sourceId)??0)+1),n.set(r.targetId,(n.get(r.targetId)??0)+1))}return{nodes:[...s.values()].map(d=>{var r;return{id:d.id,path:d.path,tags:d.tags,summary:typeof((r=d.metadata)==null?void 0:r.summary)=="string"?d.metadata.summary:void 0,isAnchor:d.id===e,linkCount:n.get(d.id)??0}}),edges:[...a.values()]}}async function P(e,s,a,n){const i=new Map;i.set(e.id,e);let d=[e];for(let r=1;r<=s;r++){const o=new Set;for(const u of d)for(const x of u.links??[]){const h=x.sourceId===u.id?x.targetId:x.sourceId;h!==u.id&&(i.has(h)||o.add(h))}if(o.size===0)break;const l=await Promise.all([...o].map(u=>a(u).catch(()=>null)));if(n!=null&&n.cancelled)return i;const m=[];for(const u of l)u&&!i.has(u.id)&&(i.set(u.id,u),m.push(u));d=m}return i}function V(e,s,a){const[n,i]=c.useState(null),[d,r]=c.useState(!1);return c.useEffect(()=>{if(!e||!s){i(null),r(!1);return}const o={cancelled:!1};return r(!0),P(s,a,l=>e.getNote(l,{includeLinks:!0}),o).then(l=>{o.cancelled||(i(B(s.id,l)),r(!1))}).catch(()=>{o.cancelled||r(!1)}),()=>{o.cancelled=!0}},[e,s,a]),{data:n,isLoading:d}}const F=c.lazy(()=>y(()=>import("./react-force-graph-2d-YVoN3oXw.js"),__vite__mapDeps([0,1,2])));function z({anchor:e}){const[s,a]=c.useState(!0),[n,i]=c.useState($),d=v(),{data:r,isLoading:o}=V(d,s?e:void 0,n);return t.jsxs("section",{className:"mt-10 border-t border-border pt-6",children:[t.jsxs("header",{className:"mb-4 flex flex-wrap items-center justify-between gap-3",children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsxs("button",{type:"button",onClick:()=>a(l=>!l),"aria-expanded":s,className:"font-serif text-xl text-fg hover:text-accent",children:[s?"▾":"▸"," Neighborhood"]}),s&&r?t.jsxs("span",{className:"text-xs text-fg-dim",children:[r.nodes.length," ",r.nodes.length===1?"note":"notes"]}):null]}),s?t.jsx(G,{depth:n,onChange:i}):null]}),s?t.jsx(O,{data:r,isLoading:o}):null]})}function G({depth:e,onChange:s}){const a=[];for(let n=S;n<=U;n++)a.push(n);return t.jsxs("fieldset",{className:"flex items-center gap-1 text-xs text-fg-dim",children:[t.jsx("legend",{className:"mr-1 inline-block",children:"Hops"}),a.map(n=>t.jsx("button",{type:"button","aria-pressed":n===e,onClick:()=>s(n),className:n===e?"rounded border border-accent bg-accent/10 px-2 py-0.5 text-accent":"rounded border border-border bg-card px-2 py-0.5 hover:text-accent",children:n},n))]})}function O({data:e,isLoading:s}){return!e&&s?t.jsx(w,{}):e?e.nodes.length<=1?t.jsx("div",{className:"rounded-md border border-border bg-card p-6 text-center text-sm text-fg-dim",children:"This note has no neighbors yet."}):t.jsx(H,{data:e}):null}function w(){return t.jsx("div",{"aria-busy":"true",className:"h-[24rem] w-full animate-pulse rounded-md border border-border bg-card"})}function H({data:e}){const s=k(),a=c.useRef(null),[n,i]=c.useState({w:600,h:384});c.useEffect(()=>{const r=a.current;if(!r)return;const o=()=>{const m=r.getBoundingClientRect();i({w:Math.max(320,Math.floor(m.width)),h:384})};o();const l=new ResizeObserver(o);return l.observe(r),()=>l.disconnect()},[]);const d=c.useMemo(()=>({nodes:e.nodes.map(r=>({...r})),links:e.edges.map(r=>({source:r.source,target:r.target,rel:r.relationship}))}),[e]);return t.jsx("div",{ref:a,"data-testid":"neighborhood-graph-canvas",className:"overflow-hidden rounded-md border border-border bg-card",children:t.jsx(c.Suspense,{fallback:t.jsx(w,{}),children:t.jsx(F,{graphData:d,width:n.w,height:n.h,nodeLabel:r=>K(r),nodeVal:r=>{const o=r;return o.isAnchor?8:3+Math.min(o.linkCount,8)},nodeColor:r=>r.isAnchor?"#c9b170":"#8a9a7a",linkColor:()=>"rgba(160, 160, 160, 0.4)",linkDirectionalArrowLength:3,linkDirectionalArrowRelPos:1,cooldownTicks:80,onNodeClick:r=>{s(`/n/${encodeURIComponent(r.id)}`)}})})})}function K(e){const s=[e.path??e.id];return e.tags&&e.tags.length>0&&s.push(`tags: ${e.tags.join(", ")}`),e.summary&&s.push(e.summary),s.join(`
`)}const W="_Transcript pending._",X="_Transcription unavailable._";function q({content:e}){const s=e.includes(W),a=!s&&e.includes(X);return s?t.jsxs("output",{"aria-live":"polite",className:"mb-4 inline-flex items-center gap-2 rounded-md border border-sky-500/30 bg-sky-500/5 px-3 py-1.5 text-xs text-sky-300",children:[t.jsx("span",{"aria-hidden":!0,className:"inline-block h-2 w-2 animate-pulse rounded-full bg-sky-400"}),"Transcribing…"]}):a?t.jsx("output",{className:"mb-4 inline-flex items-center gap-2 rounded-md border border-amber-500/30 bg-amber-500/5 px-3 py-1.5 text-xs text-amber-200",children:"Transcription unavailable — open the audio below and add a note by hand."}):null}function ce(){const{id:e}=I(),s=e?decodeURIComponent(e):void 0,a=R(i=>i.getActiveVault()),n=A(s);return c.useEffect(()=>{a&&s&&E(a.id,s)},[a,s]),a?t.jsxs("div",{className:"mx-auto max-w-6xl px-4 py-6 md:px-6 md:py-10",children:[t.jsx("nav",{className:"mb-6 text-sm text-fg-dim",children:t.jsx(p,{to:"/",className:"hover:text-accent",children:"← All notes"})}),n.isPending?t.jsx(ne,{}):n.isError?t.jsx(oe,{error:n.error}):n.data?t.jsx(J,{note:n.data}):t.jsx(ae,{id:s??""})]}):t.jsx(C,{to:"/",replace:!0})}function J({note:e}){var r;const s=c.useMemo(()=>T(e),[e]),a=e.path??e.id,n=typeof((r=e.metadata)==null?void 0:r.summary)=="string"?e.metadata.summary:null,i=c.useMemo(()=>(e.links??[]).filter(o=>o.targetId===e.id&&o.sourceId!==e.id&&o.sourceNote),[e]),d=c.useMemo(()=>{const o=new Set,l=[];for(const m of e.links??[])m.sourceId!==e.id||m.targetId===e.id||m.targetNote&&(o.has(m.targetId)||(o.add(m.targetId),l.push(m)));return l},[e]);return t.jsxs("article",{className:"grid gap-10 lg:grid-cols-[minmax(0,1fr)_18rem]",children:[t.jsxs("div",{className:"min-w-0",children:[t.jsxs("header",{className:"mb-6 border-b border-border pb-4",children:[t.jsx("h1",{className:"font-serif text-3xl tracking-tight",children:e.path?Q(e.path):e.id}),e.tags&&e.tags.length>0?t.jsx(Z,{tags:e.tags}):null,t.jsx("p",{className:"mt-2 font-mono text-xs text-fg-dim break-all",children:a}),n?t.jsx("p",{className:"mt-3 text-fg-muted",children:n}):null,t.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-2",children:[t.jsx(p,{to:`/n/${encodeURIComponent(e.id)}/edit`,className:"min-h-11 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg-muted hover:text-accent",children:"Edit"}),t.jsx(_,{note:e,keyboard:!0}),t.jsx(D,{note:e})]})]}),t.jsx(q,{content:e.content??""}),t.jsx(M,{note:e,resolve:s}),e.attachments&&e.attachments.length>0?t.jsxs("section",{className:"mt-10 border-t border-border pt-6",children:[t.jsx("h2",{className:"mb-3 font-serif text-xl",children:"Attachments"}),t.jsx("div",{className:"space-y-6",children:e.attachments.map(o=>t.jsx(ee,{attachment:o},o.id))})]}):null,t.jsx(z,{anchor:e})]}),t.jsxs("aside",{className:"space-y-6 text-sm lg:sticky lg:top-24 lg:self-start",children:[t.jsx(Y,{note:e}),d.length>0?t.jsx(N,{title:"Outbound",links:d,peer:"target"}):null,i.length>0?t.jsx(N,{title:"Inbound",links:i,peer:"source"}):null]})]})}function Q(e){return(e.split("/").pop()??e).replace(/\.md$/i,"")}function Y({note:e}){const s=e.createdAt,a=e.updatedAt,n=Object.entries(e.metadata??{}).filter(([i])=>i!=="summary");return t.jsxs("section",{className:"rounded-md border border-border bg-card p-4",children:[t.jsx("h2",{className:"mb-2 text-xs uppercase tracking-wider text-fg-dim",children:"Metadata"}),t.jsxs("dl",{className:"space-y-1.5 text-sm",children:[e.path?t.jsx(f,{label:"Path",value:t.jsx("span",{className:"font-mono text-xs break-all",children:e.path})}):null,t.jsx(f,{label:"ID",value:t.jsx("span",{className:"font-mono text-xs break-all",children:e.id})}),t.jsx(f,{label:"Created",value:t.jsx("time",{title:s,children:j(s)})}),a?t.jsx(f,{label:"Updated",value:t.jsx("time",{title:a,children:j(a)})}):null,n.map(([i,d])=>t.jsx(f,{label:i,value:t.jsx("span",{className:"break-all text-fg-muted",children:String(d)})},i))]})]})}function f({label:e,value:s}){return t.jsxs("div",{className:"flex flex-col gap-0.5",children:[t.jsx("dt",{className:"text-xs uppercase tracking-wider text-fg-dim",children:e}),t.jsx("dd",{children:s})]})}function Z({tags:e}){return t.jsx("div",{className:"mt-3 flex flex-wrap gap-1.5","aria-label":"Tags",children:e.map(s=>t.jsxs(p,{to:`/?tag=${encodeURIComponent(s)}`,className:"max-w-full break-all rounded-full border border-accent/40 bg-accent/10 px-2.5 py-0.5 text-xs font-medium text-accent hover:border-accent hover:bg-accent/20",children:["#",s]},s))})}function N({title:e,links:s,peer:a}){return t.jsxs("section",{className:"rounded-md border border-border bg-card p-4",children:[t.jsxs("h2",{className:"mb-2 text-xs uppercase tracking-wider text-fg-dim",children:[e," (",s.length,")"]}),t.jsx("ul",{className:"space-y-1.5",children:s.map(n=>{var o;const i=a==="source"?n.sourceNote:n.targetNote;if(!i)return null;const d=i.path??i.id,r=typeof((o=i.metadata)==null?void 0:o.summary)=="string"?i.metadata.summary:null;return t.jsx("li",{children:t.jsxs(p,{to:`/n/${encodeURIComponent(i.id)}`,className:"block rounded px-1 py-0.5 hover:bg-bg/50",children:[t.jsx("div",{className:"truncate font-mono text-xs text-fg-muted hover:text-accent",children:d}),r?t.jsx("div",{className:"mt-0.5 line-clamp-2 text-xs text-fg-dim",children:r}):null]})},`${n.sourceId}->${n.targetId}:${n.relationship}`)})})]})}function ee({attachment:e}){const s=(e.mimeType??"").toLowerCase(),a=e.filename??e.id;return t.jsxs("figure",{className:"rounded-md border border-border bg-card p-3",children:[t.jsxs("figcaption",{className:"mb-2 flex items-baseline justify-between gap-3",children:[t.jsx("span",{className:"truncate font-mono text-xs text-fg-muted",children:a}),typeof e.size=="number"?t.jsx("span",{className:"shrink-0 text-xs text-fg-dim",children:re(e.size)}):null]}),t.jsx(te,{attachment:e,mime:s,filename:a})]})}function te({attachment:e,mime:s,filename:a}){const n=v(),[i,d]=c.useState(null),[r,o]=c.useState(null),l=se(s,a),m=l!=="other",u=e.url;if(c.useEffect(()=>{if(!m||!u||!n)return;let h=!1,b=null;return o(null),n.fetchAttachmentBlob(u).then(g=>{h||(b=URL.createObjectURL(g),d(b))}).catch(g=>{h||o(g instanceof Error?g.message:"Failed to load attachment")}),()=>{h=!0,b&&URL.revokeObjectURL(b)}},[m,u,n]),!u)return t.jsx("p",{className:"text-sm text-fg-dim",children:"(no URL)"});if(r)return t.jsx("p",{className:"text-sm text-red-400",children:r});if(m&&!i)return t.jsx("div",{className:"h-32 animate-pulse rounded bg-border/40","aria-busy":"true"});const x=i??u;return l==="image"?t.jsx("img",{src:x,alt:a,className:"max-h-[32rem] rounded"}):l==="audio"?t.jsx("audio",{controls:!0,src:x,className:"w-full"}):l==="video"?t.jsx("video",{controls:!0,src:x,className:"w-full rounded"}):l==="pdf"?t.jsxs(t.Fragment,{children:[t.jsx("iframe",{src:x,title:a,className:"h-[40rem] w-full rounded border border-border"}),t.jsxs("a",{href:x,download:a,className:"mt-2 inline-block text-sm text-accent hover:underline",children:["Download ",a]})]}):t.jsxs("a",{href:x,download:a,className:"text-sm text-accent hover:underline",children:["Download ",a]})}function se(e,s){if(e.startsWith("image/"))return"image";if(e.startsWith("audio/"))return"audio";if(e.startsWith("video/"))return"video";if(e==="application/pdf")return"pdf";const a=s.toLowerCase().split(".").pop()??"";return["png","jpg","jpeg","gif","webp","svg"].includes(a)?"image":["mp3","wav","ogg","m4a","flac"].includes(a)?"audio":["mp4","webm","mov"].includes(a)?"video":a==="pdf"?"pdf":"other"}function re(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:e<1024*1024*1024?`${(e/(1024*1024)).toFixed(1)} MB`:`${(e/(1024*1024*1024)).toFixed(2)} GB`}function ne(){return t.jsxs("div",{className:"grid gap-10 lg:grid-cols-[minmax(0,1fr)_18rem]","aria-busy":"true",children:[t.jsxs("div",{className:"min-w-0 space-y-3",children:[t.jsx("div",{className:"h-3 w-32 animate-pulse rounded bg-border/40"}),t.jsx("div",{className:"h-8 w-2/3 animate-pulse rounded bg-border/60"}),t.jsx("div",{className:"h-4 w-full animate-pulse rounded bg-border/30"}),t.jsx("div",{className:"mt-6 space-y-2",children:[0,1,2,3,4,5].map(e=>t.jsx("div",{className:"h-3 animate-pulse rounded bg-border/30",style:{width:`${70+e*13%25}%`}},e))})]}),t.jsxs("div",{className:"space-y-4",children:[t.jsx("div",{className:"h-32 animate-pulse rounded bg-border/30"}),t.jsx("div",{className:"h-24 animate-pulse rounded bg-border/30"})]})]})}function ae({id:e}){return t.jsxs("div",{className:"rounded-md border border-border bg-card p-10 text-center",children:[t.jsx("p",{className:"mb-2 font-serif text-xl",children:"Note not found"}),t.jsxs("p",{className:"mb-4 text-sm text-fg-muted",children:["No note with id ",t.jsx("span",{className:"font-mono",children:e})," in this vault."]}),t.jsx(p,{to:"/",className:"text-sm text-accent hover:underline",children:"Back to all notes"})]})}function oe({error:e}){const s=e instanceof L;return t.jsxs("div",{className:"rounded-md border border-red-500/30 bg-red-500/5 p-6",children:[t.jsx("p",{className:"mb-2 font-medium text-red-400",children:s?"Session expired":"Could not load note"}),t.jsx("p",{className:"mb-4 text-sm text-fg-muted",children:e.message}),s?t.jsx(p,{to:"/add",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Reconnect vault"}):null]})}export{ce as NoteView};
import{c as y,y as j,u as N,r as l,J as w,K as E,M as V,O as S,P as C,j as e}from"./index-DKKYWfqC.js";function R(){const[a]=y(),s=j(),d=N(c=>c.addVault),[n,o]=l.useState({kind:"working"}),u=l.useRef(!1);return l.useEffect(()=>{if(u.current)return;u.current=!0;const c=a.get("code"),p=a.get("state"),x=a.get("error");if(x){o({kind:"error",message:`Vault returned: ${x}`});return}if(!c||!p){o({kind:"error",message:"Missing code or state in callback URL."});return}(async()=>{var m,h,g,v;try{const{pending:t,token:r}=await w(c,p),f=r.vault?`vault:${r.vault}`:void 0,k=(f?(h=(m=r.services)==null?void 0:m[f])==null?void 0:h.url:void 0)??((v=(g=r.services)==null?void 0:g.vault)==null?void 0:v.url)??t.issuerUrl,i=d({url:k,name:r.vault,issuer:t.issuer,tokenEndpoint:t.tokenEndpoint,clientId:t.clientId,scope:r.scope},E(r));r.services&&V(i,r.services);const b=S.getState();b.clearHalt(i),t.priorHaltedVaultId&&t.priorHaltedVaultId!==i&&b.clearHalt(t.priorHaltedVaultId),s("/",{replace:!0})}catch(t){if(t instanceof C){o({kind:"pending-approval",approveUrl:t.approveUrl});return}o({kind:"error",message:t.message})}})()},[a,s,d]),n.kind==="working"?e.jsxs("div",{className:"mx-auto max-w-xl px-6 py-24 text-center",children:[e.jsx("h1",{className:"mb-3 font-serif text-3xl",children:"Connecting…"}),e.jsx("p",{className:"text-fg-muted",children:"Exchanging the authorization code with your vault."})]}):n.kind==="pending-approval"?e.jsxs("div",{className:"mx-auto max-w-xl px-6 py-24 text-center",children:[e.jsx("h1",{className:"mb-3 font-serif text-3xl",children:"Waiting for hub approval"}),e.jsx("p",{className:"mb-8 text-fg-muted",children:"Your hub admin needs to approve this app before sign-in can complete. Open the approval page in your hub, approve, then try again."}),e.jsxs("div",{className:"flex flex-wrap items-center justify-center gap-3",children:[e.jsx("a",{href:n.approveUrl,target:"_blank",rel:"noopener noreferrer",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm text-white hover:bg-accent-hover",children:"Open approval page"}),e.jsx("button",{type:"button",onClick:()=>s("/add",{replace:!0}),className:"inline-block rounded-md border border-border bg-card px-4 py-2 text-sm text-fg-muted hover:text-accent",children:"Retry now"})]})]}):e.jsxs("div",{className:"mx-auto max-w-xl px-6 py-24 text-center",children:[e.jsx("h1",{className:"mb-3 font-serif text-3xl text-red-400",children:"Connection failed"}),e.jsx("p",{className:"mb-8 text-fg-muted",children:n.message}),e.jsx("button",{type:"button",onClick:()=>s("/add",{replace:!0}),className:"rounded-md bg-accent px-4 py-2 text-sm text-white hover:bg-accent-hover",children:"Try again"})]})}export{R as OAuthCallback};
import{r as c,j as t,y as v,g,G as j,V as y,u as w,i as E,z as N}from"./index-DKKYWfqC.js";function P({note:a,className:o,label:l="Delete"}){const[r,d]=c.useState(!1);return t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",onClick:()=>d(!0),className:o??"min-h-11 rounded-md border border-red-500/40 bg-transparent px-3 py-1.5 text-sm text-red-400 hover:bg-red-500/10",title:"Delete this note",children:l}),r?t.jsx(k,{note:a,onClose:()=>d(!1)}):null]})}function k({note:a,onClose:o}){const l=v(),r=g(e=>e.push),d=j(),i=a.path??a.id,[m,p]=c.useState(""),[u,b]=c.useState(null),x=c.useRef(null),s=m===i&&!d.isPending;c.useEffect(()=>{var e;(e=x.current)==null||e.focus()},[]),c.useEffect(()=>{const e=f=>{f.key==="Escape"&&o()};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[o]);const n=c.useCallback(()=>{s&&(b(null),d.mutate(a.id,{onSuccess:()=>{r(`Deleted ${i}`,"success"),l("/")},onError:e=>{e instanceof y?b("Session expired. Reconnect to delete."):b(e instanceof Error?e.message:"Delete failed")}}))},[s,i,d,l,a.id,r]);return t.jsx("dialog",{open:!0,"aria-labelledby":"confirm-delete-title",className:"fixed inset-0 z-40 m-0 flex h-full max-h-full w-full max-w-full items-center justify-center bg-black/60 p-4",onMouseDown:e=>{e.target===e.currentTarget&&o()},children:t.jsxs("div",{className:"w-full max-w-md rounded-md border border-border bg-card p-6 shadow-xl",children:[t.jsx("h2",{id:"confirm-delete-title",className:"mb-2 font-serif text-xl text-red-400",children:"Delete this note?"}),t.jsx("p",{className:"mb-3 text-sm text-fg-muted",children:"This permanently removes the note, its tags, and its links. This cannot be undone."}),t.jsxs("p",{className:"mb-3 text-sm text-fg-muted",children:["Type"," ",t.jsx("span",{className:"rounded bg-bg/60 px-1 py-0.5 font-mono text-xs text-fg",children:i})," ","to confirm:"]}),t.jsx("input",{ref:x,type:"text",value:m,onChange:e=>p(e.target.value),onKeyDown:e=>{e.key==="Enter"&&s&&n()},"aria-label":"Type note path to confirm",className:"mb-3 w-full rounded-md border border-border bg-bg/40 px-2.5 py-1.5 font-mono text-sm text-fg focus:border-red-400 focus:outline-none",placeholder:i,autoComplete:"off",spellCheck:!1}),u?t.jsx("p",{role:"alert",className:"mb-3 text-sm text-red-400",children:u}):null,t.jsxs("div",{className:"flex justify-end gap-2",children:[t.jsx("button",{type:"button",onClick:o,className:"min-h-11 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg-muted hover:text-fg",children:"Cancel"}),t.jsx("button",{type:"button",onClick:n,disabled:!s,className:"min-h-11 rounded-md bg-red-500 px-4 py-1.5 text-sm font-medium text-white hover:bg-red-600 disabled:opacity-40",children:d.isPending?"Deleting…":"Delete permanently"})]})]})})}function C({note:a,keyboard:o=!1}){var b,x;const l=w(s=>s.getActiveVault()),{roles:r}=E((l==null?void 0:l.id)??null),d=g(s=>s.push),i=N(a.id),m=((b=a.tags)==null?void 0:b.includes(r.pinned))??!1,p=((x=a.tags)==null?void 0:x.includes(r.archived))??!1,u=c.useCallback(s=>{var f;if(i.isPending)return;const n=r[s],e=((f=a.tags)==null?void 0:f.includes(n))??!1;i.mutate({tags:e?{remove:[n]}:{add:[n]}},{onSuccess:()=>{d(s==="pinned"?e?"Unpinned":"Pinned":e?"Unarchived":"Archived","success")},onError:h=>{h instanceof y?d("Session expired. Reconnect.","error"):d(h instanceof Error?h.message:"Update failed","error")}})},[i,a.tags,d,r]);return c.useEffect(()=>{if(!o)return;const s=n=>{if(n.defaultPrevented)return;const e=n.target;if(e){const f=e.tagName;if(f==="INPUT"||f==="TEXTAREA"||e.isContentEditable)return}n.metaKey||n.ctrlKey||n.altKey||(n.key==="p"||n.key==="P"?(n.preventDefault(),u("pinned")):(n.key==="a"||n.key==="A")&&(n.preventDefault(),u("archived")))};return window.addEventListener("keydown",s),()=>window.removeEventListener("keydown",s)},[o,u]),t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",onClick:()=>u("pinned"),disabled:i.isPending,"aria-pressed":m,title:m?`Unpin (${r.pinned})`:`Pin as #${r.pinned} (P)`,className:m?"min-h-11 rounded-md border border-accent/60 bg-accent/10 px-3 py-1.5 text-sm text-accent hover:bg-accent/20 disabled:opacity-40":"min-h-11 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg-muted hover:text-accent disabled:opacity-40",children:m?"★ Pinned":"☆ Pin"}),t.jsx("button",{type:"button",onClick:()=>u("archived"),disabled:i.isPending,"aria-pressed":p,title:p?`Unarchive (${r.archived})`:`Archive as #${r.archived} (A)`,className:p?"min-h-11 rounded-md border border-amber-500/40 bg-amber-500/10 px-3 py-1.5 text-sm text-amber-500 hover:bg-amber-500/20 disabled:opacity-40":"min-h-11 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg-muted hover:text-accent disabled:opacity-40",children:p?"Archived":"Archive"})]})}export{P as D,C as P};

Sorry, the diff of this file is too big to display

import{u as T,j as e,N as k,L as E,Q as b,R as A,k as C,g as S,r as o,U as R,W as L,X as _,Y as D,Z as z,i as P,$ as V,a0 as v,a1 as j,a2 as M,a3 as O,a4 as $,a5 as F}from"./index-DKKYWfqC.js";function Z(){const t=T(s=>s.getActiveVault());return t?e.jsxs("div",{className:"mx-auto max-w-2xl px-4 py-7 md:px-6 md:py-12",children:[e.jsxs("header",{className:"mb-8",children:[e.jsx("nav",{className:"mb-3 text-sm text-fg-dim",children:e.jsx(E,{to:"/",className:"hover:text-accent",children:"← Home"})}),e.jsx("h1",{className:"font-serif text-2xl tracking-tight md:text-3xl",children:"Settings"}),e.jsxs("p",{className:"mt-1 text-sm text-fg-muted",children:["Configuring ",e.jsx("span",{className:"text-fg",children:t.name}),"."]})]}),e.jsx(I,{vaultId:t.id}),e.jsx(U,{}),e.jsx(G,{vaultId:t.id}),e.jsx(Q,{vaultId:t.id}),e.jsx(Y,{})]}):e.jsx(k,{to:"/",replace:!0})}function I({vaultId:t}){const s=b(l=>l.byVault[t]??null),r=b(l=>l.refresh),n=b(l=>l.set),h=A(l=>l.clearDismissed),i=C(),d=S(l=>l.push),[x,u]=o.useState(!1),f=async()=>{i&&await r(t,i)},g=async()=>{var l;if(i){u(!0);try{await O(t,i);const m=(l=s==null?void 0:s.result)==null?void 0:l.rows.map(w=>({...w,status:"ok",differences:[]}));m&&n(t,{ok:!0,missing:[],misaligned:[],rows:m}),h(t),d("Schema updated.","success")}catch(m){d(m instanceof Error?`Schema fix failed: ${m.message}`:"Schema fix failed.","error")}finally{u(!1)}}},p=(s==null?void 0:s.loading)??!s,a=(s==null?void 0:s.result)??null,c=(s==null?void 0:s.error)??null;return e.jsxs("section",{className:"mt-6 space-y-4 rounded-xl border border-border bg-card p-6",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"font-serif text-xl text-fg",children:"Vault schema"}),e.jsxs("p",{className:"mt-1 text-xs text-fg-dim",children:["Notes declares three tags it uses to classify captures: ",e.jsx("code",{children:"capture"}),","," ",e.jsx("code",{children:"capture/text"}),", ",e.jsx("code",{children:"capture/voice"}),". This panel confirms the active vault has them set up; one click writes any missing or misaligned rows. Doesn't touch your Tag Role choices below."]})]}),e.jsx("button",{type:"button",onClick:()=>void f(),disabled:p||!i,className:"shrink-0 text-xs text-fg-dim hover:text-accent disabled:cursor-not-allowed disabled:opacity-60",children:p?"Checking…":"Refresh"})]}),c?e.jsxs("p",{className:"rounded-md border border-red-500/30 bg-red-500/5 px-3 py-2 text-xs text-red-300",children:["Audit failed: ",c]}):null,!a&&!c?e.jsx("p",{className:"text-xs text-fg-dim",children:"Loading audit…"}):null,a?e.jsxs(e.Fragment,{children:[e.jsx(H,{ok:a.ok}),e.jsx("ul",{className:"space-y-2",children:a.rows.map(l=>e.jsx(B,{row:l},l.name))}),a.ok?null:e.jsx("button",{type:"button",onClick:()=>void g(),disabled:x||!i,className:"min-h-11 rounded-md bg-accent px-3 py-1.5 text-xs font-medium text-white hover:bg-accent-hover disabled:cursor-not-allowed disabled:opacity-60",children:x?"Setting up…":"Set up missing tags"})]}):null]})}function H({ok:t}){return e.jsxs("p",{className:`inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs ${t?"bg-emerald-500/20 text-emerald-300":"bg-amber-500/20 text-amber-300"}`,children:[e.jsx("span",{"aria-hidden":!0,className:`h-1.5 w-1.5 rounded-full ${t?"bg-emerald-400":"bg-amber-400"}`}),t?"Matches Notes' schema":"Needs setup"]})}function B({row:t}){const s=t.status==="ok"?"ok":t.status==="missing"?"missing":"misaligned",r=t.status==="ok"?"text-emerald-300":"text-amber-300";return e.jsxs("li",{className:"rounded-md border border-border bg-bg/40 px-3 py-2 text-xs",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("code",{className:"font-mono text-sm text-fg",children:t.name}),e.jsx("span",{className:`text-xs ${r}`,children:s})]}),t.status==="misaligned"?e.jsxs("p",{className:"mt-1 text-fg-dim",children:["Differs in: ",t.differences.join(", ")]}):null,e.jsx("p",{className:"mt-1 text-fg-dim",children:t.expected.description}),t.expected.parent_names?e.jsxs("p",{className:"text-fg-dim",children:["Parent: ",e.jsx("code",{className:"font-mono",children:t.expected.parent_names.join(", ")})]}):null]})}function U(){const[t,s]=o.useState(()=>R()),r=n=>{s(n),$(n),F(n)};return e.jsxs("section",{className:"mt-6 space-y-4 rounded-xl border border-border bg-card p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"font-serif text-xl text-fg",children:"Text size"}),e.jsx("p",{className:"mt-1 text-xs text-fg-dim",children:"Affects the editor and rendered notes on this device. Your markdown isn't changed."})]}),e.jsxs("fieldset",{className:"space-y-2",children:[e.jsx("legend",{className:"sr-only",children:"View text size"}),L.map(n=>e.jsxs("label",{className:"flex items-start gap-2 text-sm",children:[e.jsx("input",{type:"radio",name:"text-size",value:n,checked:t===n,onChange:()=>r(n),className:"mt-1 accent-accent"}),e.jsx("span",{className:"text-fg",children:_(n)})]},n))]})]})}function Y(){const[t,s]=o.useState(!1);return o.useEffect(()=>{s(M())},[]),t?e.jsx("section",{className:"mt-6 rounded-md border border-border bg-card p-4 text-sm",children:e.jsxs("p",{className:"text-fg-muted",children:[e.jsx("span",{className:"mr-2 inline-block rounded-full bg-emerald-500/20 px-2 py-0.5 text-xs font-medium text-emerald-300",children:"Installed"}),"Parachute Notes is running as an installed app on this device."]})}):null}const y={auto:{title:"Auto",help:"Show the tree only when the vault has enough folders to make it worth the space."},always:{title:"Always",help:"Always show the tree, even on a tag-flat vault."},never:{title:"Never",help:"Hide the tree. The path-prefix text input still works."}};function G({vaultId:t}){const{mode:s,setMode:r}=D(t);return e.jsxs("section",{className:"mt-6 space-y-4 rounded-xl border border-border bg-card p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"font-serif text-xl text-fg",children:"Folder tree (Notes sidebar)"}),e.jsx("p",{className:"mt-1 text-xs text-fg-dim",children:"Controls the collapsible folder tree on the notes list page. Auto-detect renders the tree when the vault has at least five top-level folders or twenty notes in folders."})]}),e.jsxs("fieldset",{className:"space-y-2",children:[e.jsx("legend",{className:"sr-only",children:"Path tree visibility"}),z.map(n=>e.jsxs("label",{className:"flex items-start gap-2 text-sm",children:[e.jsx("input",{type:"radio",name:"path-tree-mode",value:n,checked:s===n,onChange:()=>r(n),className:"mt-1 accent-accent"}),e.jsxs("span",{children:[e.jsx("span",{className:"text-fg",children:y[n].title}),e.jsx("span",{className:"ml-2 text-xs text-fg-dim",children:y[n].help})]})]},n))]})]})}const N={pinned:{title:"Pinned",help:"Tag for notes you want at the top of views."},archived:{title:"Archived",help:"Tag for notes you've moved out of the way."},captureVoice:{title:"Voice capture",help:"Default tag for new voice memos."},captureText:{title:"Text capture",help:"Default tag for quick typed notes."},view:{title:"Saved view",help:"Tag the saved-view notes carry. Used to list them in the notes sidebar."}};function Q({vaultId:t}){const{roles:s,setRoles:r}=P(t),n=V(),h=S(a=>a.push),i=o.useId(),[d,x]=o.useState(s);o.useEffect(()=>x(s),[s]);const u=o.useMemo(()=>{const a=(n.data??[]).map(c=>c.name);return[...new Set(a)].sort((c,l)=>c.localeCompare(l))},[n.data]),f=v.some(a=>d[a].trim()!==s[a]),g=()=>{r(d),h("Tag roles saved.","success")},p=()=>{r(null),x(j),h("Tag roles reset to defaults.","success")};return e.jsxs("section",{className:"mt-6 space-y-4 rounded-xl border border-border bg-card p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"font-serif text-xl text-fg",children:"Tag roles"}),e.jsx("p",{className:"mt-1 text-xs text-fg-dim",children:"Point each role at whatever tag your vault already uses. Changes apply to future notes only — existing notes keep their current tags."})]}),e.jsx("datalist",{id:i,children:u.map(a=>e.jsx("option",{value:a},a))}),e.jsx("div",{className:"space-y-3",children:v.map(a=>e.jsxs("label",{className:"block text-sm",children:[e.jsxs("span",{className:"mb-1 flex items-baseline justify-between gap-2",children:[e.jsx("span",{className:"text-fg-muted",children:N[a].title}),e.jsxs("span",{className:"text-xs text-fg-dim",children:["default: #",j[a]]})]}),e.jsx("input",{type:"text",value:d[a],onChange:c=>x(l=>({...l,[a]:c.target.value})),list:i,placeholder:j[a],"aria-label":`${N[a].title} tag role`,spellCheck:!1,autoCapitalize:"none",autoCorrect:"off",className:"w-full rounded-md border border-border bg-bg px-3 py-2 text-sm text-fg placeholder:text-fg-dim focus:border-accent focus:outline-none"}),e.jsx("span",{className:"mt-1 block text-xs text-fg-dim",children:N[a].help})]},a))}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3 pt-2",children:[e.jsx("button",{type:"button",onClick:g,disabled:!f,className:"rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover disabled:opacity-40",children:"Save"}),e.jsx("button",{type:"button",onClick:p,className:"text-sm text-fg-muted hover:text-accent",children:"Reset to defaults"})]})]})}export{Z as Settings};
import{g as P,r as l,a6 as O,V as R,j as e,u as L,$ as F,h as I,a7 as V,a8 as z,a9 as D,N as B,L as E}from"./index-DKKYWfqC.js";const $=a=>Object.values(a).reduce((n,x)=>n+x,0);function A({mode:a,sources:n,tagOptions:x,onClose:c,onRun:d,onRunMerge:o,pending:i,offline:m}){const p=P(t=>t.push),g=l.useId(),[S,j]=l.useState(a==="rename"?n[0]??"":""),[T,h]=l.useState(null),[u,y]=l.useState(null),[b,N]=l.useState(!1),v=l.useRef(null);l.useEffect(()=>{var t,r;(t=v.current)==null||t.focus(),(r=v.current)==null||r.select()},[]),l.useEffect(()=>{const t=r=>{r.key==="Escape"&&c()};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[c]);const w=S.trim().replace(/^#/,""),f=!i&&!m&&!b&&w.length>0&&!(a==="rename"&&w===n[0]),C=l.useCallback(async()=>{if(f){h(null),y(null);try{const t=await d(w);if("renamed"in t)p(`Renamed on ${t.renamed} note${t.renamed===1?"":"s"}.`,"success");else{const r=$(t.merged);p(`Merged into #${t.target} on ${r} note${r===1?"":"s"}.`,"success")}c()}catch(t){if(t instanceof O&&a==="rename"&&o){y(t.target);return}t instanceof R?h("Session expired. Reconnect to retry."):h(t instanceof Error?t.message:"Operation failed.")}}},[f,w,a,c,d,o,p]),k=l.useCallback(async()=>{if(!(!u||!o)){h(null),N(!0);try{const t=await o(u),r=$(t.merged);p(`Merged into #${t.target} on ${r} note${r===1?"":"s"}.`,"success"),c()}catch(t){t instanceof R?h("Session expired. Reconnect to retry."):h(t instanceof Error?t.message:"Merge failed."),N(!1)}}},[u,c,o,p]),s=a==="rename"?"Rename tag":`Merge ${n.length} tags`;return e.jsx("dialog",{open:!0,"aria-labelledby":"tag-op-title",className:"fixed inset-0 z-40 m-0 flex h-full max-h-full w-full max-w-full items-center justify-center bg-black/60 p-4",onMouseDown:t=>{t.target===t.currentTarget&&c()},children:e.jsxs("div",{className:"w-full max-w-md rounded-md border border-border bg-card p-6 shadow-xl",children:[e.jsx("h2",{id:"tag-op-title",className:"mb-2 font-serif text-xl text-fg",children:s}),e.jsxs("p",{className:"mb-3 text-sm text-fg-muted",children:[a==="rename"?e.jsxs(e.Fragment,{children:["Rename ",e.jsx(M,{children:n[0]})," on every note that carries it. Notes that already have the new tag will end up with one copy."]}):e.jsxs(e.Fragment,{children:["Combine"," ",n.map((t,r)=>e.jsxs("span",{children:[e.jsx(M,{children:t}),r<n.length-1?", ":""]},t))," ","into one tag. The originals are removed."]})," ","Changes apply atomically on the vault."]}),e.jsxs("label",{className:"mb-3 block text-sm",children:[e.jsx("span",{className:"mb-1 block text-fg-muted",children:a==="rename"?"New tag name":"Target tag"}),e.jsx("input",{ref:v,type:"text",value:S,onChange:t=>{j(t.target.value),u&&y(null)},onKeyDown:t=>{t.key==="Enter"&&f&&C()},list:g,"aria-label":a==="rename"?"New tag name":"Merge target tag",spellCheck:!1,autoCapitalize:"none",autoCorrect:"off",className:"w-full rounded-md border border-border bg-bg/40 px-2.5 py-1.5 font-mono text-sm text-fg focus:border-accent focus:outline-none",autoComplete:"off"}),e.jsx("datalist",{id:g,children:x.map(t=>e.jsx("option",{value:t},t))})]}),m?e.jsx("p",{className:"mb-3 text-sm text-amber-300",children:"Offline — tag operations need a live vault connection."}):null,u?e.jsxs("div",{role:"alert",className:"mb-3 rounded-md border border-amber-500/40 bg-amber-500/5 p-3 text-sm",children:[e.jsxs("p",{className:"mb-2 text-amber-300",children:["A tag named ",e.jsx(M,{children:u})," already exists."]}),e.jsxs("p",{className:"mb-3 text-fg-muted",children:["Merge ",e.jsx(M,{children:n[0]})," into ",e.jsx(M,{children:u})," instead? Notes that carry both end up with one copy."]}),e.jsx("button",{type:"button",onClick:()=>void k(),disabled:b,className:"rounded-md bg-accent px-3 py-1.5 text-xs font-medium text-white hover:bg-accent-hover disabled:opacity-40",children:b?"Merging…":`Merge into #${u}`})]}):null,T?e.jsx("p",{role:"alert",className:"mb-3 text-sm text-red-400",children:T}):null,e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:c,className:"min-h-11 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg-muted hover:text-fg",children:"Cancel"}),e.jsx("button",{type:"button",onClick:()=>void C(),disabled:!f,className:"min-h-11 rounded-md bg-accent px-4 py-1.5 text-sm font-medium text-white hover:bg-accent-hover disabled:opacity-40",children:i?a==="rename"?"Renaming…":"Merging…":a==="rename"?"Rename":"Merge"})]})]})})}function M({children:a}){return e.jsxs("span",{className:"rounded bg-bg/60 px-1 py-0.5 font-mono text-xs text-fg",children:["#",a]})}function J(){const a=L(s=>s.getActiveVault()),n=F(),{isOnline:x}=I(),{isPinned:c,togglePin:d}=V((a==null?void 0:a.id)??null),[o,i]=l.useState(""),[m,p]=l.useState("count"),[g,S]=l.useState(new Set),[j,T]=l.useState(null),[h,u]=l.useState(!1),y=z(),b=D(),N=l.useMemo(()=>U(n.data??[],o,m),[n.data,o,m]),v=l.useMemo(()=>(n.data??[]).map(s=>s.name),[n.data]),w=s=>{S(t=>{const r=new Set(t);return r.has(s)?r.delete(s):r.add(s),r})},f=()=>S(new Set);if(!a)return e.jsx(B,{to:"/",replace:!0});const C=g.size,k=!x;return e.jsxs("div",{className:"mx-auto max-w-4xl px-4 py-6 md:px-6 md:py-10",children:[e.jsxs("header",{className:"mb-5 flex flex-wrap items-baseline justify-between gap-x-4 gap-y-3 md:mb-6",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-xs uppercase tracking-wider text-fg-dim",children:a.name}),e.jsx("h1",{className:"font-serif text-2xl tracking-tight md:text-3xl",children:"Tags"})]}),e.jsxs("button",{type:"button",onClick:()=>p(s=>s==="count"?"alpha":"count"),className:"text-sm text-fg-muted hover:text-accent","aria-label":"Toggle tag sort",children:["Sort: ",m==="count"?"most used":"A–Z"]})]}),e.jsx("input",{type:"search",placeholder:"Filter tags…",value:o,onChange:s=>i(s.target.value),"aria-label":"Filter tags",className:"mb-4 w-full rounded-md border border-border bg-card px-3 py-2 text-sm text-fg focus:border-accent focus:outline-none"}),C>0?e.jsxs("div",{className:"mb-4 flex flex-wrap items-center gap-3 rounded-md border border-accent/30 bg-accent/5 px-3 py-2 text-sm","aria-label":"Tag selection actions",children:[e.jsxs("span",{className:"text-fg-muted",children:[C," selected: ",Array.from(g).join(", ")]}),e.jsx("button",{type:"button",onClick:()=>u(!0),disabled:C<2||k,className:"rounded-md bg-accent px-3 py-1 text-xs font-medium text-white hover:bg-accent-hover disabled:opacity-40",children:"Merge into…"}),e.jsx("button",{type:"button",onClick:f,className:"text-xs text-fg-muted hover:text-accent",children:"Clear"})]}):null,n.isPending?e.jsx(Z,{}):n.isError?e.jsx(q,{error:n.error}):N.length===0?e.jsx(G,{filtering:o.trim().length>0,hasAny:(n.data??[]).length>0}):e.jsx("ul",{className:"divide-y divide-border rounded-md border border-border bg-card","aria-label":"Tag list",children:N.map(s=>e.jsx(K,{tag:s,selected:g.has(s.name),onToggle:()=>w(s.name),onRename:()=>T(s.name),pinned:c(s.name),onTogglePin:()=>d(s.name),offline:k},s.name))}),n.data&&n.data.length>0?e.jsxs("p",{className:"mt-6 text-xs text-fg-dim",children:[N.length," / ",n.data.length," tag",n.data.length===1?"":"s"]}):null,j!==null?e.jsx(A,{mode:"rename",sources:[j],tagOptions:v,onClose:()=>T(null),pending:y.isPending||b.isPending,offline:k,onRun:s=>y.mutateAsync({oldName:j,newName:s}),onRunMerge:s=>b.mutateAsync({sources:[j],target:s})}):null,h?e.jsx(A,{mode:"merge",sources:Array.from(g),tagOptions:v,onClose:()=>u(!1),pending:b.isPending,offline:k,onRun:async s=>{const t=await b.mutateAsync({sources:Array.from(g),target:s});return f(),t}}):null]})}function K({tag:a,selected:n,onToggle:x,onRename:c,pinned:d,onTogglePin:o,offline:i}){return e.jsxs("li",{className:"flex items-center gap-3 px-3 py-2 text-sm",children:[e.jsx("input",{type:"checkbox",checked:n,onChange:x,"aria-label":`Select tag ${a.name}`,className:"accent-accent"}),e.jsxs(E,{to:`/?tag=${encodeURIComponent(a.name)}`,className:"flex flex-1 items-baseline gap-2 text-fg hover:text-accent focus-visible:outline-2 focus-visible:outline-accent",children:[e.jsxs("span",{className:"font-mono",children:["#",a.name]}),e.jsx("span",{className:"text-xs text-fg-dim",children:a.count})]}),e.jsx("button",{type:"button",onClick:o,className:d?"text-xs font-medium text-accent hover:text-accent-hover":"text-xs text-fg-muted hover:text-accent","aria-label":d?`Unpin tag ${a.name}`:`Pin tag ${a.name}`,"aria-pressed":d,title:d?"Pinned to home strip — click to unpin":"Pin to home strip",children:d?"★ Pinned":"☆ Pin"}),e.jsx("button",{type:"button",onClick:c,disabled:i,className:"text-xs text-fg-muted hover:text-accent disabled:opacity-40","aria-label":`Rename tag ${a.name}`,children:"Rename"})]})}function U(a,n,x){const c=n.trim().toLowerCase(),o=[...c?a.filter(i=>i.name.toLowerCase().includes(c)):a];return x==="alpha"?o.sort((i,m)=>i.name.localeCompare(m.name)):o.sort((i,m)=>m.count-i.count||i.name.localeCompare(m.name)),o}function Z(){return e.jsx("div",{className:"divide-y divide-border rounded-md border border-border bg-card","aria-busy":"true",children:[0,1,2,3,4].map(a=>e.jsx("div",{className:"h-10 animate-pulse bg-card/60"},a))})}function q({error:a}){const n=a instanceof R;return e.jsxs("div",{className:"rounded-md border border-red-500/30 bg-red-500/5 p-6",children:[e.jsx("p",{className:"mb-2 font-medium text-red-400",children:n?"Session expired":"Could not load tags"}),e.jsx("p",{className:"mb-4 text-sm text-fg-muted",children:a.message}),n?e.jsx(E,{to:"/add",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Reconnect vault"}):null]})}function G({filtering:a,hasAny:n}){return a&&n?e.jsx("div",{className:"rounded-md border border-border bg-card p-10 text-center",children:e.jsx("p",{className:"text-fg-muted",children:"No tags match your filter."})}):e.jsxs("div",{className:"rounded-md border border-border bg-card p-10 text-center",children:[e.jsx("p",{className:"mb-3 text-fg-muted",children:"No tags in this vault yet."}),e.jsx(E,{to:"/new",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Create a note"})]})}export{J as Tags};
import{u as w,c as $,a as A,r as D,j as e,N as E,L as d,b as C,V as S}from"./index-DKKYWfqC.js";import{t as V,d as N,a as g,e as K,b as f}from"./dates-DfXc2iZW.js";function F(){const a=w(i=>i.getActiveVault()),[s]=$(),t=s.get("date"),u=V(),r=t??u,x=N(r),n=A(),c=D.useMemo(()=>{const i=[],m=[];if(!n.data||!x)return{created:i,edited:m};for(const l of n.data){const b=g(l.createdAt),k=g(l.updatedAt??l.createdAt);b===r&&i.push(l),k===r&&b!==r&&m.push(l)}return{created:i,edited:m}},[n.data,x,r]);if(!a)return e.jsx(E,{to:"/",replace:!0});if(!x)return e.jsxs("div",{className:"mx-auto max-w-3xl px-4 py-6 md:px-6 md:py-10",children:[e.jsxs("p",{className:"text-sm text-red-400",children:["Invalid date in URL: ",r]}),e.jsx(d,{to:"/today",className:"text-sm text-accent hover:underline",children:"Back to today"})]});const o=r===u,p=j(r,-1),h=j(r,1),v=r.slice(0,7);return e.jsxs("div",{className:"mx-auto max-w-3xl px-4 py-6 md:px-6 md:py-10",children:[e.jsxs("header",{className:"mb-6 flex flex-wrap items-baseline justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-xs uppercase tracking-wider text-fg-dim",children:o?"Today":"On"}),e.jsx("h1",{className:"font-serif text-2xl tracking-tight md:text-3xl",children:K(r)})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm",children:[e.jsxs(d,{to:`/today?date=${p}`,className:"rounded-md border border-border bg-card px-3 py-1.5 text-fg-muted hover:text-accent","aria-label":"Previous day",children:["← ",p]}),o?null:e.jsx(d,{to:"/today",className:"rounded-md border border-border bg-card px-3 py-1.5 text-fg-muted hover:text-accent",children:"Today"}),e.jsxs(d,{to:`/today?date=${h}`,className:"rounded-md border border-border bg-card px-3 py-1.5 text-fg-muted hover:text-accent","aria-label":"Next day",children:[h," →"]}),e.jsx(d,{to:`/calendar?month=${v}`,className:"rounded-md border border-border bg-card px-3 py-1.5 text-fg-muted hover:text-accent",children:"Calendar"}),e.jsx(d,{to:"/capture",className:"rounded-md bg-accent px-3 py-1.5 font-medium text-white hover:bg-accent-hover",children:"+ Capture"})]})]}),n.isPending?e.jsx(L,{}):n.isError?e.jsx(R,{error:n.error}):c.created.length===0&&c.edited.length===0?e.jsx(P,{isToday:o,targetKey:r}):e.jsxs("div",{className:"space-y-8",children:[c.created.length>0?e.jsx(y,{title:o?"Created today":`Created on ${r}`,notes:c.created}):null,c.edited.length>0?e.jsx(y,{title:o?"Edited today":`Edited on ${r}`,notes:c.edited}):null]})]})}function j(a,s){const t=N(a);return t?(t.setDate(t.getDate()+s),`${t.getFullYear()}-${f(t.getMonth()+1)}-${f(t.getDate())}`):a}function y({title:a,notes:s}){return e.jsxs("section",{children:[e.jsxs("h2",{className:"mb-2 text-xs uppercase tracking-wider text-fg-dim",children:[a," (",s.length,")"]}),e.jsx("ol",{className:"divide-y divide-border rounded-md border border-border bg-card",children:s.map(t=>e.jsx("li",{children:e.jsxs(d,{to:`/n/${encodeURIComponent(t.id)}`,className:"block px-4 py-3 hover:bg-bg/60 focus:bg-bg/60 focus:outline-none",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-4",children:[e.jsx("span",{className:"truncate font-mono text-sm text-fg",children:t.path??t.id}),e.jsx("span",{className:"shrink-0 text-xs text-fg-dim",children:C(t.updatedAt??t.createdAt)})]}),t.preview?e.jsx("p",{className:"mt-1 truncate text-sm text-fg-muted",children:t.preview}):null]})},t.id))})]})}function P({isToday:a,targetKey:s}){return e.jsxs("div",{className:"rounded-md border border-border bg-card p-10 text-center",children:[e.jsx("p",{className:"mb-4 text-fg-muted",children:a?"Nothing yet today — start capturing.":`Nothing on ${s}.`}),a?e.jsx(d,{to:"/capture",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Open capture"}):null]})}function L(){return e.jsx("div",{className:"space-y-3","aria-busy":"true",children:[0,1,2,3].map(a=>e.jsx("div",{className:"h-14 animate-pulse rounded-md bg-border/30"},a))})}function R({error:a}){const s=a instanceof S;return e.jsxs("div",{className:"rounded-md border border-red-500/30 bg-red-500/5 p-6",children:[e.jsx("p",{className:"mb-2 font-medium text-red-400",children:s?"Session expired":"Could not load notes"}),e.jsx("p",{className:"mb-4 text-sm text-fg-muted",children:a.message}),s?e.jsx(d,{to:"/add",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Reconnect vault"}):null]})}export{F as Today};

Sorry, the diff of this file is too big to display

const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/react-force-graph-2d-YVoN3oXw.js","assets/index-DKKYWfqC.js","assets/index-BU6cVU21.css"])))=>i.map(i=>d[i]);
import{u as w,aa as N,r as f,j as s,N as k,L as v,y as C,V as I,_ as M}from"./index-DKKYWfqC.js";const S={search:"",tags:[]};function T(e){const t=new Map;for(const i of e)t.set(i.id,i);const a=new Map,o=new Map;for(const i of e)for(const n of i.links??[]){if(n.sourceId===n.targetId||!t.has(n.sourceId)||!t.has(n.targetId))continue;const c=`${n.sourceId}|${n.targetId}|${n.relationship}`;a.has(c)||(a.set(c,{source:n.sourceId,target:n.targetId,relationship:n.relationship}),o.set(n.sourceId,(o.get(n.sourceId)??0)+1),o.set(n.targetId,(o.get(n.targetId)??0)+1))}return{nodes:e.map(i=>{var c;const n=i.tags??[];return{id:i.id,path:i.path,title:A(i),tags:n,topTag:n[0],degree:o.get(i.id)??0,summary:typeof((c=i.metadata)==null?void 0:c.summary)=="string"?i.metadata.summary:void 0}}),edges:[...a.values()]}}function A(e){return e.path?(e.path.split("/").pop()??e.path).replace(/\.md$/i,""):e.id}function R(e,t){const a=t.search.trim().toLowerCase();return!(a&&![e.path??"",e.title,e.id].join(" ").toLowerCase().includes(a)||t.tags.length>0&&!t.tags.some(d=>e.tags.includes(d)))}function E(e){const t=new Map;for(const a of e)for(const o of a.tags)t.set(o,(t.get(o)??0)+1);return[...t.entries()].sort((a,o)=>o[1]-a[1]||a[0].localeCompare(o[0])).map(([a])=>a)}function _(e){if(!e)return"#8a9a7a";let t=0;for(let o=0;o<e.length;o++)t=t*31+e.charCodeAt(o)&16777215;return`hsl(${t%360}, 40%, 55%)`}const F=f.lazy(()=>M(()=>import("./react-force-graph-2d-YVoN3oXw.js"),__vite__mapDeps([0,1,2]))),L=20;function O(){const e=w(c=>c.getActiveVault()),t=N(),[a,o]=f.useState(S),d=f.useMemo(()=>t.data?T(t.data):null,[t.data]),i=f.useMemo(()=>d?E(d.nodes):[],[d]),n=f.useMemo(()=>d?new Set(d.nodes.filter(c=>R(c,a)).map(c=>c.id)):new Set,[d,a]);return e?s.jsxs("div",{className:"flex h-[calc(100dvh-5rem)] flex-col",children:[s.jsx("div",{className:"border-b border-border bg-card/40 px-6 py-3",children:s.jsxs("div",{className:"mx-auto flex max-w-6xl flex-wrap items-center gap-4",children:[s.jsx("input",{type:"search",value:a.search,onChange:c=>o(m=>({...m,search:c.target.value})),placeholder:"Search nodes…","aria-label":"Search graph nodes",className:"min-w-48 rounded-md border border-border bg-card px-3 py-1.5 text-sm text-fg focus:border-accent focus:outline-none"}),s.jsx($,{allTags:i,selected:a.tags,onChange:c=>o(m=>({...m,tags:c}))}),d?s.jsxs("span",{className:"text-xs text-fg-dim",children:[n.size," / ",d.nodes.length," notes"]}):null]})}),s.jsx("div",{className:"min-h-0 flex-1",children:s.jsx(P,{query:t,graph:d,matched:n})})]}):s.jsx(k,{to:"/",replace:!0})}function P({query:e,graph:t,matched:a}){return e.isPending?s.jsx(y,{message:"Loading vault…"}):e.isError?s.jsx(B,{error:e.error}):!t||t.nodes.length===0?s.jsx("div",{className:"flex h-full items-center justify-center p-10",children:s.jsxs("div",{className:"max-w-sm rounded-md border border-border bg-card p-8 text-center",children:[s.jsx("p",{className:"mb-2 font-serif text-xl",children:"No notes yet"}),s.jsx("p",{className:"mb-4 text-sm text-fg-muted",children:"This vault is empty. Start by creating the first note."}),s.jsx(v,{to:"/new",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Create a note"})]})}):s.jsx(z,{graph:t,matched:a})}function $({allTags:e,selected:t,onChange:a}){const o=e.slice(0,L);if(o.length===0)return null;const d=i=>a(t.includes(i)?t.filter(n=>n!==i):[...t,i]);return s.jsxs("fieldset",{"aria-label":"Filter by tag",className:"flex flex-wrap items-center gap-1 text-xs text-fg-dim",children:[s.jsx("legend",{className:"mr-1 inline-block",children:"Tags"}),o.map(i=>{const n=t.includes(i);return s.jsx("button",{type:"button","aria-pressed":n,onClick:()=>d(i),className:n?"max-w-full break-all rounded-full border border-accent bg-accent/10 px-2 py-0.5 text-accent":"max-w-full break-all rounded-full border border-border bg-card px-2 py-0.5 hover:text-accent",children:i},i)}),t.length>0?s.jsx("button",{type:"button",onClick:()=>a([]),className:"ml-1 text-xs text-fg-dim hover:text-accent",children:"Clear"}):null]})}function y({message:e}){return s.jsx("div",{"aria-busy":"true",className:"flex h-full animate-pulse items-center justify-center bg-card/30 text-sm text-fg-dim",children:e})}function z({graph:e,matched:t}){const a=C(),o=f.useRef(null),d=f.useRef(null),[i,n]=f.useState({w:800,h:600});f.useEffect(()=>{const r=o.current;if(!r)return;const l=()=>{const u=r.getBoundingClientRect();n({w:Math.max(320,Math.floor(u.width)),h:Math.max(320,Math.floor(u.height))})};l();const h=new ResizeObserver(l);return h.observe(r),()=>h.disconnect()},[]);const c=()=>{var r,l;(l=(r=d.current)==null?void 0:r.zoomToFit)==null||l.call(r,400,40)},m=f.useMemo(()=>({nodes:e.nodes.map(r=>({...r})),links:e.edges.map(r=>({source:r.source,target:r.target,rel:r.relationship}))}),[e]),g=t.size!==e.nodes.length,j=r=>!g||t.has(r)?1:.15;return s.jsxs("div",{ref:o,"data-testid":"vault-graph-canvas",className:"relative h-full w-full touch-none",children:[s.jsx(f.Suspense,{fallback:s.jsx(y,{message:"Rendering graph…"}),children:s.jsx(F,{ref:d,graphData:m,width:i.w,height:i.h,backgroundColor:"rgba(0,0,0,0)",nodeLabel:r=>V(r),nodeRelSize:5,nodeVal:r=>2+Math.min(r.degree,12),nodeColor:r=>{const l=r,h=_(l.topTag);return g&&!t.has(l.id)?G(h):h},nodePointerAreaPaint:(r,l,h)=>{const u=r;if(u.x==null||u.y==null)return;const x=2+Math.min(u.degree,12),p=Math.max(Math.sqrt(x)*5,10);h.fillStyle=l,h.beginPath(),h.arc(u.x,u.y,p,0,2*Math.PI),h.fill()},linkColor:r=>{const l=r,h=b(l.source),u=b(l.target);return g&&(!t.has(h)||!t.has(u))?"rgba(160, 160, 160, 0.08)":"rgba(160, 160, 160, 0.35)"},linkDirectionalArrowLength:2.5,linkDirectionalArrowRelPos:1,cooldownTicks:100,onEngineStop:()=>c(),nodeCanvasObjectMode:()=>"after",nodeCanvasObject:(r,l,h)=>{const u=r;if(u.x==null||u.y==null||j(u.id)<.5)return;const p=10/h;l.font=`${p}px sans-serif`,l.fillStyle="rgba(220, 220, 220, 0.8)",l.textAlign="left",l.textBaseline="middle",l.fillText(u.title,u.x+6,u.y)},onNodeClick:r=>{a(`/n/${encodeURIComponent(r.id)}`)}})}),s.jsx("button",{type:"button",onClick:c,className:"absolute right-3 bottom-3 rounded-md border border-border bg-card/90 px-3 py-1.5 text-xs text-fg-muted shadow-sm backdrop-blur hover:text-accent",children:"Fit to screen"})]})}function V(e){const t=[e.path??e.id,`${e.degree} link${e.degree===1?"":"s"}`];return e.tags.length>0&&t.push(`tags: ${e.tags.join(", ")}`),e.summary&&t.push(e.summary),t.join(`
`)}function G(e){return e.startsWith("hsl(")?e.replace("hsl(","hsla(").replace(")",", 0.2)"):e}function b(e){return typeof e=="string"?e:e&&typeof e=="object"&&"id"in e?String(e.id):""}function B({error:e}){const t=e instanceof I;return s.jsx("div",{className:"flex h-full items-center justify-center p-10",children:s.jsxs("div",{className:"max-w-md rounded-md border border-red-500/30 bg-red-500/5 p-6",children:[s.jsx("p",{className:"mb-2 font-medium text-red-400",children:t?"Session expired":"Could not load vault"}),s.jsx("p",{className:"mb-4 text-sm text-fg-muted",children:e.message}),t?s.jsx(v,{to:"/add",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Reconnect vault"}):null]})})}export{O as VaultGraph};
import{u as a,j as e,L as c,ab as m}from"./index-DKKYWfqC.js";function u(){const l=a(t=>t.vaults),d=a(t=>t.activeVaultId),i=a(t=>t.removeVault),o=a(t=>t.setActiveVault),n=Object.values(l).sort((t,s)=>t.name.localeCompare(s.name));return e.jsxs("div",{className:"mx-auto max-w-3xl px-6 py-16",children:[e.jsxs("div",{className:"mb-8 flex items-center justify-between",children:[e.jsx("h1",{className:"font-serif text-4xl tracking-tight",children:"Vaults"}),e.jsx(c,{to:"/add",className:"rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent-hover",children:"Add vault"})]}),n.length===0?e.jsx("p",{className:"text-fg-muted",children:"No vaults connected yet."}):e.jsx("ul",{className:"space-y-3",children:n.map(t=>{const s=t.id===d,r=m(t.url);return e.jsxs("li",{className:"rounded-lg border border-border bg-card p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"font-serif text-lg text-fg",children:t.name}),s?e.jsx("span",{className:"rounded bg-accent/10 px-2 py-0.5 text-xs text-accent",children:"active"}):null,e.jsx("span",{className:"rounded border border-border px-2 py-0.5 text-xs text-fg-dim",children:t.scope}),r?e.jsx("span",{className:"rounded border border-amber-500/40 bg-amber-500/10 px-2 py-0.5 text-xs text-amber-500",children:"needs reconnect"}):null]}),e.jsx("p",{className:"mt-1 truncate font-mono text-xs text-fg-muted",children:t.url})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-4 text-sm",children:[s?null:e.jsx("button",{type:"button",onClick:()=>o(t.id),className:"text-fg-muted hover:text-accent",children:"Make active"}),e.jsx("button",{type:"button",onClick:()=>{confirm(`Remove ${t.name}? The access token will be deleted.`)&&i(t.id)},className:"text-red-400 hover:text-red-300",children:"Remove"})]})]}),r?e.jsxs("p",{className:"mt-3 rounded border border-amber-500/30 bg-amber-500/5 px-3 py-2 text-xs text-amber-500",children:["Vault now serves under ",e.jsx("code",{children:"/vault/<name>/"}),". This stored URL is from the older scheme and won't reach the new endpoints. Remove this entry and"," ",e.jsx(c,{to:"/add",className:"underline",children:"add it again"})," ","— discovery will pick the right URL automatically."]}):null]},t.id)})})]})}export{u as Vaults};
try{self["workbox:window:7.3.0"]&&_()}catch{}function b(n,r){return new Promise((function(t){var o=new MessageChannel;o.port1.onmessage=function(f){t(f.data)},n.postMessage(r,[o.port2])}))}function P(n,r){(r==null||r>n.length)&&(r=n.length);for(var t=0,o=Array(r);t<r;t++)o[t]=n[t];return o}function j(n,r){for(var t=0;t<r.length;t++){var o=r[t];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(n,W(o.key),o)}}function S(n,r){var t=typeof Symbol<"u"&&n[Symbol.iterator]||n["@@iterator"];if(t)return(t=t.call(n)).next.bind(t);if(Array.isArray(n)||(t=(function(f,c){if(f){if(typeof f=="string")return P(f,c);var a={}.toString.call(f).slice(8,-1);return a==="Object"&&f.constructor&&(a=f.constructor.name),a==="Map"||a==="Set"?Array.from(f):a==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)?P(f,c):void 0}})(n))||r){t&&(n=t);var o=0;return function(){return o>=n.length?{done:!0}:{done:!1,value:n[o++]}}}throw new TypeError(`Invalid attempt to iterate non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function w(n,r){return w=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,o){return t.__proto__=o,t},w(n,r)}function W(n){var r=(function(t,o){if(typeof t!="object"||!t)return t;var f=t[Symbol.toPrimitive];if(f!==void 0){var c=f.call(t,o);if(typeof c!="object")return c;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(t)})(n,"string");return typeof r=="symbol"?r:r+""}try{self["workbox:core:7.3.0"]&&_()}catch{}var m=function(){var n=this;this.promise=new Promise((function(r,t){n.resolve=r,n.reject=t}))};function y(n,r){var t=location.href;return new URL(n,t).href===new URL(r,t).href}var d=function(n,r){this.type=n,Object.assign(this,r)};function l(n,r,t){return t?r?r(n):n:(n&&n.then||(n=Promise.resolve(n)),r?n.then(r):n)}function k(){}var L={type:"SKIP_WAITING"};function E(n,r){return n&&n.then?n.then(k):Promise.resolve()}var O=(function(n){function r(c,a){var e,i;return a===void 0&&(a={}),(e=n.call(this)||this).nn={},e.tn=0,e.rn=new m,e.en=new m,e.on=new m,e.un=0,e.an=new Set,e.cn=function(){var u=e.fn,s=u.installing;e.tn>0||!y(s.scriptURL,e.sn.toString())||performance.now()>e.un+6e4?(e.vn=s,u.removeEventListener("updatefound",e.cn)):(e.hn=s,e.an.add(s),e.rn.resolve(s)),++e.tn,s.addEventListener("statechange",e.ln)},e.ln=function(u){var s=e.fn,v=u.target,h=v.state,p=v===e.vn,g={sw:v,isExternal:p,originalEvent:u};!p&&e.mn&&(g.isUpdate=!0),e.dispatchEvent(new d(h,g)),h==="installed"?e.wn=self.setTimeout((function(){h==="installed"&&s.waiting===v&&e.dispatchEvent(new d("waiting",g))}),200):h==="activating"&&(clearTimeout(e.wn),p||e.en.resolve(v))},e.yn=function(u){var s=e.hn,v=s!==navigator.serviceWorker.controller;e.dispatchEvent(new d("controlling",{isExternal:v,originalEvent:u,sw:s,isUpdate:e.mn})),v||e.on.resolve(s)},e.gn=(i=function(u){var s=u.data,v=u.ports,h=u.source;return l(e.getSW(),(function(){e.an.has(h)&&e.dispatchEvent(new d("message",{data:s,originalEvent:u,ports:v,sw:h}))}))},function(){for(var u=[],s=0;s<arguments.length;s++)u[s]=arguments[s];try{return Promise.resolve(i.apply(this,u))}catch(v){return Promise.reject(v)}}),e.sn=c,e.nn=a,navigator.serviceWorker.addEventListener("message",e.gn),e}var t,o;o=n,(t=r).prototype=Object.create(o.prototype),t.prototype.constructor=t,w(t,o);var f=r.prototype;return f.register=function(c){var a=(c===void 0?{}:c).immediate,e=a!==void 0&&a;try{var i=this;return l((function(u,s){var v=u();return v&&v.then?v.then(s):s(v)})((function(){if(!e&&document.readyState!=="complete")return E(new Promise((function(u){return window.addEventListener("load",u)})))}),(function(){return i.mn=!!navigator.serviceWorker.controller,i.dn=i.pn(),l(i.bn(),(function(u){i.fn=u,i.dn&&(i.hn=i.dn,i.en.resolve(i.dn),i.on.resolve(i.dn),i.dn.addEventListener("statechange",i.ln,{once:!0}));var s=i.fn.waiting;return s&&y(s.scriptURL,i.sn.toString())&&(i.hn=s,Promise.resolve().then((function(){i.dispatchEvent(new d("waiting",{sw:s,wasWaitingBeforeRegister:!0}))})).then((function(){}))),i.hn&&(i.rn.resolve(i.hn),i.an.add(i.hn)),i.fn.addEventListener("updatefound",i.cn),navigator.serviceWorker.addEventListener("controllerchange",i.yn),i.fn}))})))}catch(u){return Promise.reject(u)}},f.update=function(){try{return this.fn?l(E(this.fn.update())):l()}catch(c){return Promise.reject(c)}},f.getSW=function(){return this.hn!==void 0?Promise.resolve(this.hn):this.rn.promise},f.messageSW=function(c){try{return l(this.getSW(),(function(a){return b(a,c)}))}catch(a){return Promise.reject(a)}},f.messageSkipWaiting=function(){this.fn&&this.fn.waiting&&b(this.fn.waiting,L)},f.pn=function(){var c=navigator.serviceWorker.controller;return c&&y(c.scriptURL,this.sn.toString())?c:void 0},f.bn=function(){try{var c=this;return l((function(a,e){try{var i=a()}catch(u){return e(u)}return i&&i.then?i.then(void 0,e):i})((function(){return l(navigator.serviceWorker.register(c.sn,c.nn),(function(a){return c.un=performance.now(),a}))}),(function(a){throw a})))}catch(a){return Promise.reject(a)}},(function(c,a,e){return a&&j(c.prototype,a),Object.defineProperty(c,"prototype",{writable:!1}),c})(r,[{key:"active",get:function(){return this.en.promise}},{key:"controlling",get:function(){return this.on.promise}}])})((function(){function n(){this.Pn=new Map}var r=n.prototype;return r.addEventListener=function(t,o){this.jn(t).add(o)},r.removeEventListener=function(t,o){this.jn(t).delete(o)},r.dispatchEvent=function(t){t.target=this;for(var o,f=S(this.jn(t.type));!(o=f()).done;)(0,o.value)(t)},r.jn=function(t){return this.Pn.has(t)||this.Pn.set(t,new Set),this.Pn.get(t)},n})());export{O as Workbox,d as WorkboxEvent,b as messageSW};
define(["exports"],function(t){"use strict";try{self["workbox:core:7.3.0"]&&_()}catch(t){}const e=(t,...e)=>{let s=t;return e.length>0&&(s+=` :: ${JSON.stringify(e)}`),s};class s extends Error{constructor(t,s){super(e(t,s)),this.name=t,this.details=s}}try{self["workbox:routing:7.3.0"]&&_()}catch(t){}const n=t=>t&&"object"==typeof t?t:{handle:t};class i{constructor(t,e,s="GET"){this.handler=n(e),this.match=t,this.method=s}setCatchHandler(t){this.catchHandler=n(t)}}class r extends i{constructor(t,e,s){super(({url:e})=>{const s=t.exec(e.href);if(s&&(e.origin===location.origin||0===s.index))return s.slice(1)},e,s)}}class a{constructor(){this.t=new Map,this.i=new Map}get routes(){return this.t}addFetchListener(){self.addEventListener("fetch",t=>{const{request:e}=t,s=this.handleRequest({request:e,event:t});s&&t.respondWith(s)})}addCacheListener(){self.addEventListener("message",t=>{if(t.data&&"CACHE_URLS"===t.data.type){const{payload:e}=t.data,s=Promise.all(e.urlsToCache.map(e=>{"string"==typeof e&&(e=[e]);const s=new Request(...e);return this.handleRequest({request:s,event:t})}));t.waitUntil(s),t.ports&&t.ports[0]&&s.then(()=>t.ports[0].postMessage(!0))}})}handleRequest({request:t,event:e}){const s=new URL(t.url,location.href);if(!s.protocol.startsWith("http"))return;const n=s.origin===location.origin,{params:i,route:r}=this.findMatchingRoute({event:e,request:t,sameOrigin:n,url:s});let a=r&&r.handler;const o=t.method;if(!a&&this.i.has(o)&&(a=this.i.get(o)),!a)return;let c;try{c=a.handle({url:s,request:t,event:e,params:i})}catch(t){c=Promise.reject(t)}const h=r&&r.catchHandler;return c instanceof Promise&&(this.o||h)&&(c=c.catch(async n=>{if(h)try{return await h.handle({url:s,request:t,event:e,params:i})}catch(t){t instanceof Error&&(n=t)}if(this.o)return this.o.handle({url:s,request:t,event:e});throw n})),c}findMatchingRoute({url:t,sameOrigin:e,request:s,event:n}){const i=this.t.get(s.method)||[];for(const r of i){let i;const a=r.match({url:t,sameOrigin:e,request:s,event:n});if(a)return i=a,(Array.isArray(i)&&0===i.length||a.constructor===Object&&0===Object.keys(a).length||"boolean"==typeof a)&&(i=void 0),{route:r,params:i}}return{}}setDefaultHandler(t,e="GET"){this.i.set(e,n(t))}setCatchHandler(t){this.o=n(t)}registerRoute(t){this.t.has(t.method)||this.t.set(t.method,[]),this.t.get(t.method).push(t)}unregisterRoute(t){if(!this.t.has(t.method))throw new s("unregister-route-but-not-found-with-method",{method:t.method});const e=this.t.get(t.method).indexOf(t);if(!(e>-1))throw new s("unregister-route-route-not-registered");this.t.get(t.method).splice(e,1)}}let o;const c=()=>(o||(o=new a,o.addFetchListener(),o.addCacheListener()),o);function h(t,e,n){let a;if("string"==typeof t){const s=new URL(t,location.href);a=new i(({url:t})=>t.href===s.href,e,n)}else if(t instanceof RegExp)a=new r(t,e,n);else if("function"==typeof t)a=new i(t,e,n);else{if(!(t instanceof i))throw new s("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});a=t}return c().registerRoute(a),a}const u={googleAnalytics:"googleAnalytics",precache:"precache-v2",prefix:"workbox",runtime:"runtime",suffix:"undefined"!=typeof registration?registration.scope:""},l=t=>[u.prefix,t,u.suffix].filter(t=>t&&t.length>0).join("-"),f=t=>t||l(u.precache),w=t=>t||l(u.runtime);function d(t){t.then(()=>{})}const p=new Set;function y(){return y=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var s=arguments[e];for(var n in s)({}).hasOwnProperty.call(s,n)&&(t[n]=s[n])}return t},y.apply(null,arguments)}let m,g;const R=new WeakMap,v=new WeakMap,b=new WeakMap,q=new WeakMap,D=new WeakMap;let U={get(t,e,s){if(t instanceof IDBTransaction){if("done"===e)return v.get(t);if("objectStoreNames"===e)return t.objectStoreNames||b.get(t);if("store"===e)return s.objectStoreNames[1]?void 0:s.objectStore(s.objectStoreNames[0])}return I(t[e])},set:(t,e,s)=>(t[e]=s,!0),has:(t,e)=>t instanceof IDBTransaction&&("done"===e||"store"===e)||e in t};function x(t){return t!==IDBDatabase.prototype.transaction||"objectStoreNames"in IDBTransaction.prototype?(g||(g=[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey])).includes(t)?function(...e){return t.apply(C(this),e),I(R.get(this))}:function(...e){return I(t.apply(C(this),e))}:function(e,...s){const n=t.call(C(this),e,...s);return b.set(n,e.sort?e.sort():[e]),I(n)}}function L(t){return"function"==typeof t?x(t):(t instanceof IDBTransaction&&function(t){if(v.has(t))return;const e=new Promise((e,s)=>{const n=()=>{t.removeEventListener("complete",i),t.removeEventListener("error",r),t.removeEventListener("abort",r)},i=()=>{e(),n()},r=()=>{s(t.error||new DOMException("AbortError","AbortError")),n()};t.addEventListener("complete",i),t.addEventListener("error",r),t.addEventListener("abort",r)});v.set(t,e)}(t),e=t,(m||(m=[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction])).some(t=>e instanceof t)?new Proxy(t,U):t);var e}function I(t){if(t instanceof IDBRequest)return function(t){const e=new Promise((e,s)=>{const n=()=>{t.removeEventListener("success",i),t.removeEventListener("error",r)},i=()=>{e(I(t.result)),n()},r=()=>{s(t.error),n()};t.addEventListener("success",i),t.addEventListener("error",r)});return e.then(e=>{e instanceof IDBCursor&&R.set(e,t)}).catch(()=>{}),D.set(e,t),e}(t);if(q.has(t))return q.get(t);const e=L(t);return e!==t&&(q.set(t,e),D.set(e,t)),e}const C=t=>D.get(t);const E=["get","getKey","getAll","getAllKeys","count"],N=["put","add","delete","clear"],O=new Map;function B(t,e){if(!(t instanceof IDBDatabase)||e in t||"string"!=typeof e)return;if(O.get(e))return O.get(e);const s=e.replace(/FromIndex$/,""),n=e!==s,i=N.includes(s);if(!(s in(n?IDBIndex:IDBObjectStore).prototype)||!i&&!E.includes(s))return;const r=async function(t,...e){const r=this.transaction(t,i?"readwrite":"readonly");let a=r.store;return n&&(a=a.index(e.shift())),(await Promise.all([a[s](...e),i&&r.done]))[0]};return O.set(e,r),r}U=(t=>y({},t,{get:(e,s,n)=>B(e,s)||t.get(e,s,n),has:(e,s)=>!!B(e,s)||t.has(e,s)}))(U);try{self["workbox:expiration:7.3.0"]&&_()}catch(t){}const k="cache-entries",M=t=>{const e=new URL(t,location.href);return e.hash="",e.href};class T{constructor(t){this.h=null,this.u=t}l(t){const e=t.createObjectStore(k,{keyPath:"id"});e.createIndex("cacheName","cacheName",{unique:!1}),e.createIndex("timestamp","timestamp",{unique:!1})}p(t){this.l(t),this.u&&function(t,{blocked:e}={}){const s=indexedDB.deleteDatabase(t);e&&s.addEventListener("blocked",t=>e(t.oldVersion,t)),I(s).then(()=>{})}(this.u)}async setTimestamp(t,e){const s={url:t=M(t),timestamp:e,cacheName:this.u,id:this.m(t)},n=(await this.getDb()).transaction(k,"readwrite",{durability:"relaxed"});await n.store.put(s),await n.done}async getTimestamp(t){const e=await this.getDb(),s=await e.get(k,this.m(t));return null==s?void 0:s.timestamp}async expireEntries(t,e){const s=await this.getDb();let n=await s.transaction(k).store.index("timestamp").openCursor(null,"prev");const i=[];let r=0;for(;n;){const s=n.value;s.cacheName===this.u&&(t&&s.timestamp<t||e&&r>=e?i.push(n.value):r++),n=await n.continue()}const a=[];for(const t of i)await s.delete(k,t.id),a.push(t.url);return a}m(t){return this.u+"|"+M(t)}async getDb(){return this.h||(this.h=await function(t,e,{blocked:s,upgrade:n,blocking:i,terminated:r}={}){const a=indexedDB.open(t,e),o=I(a);return n&&a.addEventListener("upgradeneeded",t=>{n(I(a.result),t.oldVersion,t.newVersion,I(a.transaction),t)}),s&&a.addEventListener("blocked",t=>s(t.oldVersion,t.newVersion,t)),o.then(t=>{r&&t.addEventListener("close",()=>r()),i&&t.addEventListener("versionchange",t=>i(t.oldVersion,t.newVersion,t))}).catch(()=>{}),o}("workbox-expiration",1,{upgrade:this.p.bind(this)})),this.h}}class j{constructor(t,e={}){this.R=!1,this.v=!1,this.q=e.maxEntries,this.D=e.maxAgeSeconds,this.U=e.matchOptions,this.u=t,this._=new T(t)}async expireEntries(){if(this.R)return void(this.v=!0);this.R=!0;const t=this.D?Date.now()-1e3*this.D:0,e=await this._.expireEntries(t,this.q),s=await self.caches.open(this.u);for(const t of e)await s.delete(t,this.U);this.R=!1,this.v&&(this.v=!1,d(this.expireEntries()))}async updateTimestamp(t){await this._.setTimestamp(t,Date.now())}async isURLExpired(t){if(this.D){const e=await this._.getTimestamp(t),s=Date.now()-1e3*this.D;return void 0===e||e<s}return!1}async delete(){this.v=!1,await this._.expireEntries(1/0)}}try{self["workbox:cacheable-response:7.3.0"]&&_()}catch(t){}class W{constructor(t={}){this.L=t.statuses,this.I=t.headers}isResponseCacheable(t){let e=!0;return this.L&&(e=this.L.includes(t.status)),this.I&&e&&(e=Object.keys(this.I).some(e=>t.headers.get(e)===this.I[e])),e}}try{self["workbox:strategies:7.3.0"]&&_()}catch(t){}const P={cacheWillUpdate:async({response:t})=>200===t.status||0===t.status?t:null};function S(t,e){const s=new URL(t);for(const t of e)s.searchParams.delete(t);return s.href}class K{constructor(){this.promise=new Promise((t,e)=>{this.resolve=t,this.reject=e})}}function A(t){return"string"==typeof t?new Request(t):t}class F{constructor(t,e){this.C={},Object.assign(this,e),this.event=e.event,this.N=t,this.O=new K,this.B=[],this.k=[...t.plugins],this.M=new Map;for(const t of this.k)this.M.set(t,{});this.event.waitUntil(this.O.promise)}async fetch(t){const{event:e}=this;let n=A(t);if("navigate"===n.mode&&e instanceof FetchEvent&&e.preloadResponse){const t=await e.preloadResponse;if(t)return t}const i=this.hasCallback("fetchDidFail")?n.clone():null;try{for(const t of this.iterateCallbacks("requestWillFetch"))n=await t({request:n.clone(),event:e})}catch(t){if(t instanceof Error)throw new s("plugin-error-request-will-fetch",{thrownErrorMessage:t.message})}const r=n.clone();try{let t;t=await fetch(n,"navigate"===n.mode?void 0:this.N.fetchOptions);for(const s of this.iterateCallbacks("fetchDidSucceed"))t=await s({event:e,request:r,response:t});return t}catch(t){throw i&&await this.runCallbacks("fetchDidFail",{error:t,event:e,originalRequest:i.clone(),request:r.clone()}),t}}async fetchAndCachePut(t){const e=await this.fetch(t),s=e.clone();return this.waitUntil(this.cachePut(t,s)),e}async cacheMatch(t){const e=A(t);let s;const{cacheName:n,matchOptions:i}=this.N,r=await this.getCacheKey(e,"read"),a=Object.assign(Object.assign({},i),{cacheName:n});s=await caches.match(r,a);for(const t of this.iterateCallbacks("cachedResponseWillBeUsed"))s=await t({cacheName:n,matchOptions:i,cachedResponse:s,request:r,event:this.event})||void 0;return s}async cachePut(t,e){const n=A(t);var i;await(i=0,new Promise(t=>setTimeout(t,i)));const r=await this.getCacheKey(n,"write");if(!e)throw new s("cache-put-with-no-response",{url:(a=r.url,new URL(String(a),location.href).href.replace(new RegExp(`^${location.origin}`),""))});var a;const o=await this.T(e);if(!o)return!1;const{cacheName:c,matchOptions:h}=this.N,u=await self.caches.open(c),l=this.hasCallback("cacheDidUpdate"),f=l?await async function(t,e,s,n){const i=S(e.url,s);if(e.url===i)return t.match(e,n);const r=Object.assign(Object.assign({},n),{ignoreSearch:!0}),a=await t.keys(e,r);for(const e of a)if(i===S(e.url,s))return t.match(e,n)}(u,r.clone(),["__WB_REVISION__"],h):null;try{await u.put(r,l?o.clone():o)}catch(t){if(t instanceof Error)throw"QuotaExceededError"===t.name&&await async function(){for(const t of p)await t()}(),t}for(const t of this.iterateCallbacks("cacheDidUpdate"))await t({cacheName:c,oldResponse:f,newResponse:o.clone(),request:r,event:this.event});return!0}async getCacheKey(t,e){const s=`${t.url} | ${e}`;if(!this.C[s]){let n=t;for(const t of this.iterateCallbacks("cacheKeyWillBeUsed"))n=A(await t({mode:e,request:n,event:this.event,params:this.params}));this.C[s]=n}return this.C[s]}hasCallback(t){for(const e of this.N.plugins)if(t in e)return!0;return!1}async runCallbacks(t,e){for(const s of this.iterateCallbacks(t))await s(e)}*iterateCallbacks(t){for(const e of this.N.plugins)if("function"==typeof e[t]){const s=this.M.get(e),n=n=>{const i=Object.assign(Object.assign({},n),{state:s});return e[t](i)};yield n}}waitUntil(t){return this.B.push(t),t}async doneWaiting(){for(;this.B.length;){const t=this.B.splice(0),e=(await Promise.allSettled(t)).find(t=>"rejected"===t.status);if(e)throw e.reason}}destroy(){this.O.resolve(null)}async T(t){let e=t,s=!1;for(const t of this.iterateCallbacks("cacheWillUpdate"))if(e=await t({request:this.request,response:e,event:this.event})||void 0,s=!0,!e)break;return s||e&&200!==e.status&&(e=void 0),e}}class H{constructor(t={}){this.cacheName=w(t.cacheName),this.plugins=t.plugins||[],this.fetchOptions=t.fetchOptions,this.matchOptions=t.matchOptions}handle(t){const[e]=this.handleAll(t);return e}handleAll(t){t instanceof FetchEvent&&(t={event:t,request:t.request});const e=t.event,s="string"==typeof t.request?new Request(t.request):t.request,n="params"in t?t.params:void 0,i=new F(this,{event:e,request:s,params:n}),r=this.j(i,s,e);return[r,this.W(r,i,s,e)]}async j(t,e,n){let i;await t.runCallbacks("handlerWillStart",{event:n,request:e});try{if(i=await this.P(e,t),!i||"error"===i.type)throw new s("no-response",{url:e.url})}catch(s){if(s instanceof Error)for(const r of t.iterateCallbacks("handlerDidError"))if(i=await r({error:s,event:n,request:e}),i)break;if(!i)throw s}for(const s of t.iterateCallbacks("handlerWillRespond"))i=await s({event:n,request:e,response:i});return i}async W(t,e,s,n){let i,r;try{i=await t}catch(r){}try{await e.runCallbacks("handlerDidRespond",{event:n,request:s,response:i}),await e.doneWaiting()}catch(t){t instanceof Error&&(r=t)}if(await e.runCallbacks("handlerDidComplete",{event:n,request:s,response:i,error:r}),e.destroy(),r)throw r}}function $(t,e){const s=e();return t.waitUntil(s),s}try{self["workbox:precaching:7.3.0"]&&_()}catch(t){}function G(t){if(!t)throw new s("add-to-cache-list-unexpected-type",{entry:t});if("string"==typeof t){const e=new URL(t,location.href);return{cacheKey:e.href,url:e.href}}const{revision:e,url:n}=t;if(!n)throw new s("add-to-cache-list-unexpected-type",{entry:t});if(!e){const t=new URL(n,location.href);return{cacheKey:t.href,url:t.href}}const i=new URL(n,location.href),r=new URL(n,location.href);return i.searchParams.set("__WB_REVISION__",e),{cacheKey:i.href,url:r.href}}class V{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:t,state:e})=>{e&&(e.originalRequest=t)},this.cachedResponseWillBeUsed=async({event:t,state:e,cachedResponse:s})=>{if("install"===t.type&&e&&e.originalRequest&&e.originalRequest instanceof Request){const t=e.originalRequest.url;s?this.notUpdatedURLs.push(t):this.updatedURLs.push(t)}return s}}}class J{constructor({precacheController:t}){this.cacheKeyWillBeUsed=async({request:t,params:e})=>{const s=(null==e?void 0:e.cacheKey)||this.S.getCacheKeyForURL(t.url);return s?new Request(s,{headers:t.headers}):t},this.S=t}}let Q,z;async function X(t,e){let n=null;if(t.url){n=new URL(t.url).origin}if(n!==self.location.origin)throw new s("cross-origin-copy-response",{origin:n});const i=t.clone(),r={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},a=e?e(r):r,o=function(){if(void 0===Q){const t=new Response("");if("body"in t)try{new Response(t.body),Q=!0}catch(t){Q=!1}Q=!1}return Q}()?i.body:await i.blob();return new Response(o,a)}class Y extends H{constructor(t={}){t.cacheName=f(t.cacheName),super(t),this.K=!1!==t.fallbackToNetwork,this.plugins.push(Y.copyRedirectedCacheableResponsesPlugin)}async P(t,e){const s=await e.cacheMatch(t);return s||(e.event&&"install"===e.event.type?await this.A(t,e):await this.F(t,e))}async F(t,e){let n;const i=e.params||{};if(!this.K)throw new s("missing-precache-entry",{cacheName:this.cacheName,url:t.url});{const s=i.integrity,r=t.integrity,a=!r||r===s;n=await e.fetch(new Request(t,{integrity:"no-cors"!==t.mode?r||s:void 0})),s&&a&&"no-cors"!==t.mode&&(this.H(),await e.cachePut(t,n.clone()))}return n}async A(t,e){this.H();const n=await e.fetch(t);if(!await e.cachePut(t,n.clone()))throw new s("bad-precaching-response",{url:t.url,status:n.status});return n}H(){let t=null,e=0;for(const[s,n]of this.plugins.entries())n!==Y.copyRedirectedCacheableResponsesPlugin&&(n===Y.defaultPrecacheCacheabilityPlugin&&(t=s),n.cacheWillUpdate&&e++);0===e?this.plugins.push(Y.defaultPrecacheCacheabilityPlugin):e>1&&null!==t&&this.plugins.splice(t,1)}}Y.defaultPrecacheCacheabilityPlugin={cacheWillUpdate:async({response:t})=>!t||t.status>=400?null:t},Y.copyRedirectedCacheableResponsesPlugin={cacheWillUpdate:async({response:t})=>t.redirected?await X(t):t};class Z{constructor({cacheName:t,plugins:e=[],fallbackToNetwork:s=!0}={}){this.$=new Map,this.G=new Map,this.V=new Map,this.N=new Y({cacheName:f(t),plugins:[...e,new J({precacheController:this})],fallbackToNetwork:s}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this.N}precache(t){this.addToCacheList(t),this.J||(self.addEventListener("install",this.install),self.addEventListener("activate",this.activate),this.J=!0)}addToCacheList(t){const e=[];for(const n of t){"string"==typeof n?e.push(n):n&&void 0===n.revision&&e.push(n.url);const{cacheKey:t,url:i}=G(n),r="string"!=typeof n&&n.revision?"reload":"default";if(this.$.has(i)&&this.$.get(i)!==t)throw new s("add-to-cache-list-conflicting-entries",{firstEntry:this.$.get(i),secondEntry:t});if("string"!=typeof n&&n.integrity){if(this.V.has(t)&&this.V.get(t)!==n.integrity)throw new s("add-to-cache-list-conflicting-integrities",{url:i});this.V.set(t,n.integrity)}if(this.$.set(i,t),this.G.set(i,r),e.length>0){const t=`Workbox is precaching URLs without revision info: ${e.join(", ")}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(t)}}}install(t){return $(t,async()=>{const e=new V;this.strategy.plugins.push(e);for(const[e,s]of this.$){const n=this.V.get(s),i=this.G.get(e),r=new Request(e,{integrity:n,cache:i,credentials:"same-origin"});await Promise.all(this.strategy.handleAll({params:{cacheKey:s},request:r,event:t}))}const{updatedURLs:s,notUpdatedURLs:n}=e;return{updatedURLs:s,notUpdatedURLs:n}})}activate(t){return $(t,async()=>{const t=await self.caches.open(this.strategy.cacheName),e=await t.keys(),s=new Set(this.$.values()),n=[];for(const i of e)s.has(i.url)||(await t.delete(i),n.push(i.url));return{deletedURLs:n}})}getURLsToCacheKeys(){return this.$}getCachedURLs(){return[...this.$.keys()]}getCacheKeyForURL(t){const e=new URL(t,location.href);return this.$.get(e.href)}getIntegrityForCacheKey(t){return this.V.get(t)}async matchPrecache(t){const e=t instanceof Request?t.url:t,s=this.getCacheKeyForURL(e);if(s){return(await self.caches.open(this.strategy.cacheName)).match(s)}}createHandlerBoundToURL(t){const e=this.getCacheKeyForURL(t);if(!e)throw new s("non-precached-url",{url:t});return s=>(s.request=new Request(t),s.params=Object.assign({cacheKey:e},s.params),this.strategy.handle(s))}}const tt=()=>(z||(z=new Z),z);class et extends i{constructor(t,e){super(({request:s})=>{const n=t.getURLsToCacheKeys();for(const i of function*(t,{ignoreURLParametersMatching:e=[/^utm_/,/^fbclid$/],directoryIndex:s="index.html",cleanURLs:n=!0,urlManipulation:i}={}){const r=new URL(t,location.href);r.hash="",yield r.href;const a=function(t,e=[]){for(const s of[...t.searchParams.keys()])e.some(t=>t.test(s))&&t.searchParams.delete(s);return t}(r,e);if(yield a.href,s&&a.pathname.endsWith("/")){const t=new URL(a.href);t.pathname+=s,yield t.href}if(n){const t=new URL(a.href);t.pathname+=".html",yield t.href}if(i){const t=i({url:r});for(const e of t)yield e.href}}(s.url,e)){const e=n.get(i);if(e){return{cacheKey:e,integrity:t.getIntegrityForCacheKey(e)}}}},t.strategy)}}t.CacheableResponsePlugin=class{constructor(t){this.cacheWillUpdate=async({response:t})=>this.X.isResponseCacheable(t)?t:null,this.X=new W(t)}},t.ExpirationPlugin=class{constructor(t={}){this.cachedResponseWillBeUsed=async({event:t,request:e,cacheName:s,cachedResponse:n})=>{if(!n)return null;const i=this.Y(n),r=this.Z(s);d(r.expireEntries());const a=r.updateTimestamp(e.url);if(t)try{t.waitUntil(a)}catch(t){}return i?n:null},this.cacheDidUpdate=async({cacheName:t,request:e})=>{const s=this.Z(t);await s.updateTimestamp(e.url),await s.expireEntries()},this.tt=t,this.D=t.maxAgeSeconds,this.et=new Map,t.purgeOnQuotaError&&function(t){p.add(t)}(()=>this.deleteCacheAndMetadata())}Z(t){if(t===w())throw new s("expire-custom-caches-only");let e=this.et.get(t);return e||(e=new j(t,this.tt),this.et.set(t,e)),e}Y(t){if(!this.D)return!0;const e=this.st(t);if(null===e)return!0;return e>=Date.now()-1e3*this.D}st(t){if(!t.headers.has("date"))return null;const e=t.headers.get("date"),s=new Date(e).getTime();return isNaN(s)?null:s}async deleteCacheAndMetadata(){for(const[t,e]of this.et)await self.caches.delete(t),await e.delete();this.et=new Map}},t.NavigationRoute=class extends i{constructor(t,{allowlist:e=[/./],denylist:s=[]}={}){super(t=>this.nt(t),t),this.it=e,this.rt=s}nt({url:t,request:e}){if(e&&"navigate"!==e.mode)return!1;const s=t.pathname+t.search;for(const t of this.rt)if(t.test(s))return!1;return!!this.it.some(t=>t.test(s))}},t.StaleWhileRevalidate=class extends H{constructor(t={}){super(t),this.plugins.some(t=>"cacheWillUpdate"in t)||this.plugins.unshift(P)}async P(t,e){const n=e.fetchAndCachePut(t).catch(()=>{});e.waitUntil(n);let i,r=await e.cacheMatch(t);if(r);else try{r=await n}catch(t){t instanceof Error&&(i=t)}if(!r)throw new s("no-response",{url:t.url,error:i});return r}},t.cleanupOutdatedCaches=function(){self.addEventListener("activate",t=>{const e=f();t.waitUntil((async(t,e="-precache-")=>{const s=(await self.caches.keys()).filter(s=>s.includes(e)&&s.includes(self.registration.scope)&&s!==t);return await Promise.all(s.map(t=>self.caches.delete(t))),s})(e).then(t=>{}))})},t.createHandlerBoundToURL=function(t){return tt().createHandlerBoundToURL(t)},t.precacheAndRoute=function(t,e){!function(t){tt().precache(t)}(t),function(t){const e=tt();h(new et(e,t))}(e)},t.registerRoute=h});

Sorry, the diff of this file is not supported yet