From fc6619e4e4e6e559634f4740e8ee08630d484ba2 Mon Sep 17 00:00:00 2001 From: Nicholas Truglia <89828514+nickstruglia@users.noreply.github.com> Date: Thu, 8 Oct 2026 23:21:56 +0000 Subject: [PATCH 1/2] feat: add Keyfold, a key manager editor Keyfold keeps crypto seed phrases and wallet keys, SSH and PGP keys, API tokens and recovery codes in one note, as collapsible cards with hidden fields, checksum checks and an optional vault password. The package carries Keyfold's own build for this address, with SHA-256 checksums that `yarn build` verifies before copying the files to dist/: Keyfold builds with Vite 8, which needs Node 20.19+, and this repository builds on Node 16. The package README says how to rebuild the files and compare them. Source: https://github.com/nickstruglia/standard-notes-keyfold --- cdn/plugins.json | 4 + .../io.github.nickstruglia.keyfold/LICENSE | 21 ++ .../io.github.nickstruglia.keyfold/README.md | 35 +++ .../io.github.nickstruglia.keyfold/SHA256SUMS | 4 + .../io.github.nickstruglia.keyfold/build.mjs | 37 +++ .../package.json | 28 ++ .../prebuilt/assets/index-BhYPNPAd.js | 265 ++++++++++++++++ .../prebuilt/icon.svg | 1 + .../prebuilt/index.html | 16 + .../prebuilt/keyfold-viewer.html | 282 ++++++++++++++++++ yarn.lock | 6 + 11 files changed, 699 insertions(+) create mode 100644 packages/io.github.nickstruglia.keyfold/LICENSE create mode 100644 packages/io.github.nickstruglia.keyfold/README.md create mode 100644 packages/io.github.nickstruglia.keyfold/SHA256SUMS create mode 100644 packages/io.github.nickstruglia.keyfold/build.mjs create mode 100644 packages/io.github.nickstruglia.keyfold/package.json create mode 100644 packages/io.github.nickstruglia.keyfold/prebuilt/assets/index-BhYPNPAd.js create mode 100644 packages/io.github.nickstruglia.keyfold/prebuilt/icon.svg create mode 100644 packages/io.github.nickstruglia.keyfold/prebuilt/index.html create mode 100644 packages/io.github.nickstruglia.keyfold/prebuilt/keyfold-viewer.html diff --git a/cdn/plugins.json b/cdn/plugins.json index 5f280c2..91bfd7f 100644 --- a/cdn/plugins.json +++ b/cdn/plugins.json @@ -59,6 +59,10 @@ "identifier": "dev.randombits.excalidraw", "staticFiles": ["dist", "package.json"] }, + { + "identifier": "io.github.nickstruglia.keyfold", + "staticFiles": ["dist", "package.json"] + }, { "identifier": "com.sncommunity.standard-blue-theme", "staticFiles": ["dist", "package.json"] diff --git a/packages/io.github.nickstruglia.keyfold/LICENSE b/packages/io.github.nickstruglia.keyfold/LICENSE new file mode 100644 index 0000000..436026c --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Nicholas Truglia + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/io.github.nickstruglia.keyfold/README.md b/packages/io.github.nickstruglia.keyfold/README.md new file mode 100644 index 0000000..b3e0a32 --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/README.md @@ -0,0 +1,35 @@ +# Keyfold + +A key manager for Standard Notes: crypto seed phrases and wallet keys, plus SSH and PGP keys, API tokens and recovery +codes. Each entry folds into a one-line card, secrets stay hidden until revealed, seed phrases and keys are checked for +typos (BIP39 and Electrum checksums, Base58Check, Bech32, PGP armor), and an optional vault password encrypts the +whole note again (AES-256-GCM, PBKDF2-SHA256 with 600,000 iterations). Encrypted backup files open in a single-file +offline viewer, without Standard Notes. + +Its Content Security Policy blocks every outgoing connection (`connect-src 'none'`), and scripts, images and fonts +from other sites. The only runtime dependency is Preact. + +- Source, tests and documentation: https://github.com/nickstruglia/standard-notes-keyfold (MIT) +- This copy: version 1.0.23, built from commit [`9f45f89`](https://github.com/nickstruglia/standard-notes-keyfold/commit/9f45f89f194865a94d26670187a58817eb2f2854) + +## Why the files are prebuilt + +This repository builds its packages on Node 16, and Keyfold's build (Vite 8) needs Node 20.19 or newer. So +`prebuilt/` holds the output of Keyfold's own build for this package's address, and `yarn build` checks every file +against `SHA256SUMS` before copying it to `dist/`. + +## Rebuilding and comparing + +With Node 22.12 or newer: + +```sh +git clone https://github.com/nickstruglia/standard-notes-keyfold.git +cd standard-notes-keyfold +git checkout 9f45f89f194865a94d26670187a58817eb2f2854 +npm ci --ignore-scripts +node scripts/directory-package.mjs 1.0.23 +diff -r directory-package/io.github.nickstruglia.keyfold/prebuilt /prebuilt +diff directory-package/io.github.nickstruglia.keyfold/SHA256SUMS /SHA256SUMS +``` + +The script builds Keyfold for `https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/` and writes this folder, with the same files byte for byte. diff --git a/packages/io.github.nickstruglia.keyfold/SHA256SUMS b/packages/io.github.nickstruglia.keyfold/SHA256SUMS new file mode 100644 index 0000000..8f01156 --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/SHA256SUMS @@ -0,0 +1,4 @@ +db954df76375f52c561eae1cc8f7db8d4e373fd7dfd51c6e07d26ecc866c352c assets/index-BhYPNPAd.js +0e0ccb766d5e6a479278c3c98865189e0f0bde69ae739d75a1d26470613de64c icon.svg +cfa422d04a596927bdae7f380128398e36accc9392da7a07e3ce66c161a10473 index.html +a13eaf8f351acab9939769e7be2d6f17189d5f489924575861a7becb7e91a587 keyfold-viewer.html diff --git a/packages/io.github.nickstruglia.keyfold/build.mjs b/packages/io.github.nickstruglia.keyfold/build.mjs new file mode 100644 index 0000000..1faebd2 --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/build.mjs @@ -0,0 +1,37 @@ +// Copies the prebuilt files to dist/ after checking each one against SHA256SUMS. +// They are Keyfold's own build for this address; README.md says how to rebuild them. +import { createHash } from 'crypto' +import { copyFileSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync } from 'fs' +import { dirname, join, relative } from 'path' +import { fileURLToPath } from 'url' + +const here = dirname(fileURLToPath(import.meta.url)) +const prebuilt = join(here, 'prebuilt') +const dist = join(here, 'dist') + +const walk = (dir) => + readdirSync(dir).flatMap((name) => { + const path = join(dir, name) + return statSync(path).isDirectory() ? walk(path) : [relative(prebuilt, path).split('\\').join('/')] + }) + +const sums = new Map( + readFileSync(join(here, 'SHA256SUMS'), 'utf8') + .trim() + .split('\n') + .map((line) => { + const [hash, file] = line.split(' ') + return [file, hash] + }), +) +const files = walk(prebuilt).sort() +if (files.join('\n') !== [...sums.keys()].sort().join('\n')) throw new Error('prebuilt/ does not match SHA256SUMS') + +rmSync(dist, { recursive: true, force: true }) +for (const file of files) { + const hash = createHash('sha256').update(readFileSync(join(prebuilt, file))).digest('hex') + if (hash !== sums.get(file)) throw new Error(`${file} does not match SHA256SUMS`) + mkdirSync(dirname(join(dist, file)), { recursive: true }) + copyFileSync(join(prebuilt, file), join(dist, file)) +} +console.log(`Keyfold: ${files.length} files checked and copied to dist/`) diff --git a/packages/io.github.nickstruglia.keyfold/package.json b/packages/io.github.nickstruglia.keyfold/package.json new file mode 100644 index 0000000..e5b5c7d --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/package.json @@ -0,0 +1,28 @@ +{ + "name": "sn-keyfold", + "version": "1.0.23", + "private": true, + "description": "A key manager for Standard Notes: seed phrases, wallet, SSH and PGP keys, API tokens and recovery codes, in collapsible cards with hidden fields and checksum checks.", + "author": "Nicholas Truglia", + "license": "MIT", + "homepage": "https://github.com/nickstruglia/standard-notes-keyfold", + "repository": { + "type": "git", + "url": "https://github.com/standardnotes/plugins", + "directory": "packages/io.github.nickstruglia.keyfold" + }, + "scripts": { + "build": "node build.mjs" + }, + "sn": { + "name": "Keyfold", + "content_type": "SN|Component", + "area": "editor-editor", + "main": "dist/index.html", + "file_type": "json", + "interchangeable": false, + "marketing_url": "https://github.com/nickstruglia/standard-notes-keyfold", + "thumbnail_url": "https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/icon.svg", + "showInGallery": true + } +} diff --git a/packages/io.github.nickstruglia.keyfold/prebuilt/assets/index-BhYPNPAd.js b/packages/io.github.nickstruglia.keyfold/prebuilt/assets/index-BhYPNPAd.js new file mode 100644 index 0000000..ef67927 --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/prebuilt/assets/index-BhYPNPAd.js @@ -0,0 +1,265 @@ +(function(){var e=document.createElement(`style`);e.textContent=`:root{--bg:var(--sn-stylekit-background-color,#fff);--fg:var(--sn-stylekit-foreground-color,#1d1d20);--muted:var(--sn-stylekit-passive-color-0,var(--sn-stylekit-neutral-color,#6c7079));--border:var(--sn-stylekit-border-color,#e0e2e6);--panel:var(--sn-stylekit-secondary-background-color,#f6f7f9);--contrast:var(--sn-stylekit-contrast-background-color,#eef0f3);--info:var(--sn-stylekit-info-color,#086dd6);--info-fg:var(--sn-stylekit-info-contrast-color,#fff);--success:var(--sn-stylekit-success-color,#1e8a34);--warning:var(--sn-stylekit-warning-color,#a96500);--danger:var(--sn-stylekit-danger-color,#cc1f36);--danger-fg:var(--sn-stylekit-danger-contrast-color,#fff);--placeholder:var(--sn-stylekit-input-placeholder-color,var(--muted));--success-text:color-mix(in srgb, var(--success) 70%, var(--fg));--warning-text:color-mix(in srgb, var(--warning) 55%, var(--fg));--danger-text:color-mix(in srgb, var(--danger) 75%, var(--fg));--keys:color-mix(in srgb, var(--info) 60%, var(--danger));--font:var(--sn-stylekit-sans-serif-font,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);--mono:var(--sn-stylekit-monospace-font,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);--radius:6px;--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark}@media (prefers-color-scheme:dark){:root{--lightningcss-light: ;--lightningcss-dark:initial}html.standalone{--bg:#17181b;--fg:#e7e8ea;--muted:#9a9ea6;--border:#2e3036;--panel:#1d1f23;--contrast:#262930;--info:#4c9df0;--success:#4fbf63;--warning:#e3a33a;--danger:#f0566a;--placeholder:#6d7179}}html.theme-pending{opacity:0}*{box-sizing:border-box}html,body{background:var(--bg);height:100%;color:var(--fg);font:14px/1.45 var(--font);margin:0}#app,.app{flex-direction:column;height:100%;min-height:0;display:flex}h2,h3{margin:0;font-weight:600}h2{font-size:1.15rem}h3{align-items:center;gap:6px;font-size:.95rem;display:flex}a{color:var(--info)}code{font-family:var(--mono);word-break:break-all;font-size:.9em}.muted{color:var(--muted)}.small{font-size:.85rem}.input{width:100%;min-width:0;font:inherit;color:var(--fg);background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);outline:none;padding:7px 9px}.input::placeholder{color:var(--placeholder)}.input:focus-visible,.button:focus-visible,.icon-button:focus-visible,.entry-item:focus-visible{outline:2px solid var(--info);outline-offset:1px}.input[readonly]{background:var(--panel)}textarea.input{resize:vertical;min-height:2.6em}select.input{width:auto;padding-right:4px}.mono{font-family:var(--mono)}.masked-placeholder{text-align:left;cursor:pointer;color:var(--muted);letter-spacing:2px}.button{font:inherit;color:var(--fg);background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);cursor:pointer;white-space:nowrap;align-items:center;gap:6px;padding:7px 12px;font-weight:500;display:inline-flex}.button.small{padding:4px 9px;font-size:.85rem}.button.primary{background:var(--info);border-color:var(--info);color:var(--info-fg)}.button.danger{color:var(--danger);border-color:var(--danger)}.button:disabled,.icon-button:disabled{opacity:.5;cursor:not-allowed}.icon-button{width:30px;height:30px;color:var(--muted);border-radius:var(--radius);cursor:pointer;background:0 0;border:1px solid #0000;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.icon-button.active{color:var(--warning)}.check{cursor:pointer;align-items:flex-start;gap:8px;margin:6px 0;display:flex}.check input{margin-top:3px}.row{flex-wrap:wrap;align-items:flex-end;gap:10px;display:flex}.row>.field{flex:180px}.row.tight{gap:6px}.row.end{justify-content:flex-end}.grow{flex:200px}.field{flex-direction:column;gap:4px;min-width:0;margin-bottom:10px;display:flex}.field-control{display:contents}.field-label{color:var(--muted);font-size:.8rem;font-weight:600}.hint{color:var(--muted);margin:0;font-size:.8rem}.status{align-items:baseline;gap:6px;margin:6px 0 10px;font-size:.85rem;display:flex}.status svg{flex:none;align-self:flex-start;margin-top:.2em}.status-ok{color:var(--success-text)}.status-error{color:var(--danger-text)}.status-warn{color:var(--warning-text)}.status-info{color:var(--muted)}.pill{white-space:nowrap;background:var(--contrast);color:var(--muted);border-radius:999px;align-items:center;gap:3px;padding:0 7px;font-size:.72rem;line-height:1.6;display:inline-flex}.pill-ok{color:var(--success-text);background:color-mix(in srgb, var(--success) 13%, transparent)}.pill-error{color:var(--danger-text);background:color-mix(in srgb, var(--danger) 13%, transparent)}.pill-warn{color:color-mix(in srgb, var(--warning) 45%, var(--fg));background:color-mix(in srgb, var(--warning) 15%, transparent)}.badge{border-radius:999px;flex:none;padding:2px 8px;font-size:.75rem;font-weight:600}.badge-mnemonic{color:var(--info);background:color-mix(in srgb, var(--info) 12%, transparent)}.badge-privateKey{color:var(--success);background:color-mix(in srgb, var(--success) 12%, transparent)}.badge-other,.badge-recoveryCodes{color:var(--muted);background:var(--contrast)}.badge-sshKey,.badge-pgpKey,.badge-apiKey,.badge-genericKey{color:var(--keys);background:color-mix(in srgb, var(--keys) 12%, transparent)}.banner{background:var(--contrast);border-bottom:1px solid var(--border);padding:8px 14px;font-size:.85rem}.banner svg{vertical-align:-3px;margin-right:4px}.banner-warn{color:var(--fg);background:color-mix(in srgb, var(--warning) 16%, var(--bg))}.layout{flex:1;grid-template-columns:minmax(260px,340px) minmax(0,1fr);min-height:0;display:grid}.sidebar{border-right:1px solid var(--border);background:var(--panel);flex-direction:column;min-height:0;display:flex}.toolbar{background:var(--panel);border-bottom:1px solid var(--border);flex-direction:column;gap:8px;padding:10px 12px;display:flex}.toolbar-row{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.spacer{flex:1}.search{color:var(--muted);flex:200px;position:relative}.search svg{position:absolute;top:50%;left:9px;transform:translateY(-50%)}.search .input{padding-left:30px}.popover-wrap{position:relative}.popover{z-index:15;background:var(--bg);border:1px solid var(--border);border-radius:8px;min-width:190px;max-height:70vh;padding:6px;position:absolute;top:calc(100% + 4px);right:0;overflow-y:auto;box-shadow:0 8px 24px #00000029}.popover-dialog{width:270px;padding:12px}.menu-heading{letter-spacing:.04em;text-transform:uppercase;color:var(--muted);padding:6px 10px 2px;font-size:.72rem;font-weight:600}.menu-group+.menu-group{border-top:1px solid var(--border);margin-top:4px;padding-top:4px}.menu-item{width:100%;font:inherit;text-align:left;color:var(--fg);border-radius:var(--radius);cursor:pointer;background:0 0;border:0;align-items:center;gap:8px;padding:7px 10px;display:flex}.menu-item:focus-visible{background:var(--contrast)}.view-options fieldset{border:0;margin:0 0 10px;padding:0}.view-options legend{color:var(--muted);margin-bottom:2px;padding:0;font-size:.8rem;font-weight:600}.view-options .check{margin:3px 0}.view-options select.input{width:100%}.group-heading{text-transform:uppercase;letter-spacing:.04em;margin:10px 0 4px;font-size:.78rem}.group:first-child .group-heading{margin-top:0}.group-toggle{width:100%;font:inherit;color:var(--muted);border-radius:var(--radius);cursor:pointer;text-transform:inherit;letter-spacing:inherit;background:0 0;border:0;align-items:center;gap:6px;padding:4px;font-weight:600;display:flex}.count{background:var(--contrast);border-radius:999px;padding:0 6px;font-size:.72rem}.toolbar .count{background:0 0;padding:0;font-size:.8rem}.chevron{flex:none;transition:transform .15s}[aria-expanded=true]>.chevron{transform:rotate(90deg)}.entry-list{flex:1;padding:8px 6px;overflow-y:auto}.entry-rows{margin:0;padding:0;list-style:none}.entry-item{width:100%;font:inherit;text-align:left;color:var(--fg);border-radius:var(--radius);cursor:pointer;background:0 0;border:1px solid #0000;align-items:flex-start;gap:10px;padding:9px 10px;display:flex}.entry-item.selected{background:color-mix(in srgb, var(--info) 10%, var(--bg));border-color:var(--border);box-shadow:inset 3px 0 0 var(--info)}.entry-icon{border-radius:var(--radius);padding:6px;display:inline-flex}.entry-main{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.entry-title{text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.entry-title .star{color:var(--warning);vertical-align:-1px;margin-right:4px}.entry-meta{color:var(--muted);text-overflow:ellipsis;white-space:nowrap;font-size:.8rem;overflow:hidden}.entry-pills{flex-wrap:wrap;gap:4px;display:flex}.entry-pills:empty{display:none}.entry-date{color:var(--muted);flex:none;font-size:.75rem}.empty{text-align:center;color:var(--muted);padding:24px 16px}.empty p{margin:6px 0}.detail{min-width:0;min-height:0;overflow-y:auto}.detail.full{flex:1}.stack{max-width:980px;margin:0 auto;padding:12px 12px 48px}.cards{flex-direction:column;gap:6px;margin:0;padding:0;list-style:none;display:flex}.card-entry{background:var(--bg);border:1px solid var(--border);border-radius:8px}.card-entry.open{box-shadow:0 2px 10px #00000012}.card-header{border-radius:8px;align-items:center;gap:4px;padding-right:6px;display:flex}.card-entry.open .card-header{z-index:3;background:var(--bg);border-bottom:1px solid var(--border);border-radius:8px 8px 0 0;position:sticky;top:0}.card-toggle{min-width:0;font:inherit;text-align:left;color:var(--fg);cursor:pointer;background:0 0;border:0;border-radius:8px;flex:auto;align-items:flex-start;gap:10px;padding:10px 12px;display:flex}.card-toggle>.chevron{color:var(--muted);margin-top:7px}.card-toggle:focus-visible,.group-toggle:focus-visible,.section-toggle:focus-visible{outline:2px solid var(--info);outline-offset:-2px}.card-body{padding:0 16px 12px 46px}.entry-actions{flex:none;display:flex}.empty .row.center{justify-content:center;margin-top:12px}.placeholder{flex-direction:column;justify-content:center;align-items:center;gap:8px;height:100%;display:flex}.editor-header{z-index:2;background:var(--bg);border-bottom:1px solid var(--border);align-items:center;gap:6px;padding:10px 16px;display:flex;position:sticky;top:0}.title-input{border-color:#0000;flex:1;font-size:1.1rem;font-weight:600}.title-input:focus{border-color:var(--border)}.editor-body{max-width:880px;padding:8px 16px 32px}.editor-footer{margin-top:16px}.back-button{display:none}.section{border-bottom:1px solid var(--border);padding:10px 0 6px}.section:last-of-type{border-bottom:none}.section.closed{padding-bottom:10px}.section-header{justify-content:space-between;align-items:center;gap:8px;margin-bottom:10px;display:flex}.section.closed .section-header{margin-bottom:0}.section-heading{flex:1;min-width:0}.section-toggle{width:100%;font:inherit;text-align:left;color:var(--fg);border-radius:var(--radius);cursor:pointer;background:0 0;border:0;align-items:center;gap:6px;padding:2px 4px;font-weight:600;display:flex}.section-toggle>.chevron{color:var(--muted)}.section-summary{min-width:0;color:var(--muted);text-overflow:ellipsis;white-space:nowrap;margin-left:4px;font-size:.82rem;font-weight:400;overflow:hidden}.section>h3{margin-bottom:10px}.section p{margin:0 0 10px}.secret{align-items:center;gap:2px;display:flex}.secret-multiline{align-items:flex-start}.secret-actions{flex:none;display:flex}.secret-multiline .secret-actions{flex-direction:column}.word-toolbar{flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:8px;display:flex}.word-grid{grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:6px;margin:0 0 6px;padding:0;list-style:none;display:grid}.word{position:relative}.word-index{min-width:18px;color:var(--muted);text-align:right;pointer-events:none;font-size:.75rem;position:absolute;top:50%;left:8px;transform:translateY(-50%)}.word .input{padding-left:30px;padding-right:6px}.word .input::-webkit-calendar-picker-indicator{display:none!important}.word .input::-webkit-list-button{display:none!important}.word-invalid .input{border-color:var(--danger);background:color-mix(in srgb, var(--danger) 6%, var(--bg))}.custom-field{grid-template-columns:minmax(110px,.6fr) minmax(0,1.4fr) auto;align-items:center;gap:8px;margin-bottom:8px;display:grid}.custom-actions{align-items:center;gap:4px;display:flex}.custom-actions .check{margin:0}.backup-row{align-items:center;margin-bottom:8px}.backup-row input[type=date]{width:auto}.screen{flex:1;justify-content:center;align-items:center;padding:24px 16px;display:flex;overflow:auto}.card{text-align:center;background:var(--bg);border:1px solid var(--border);border-radius:10px;flex-direction:column;align-items:center;gap:10px;width:100%;max-width:420px;padding:24px;display:flex}.card p{margin:0}.lock-card .input,.lock-card .button{justify-content:center;width:100%}.open-note{width:100%;max-width:640px}.open-note textarea{width:100%}.screen.dragging .open-note{border-color:var(--info);box-shadow:0 0 0 3px color-mix(in srgb, var(--info) 30%, transparent)}.paste-note{width:100%}.paste-note>summary{color:var(--info);cursor:pointer;font-size:.85rem}.paste-note>*+*{margin-top:10px}a.button{text-decoration:none}.backup-ready>.row{margin-bottom:10px}.password-form{max-width:460px}.overlay{z-index:40;background:#00000059;justify-content:center;align-items:center;padding:16px;display:flex;position:fixed;inset:0}.dialog{text-align:left;align-items:stretch;box-shadow:0 10px 30px #0003}.toasts{z-index:30;pointer-events:none;flex-direction:column;align-items:flex-end;gap:8px;display:flex;position:fixed;bottom:16px;left:16px;right:16px}.toast{background:var(--bg);border:1px solid var(--border);border-left:4px solid var(--info);border-radius:var(--radius);pointer-events:auto;align-items:center;gap:8px;max-width:420px;padding:8px 8px 8px 12px;font-size:.85rem;display:flex;box-shadow:0 4px 16px #00000026}.toast-success{border-left-color:var(--success)}.toast-error{border-left-color:var(--danger)}.app.privacy .layout,.app.privacy .toolbar,.app.privacy .detail{filter:blur(10px);pointer-events:none;-webkit-user-select:none;user-select:none}.app.privacy~.overlay,.app.privacy~.toasts{filter:blur(10px)}.privacy-cover{z-index:10;width:100%;font:inherit;cursor:pointer;color:var(--muted);background:0 0;border:0;flex-direction:column;justify-content:center;align-items:center;gap:8px;display:flex;position:fixed;inset:0}.app.compact{font-size:13px}.app.compact .input{padding:4px 7px}.app.compact .button{padding:4px 9px}.app.compact .toolbar{gap:6px;padding:6px 10px}.app.compact .stack{padding-top:8px}.app.compact .cards{gap:4px}.app.compact .card-toggle,.app.compact .entry-item{align-items:center;padding:5px 10px}.app.compact .card-toggle>.chevron{margin-top:0}.app.compact .entry-icon{padding:3px}.app.compact .entry-main{flex-direction:row;align-items:center;gap:8px}.app.compact .entry-title{text-overflow:ellipsis;white-space:nowrap;flex:none;min-width:0;max-width:60%;overflow:hidden}.app.compact .entry-meta{flex:0 10 auto;min-width:0}.app.compact .entry-pills{flex-wrap:nowrap;flex:0 auto;min-width:0;overflow:hidden}.app.compact .sidebar .entry-date,.app.compact .entry-pills .pill:not(.pill-error):not(.pill-warn){display:none}.app.compact .card-body{padding:0 12px 8px 36px}.app.compact .section{padding:6px 0 4px}.app.compact .section.closed{padding-bottom:6px}.app.compact .section-header{margin-bottom:6px}.app.compact .section.closed .section-header{margin-bottom:0}.app.compact .field{margin-bottom:6px}.app.compact .helper,.app.compact .field>.hint:not([class*=status-]):not(.hint-safety){display:none}.app.compact .word-grid{grid-template-columns:repeat(auto-fill,minmax(112px,1fr));gap:4px}.app.compact .word .input{padding-left:28px}.app.compact .search .input{padding-left:30px}.app.compact .editor-footer{margin-top:8px}@media (pointer:coarse){.input,.app.compact .input{font-size:16px}.icon-button{width:40px;height:40px}.entry-actions{gap:6px}}@media (max-width:560px){.toolbar .button-text,.app.compact .entry-meta{display:none}.toolbar .button{padding:5px 8px}}@media (max-width:760px){.card-header{flex-wrap:wrap}.card-entry.open .entry-actions{margin-left:auto}.card-body,.app.compact .card-body{padding:0 10px 10px}.entry-date{display:none}.layout{grid-template-columns:minmax(0,1fr)}.layout.has-detail .sidebar,.layout:not(.has-detail) .detail{display:none}.sidebar{border-right:none}.back-button{display:inline-flex}.editor-header{flex-wrap:wrap;padding:8px 10px}.editor-header .badge{margin-right:auto}.title-input{flex-basis:100%;order:10}.editor-body{padding:4px 12px 24px}.custom-field{grid-template-columns:minmax(0,1fr)}.word-grid{grid-template-columns:repeat(auto-fill,minmax(120px,1fr))}}@media (max-width:560px){.toolbar-row{position:relative}.popover-wrap{position:static}.popover{min-width:0;left:0;right:0}.popover-dialog{width:auto}}@media (max-width:760px),(max-height:560px){.card-entry.open .card-header{position:static}}@media (pointer:coarse){.button,.toolbar .button{min-height:40px}.toolbar .button{min-width:36px}.group-toggle,.section-toggle{min-height:40px}.menu-item{min-height:44px}.check{align-items:center;min-height:40px}.check input{width:20px;height:20px}}@media (hover:hover){.button:hover:not(:disabled){background:var(--contrast)}.button.primary:hover:not(:disabled){background:var(--info);filter:brightness(1.08)}.button.danger:hover:not(:disabled){background:var(--danger);color:var(--danger-fg)}.icon-button:hover:not(:disabled){color:var(--fg);background:var(--contrast)}.icon-button.danger:hover:not(:disabled){color:var(--danger)}.group-toggle:hover{color:var(--fg)}.entry-item:hover{background:var(--contrast)}.card-toggle:hover{background:var(--panel)}.menu-item:hover{background:var(--contrast)}.title-input:hover{border-color:var(--border)}}.input::-webkit-date-and-time-value{text-align:start}@media (forced-colors:active){.pill,.status-error,.entry-item.selected,.word-invalid .input{border:1px solid canvastext}.entry-item.selected{border-color:highlight}.word-invalid .input{border-width:2px}}@supports not (color:color-mix(in srgb, red, red)){:root{--keys:var(--info);--success-text:var(--success);--warning-text:var(--fg);--danger-text:var(--danger)}.pill-ok,.pill-error,.pill-warn,.badge,[class*=badge-],.entry-item.selected,.word-invalid .input{background:var(--contrast)}.pill-warn{color:var(--fg)}}@media print{.app{display:none}}.link-button{font:inherit;color:var(--info);cursor:pointer;background:0 0;border:0;margin:0 .25em;padding:0;text-decoration:underline} +/*$vite$:1*/`,document.head.appendChild(e);var t,n,r,i,a,o,s,c,l,u,d,f,p,m,h,g={},_=[],v=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,y=Array.isArray;function b(e,t){for(var n in t)e[n]=t[n];return e}function ee(e){e&&e.parentNode&&e.parentNode.removeChild(e)}function x(e,n,r){var i,a,o,s={};for(o in n)o==`key`?i=n[o]:o==`ref`?a=n[o]:s[o]=n[o];if(arguments.length>2&&(s.children=arguments.length>3?t.call(arguments,2):r),typeof e==`function`&&e.defaultProps!=null)for(o in e.defaultProps)s[o]===void 0&&(s[o]=e.defaultProps[o]);return S(e,s,i,a,null)}function S(e,t,i,a,o){var s={type:e,props:t,key:i,ref:a,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:o??++r,__i:-1,__u:0};return o==null&&n.vnode!=null&&n.vnode(s),s}function C(e){return e.children}function te(e,t){this.props=e,this.context=t}function w(e,t){if(t==null)return e.__?w(e.__,e.__i+1):null;for(var n;tt&&i.sort(s),e=i.shift(),t=i.length,T(e)}finally{i.length=D.__r=0}}function re(e,t,n,r,i,a,o,s,c,l,u){var d,f,p,m,h,v,y=r&&r.__k||_,b=t.length;for(c=ie(n,t,y,c,b),d=0;d0?o=e.__k[a]=S(o.type,o.props,o.key,o.ref?o.ref:null,o.__v):e.__k[a]=o,c=a+f,o.__=e,o.__b=e.__b+1,s=null,(l=o.__i=oe(o,n,c,d))!=-1&&(d--,(s=n[l])&&(s.__u|=2)),s==null||s.__v==null?(l==-1&&(i>u?f--:ic?f--:f++,o.__u|=4))):e.__k[a]=null;if(d)for(a=0;a+!!u){for(i=n-1,a=n+1;i>=0||a=0?i--:a++])!=null&&!(2&l.__u)&&s==l.key&&c==l.type)return o}return-1}function O(e,t,n){t[0]==`-`?e.setProperty(t,n??``):e[t]=n==null?``:typeof n!=`number`||v.test(t)?n:n+`px`}function k(e,t,n,r,i){var a,o;n:if(t==`style`){if(typeof n==`string`)e.style.cssText=n;else{if(typeof r==`string`&&(e.style.cssText=r=``),r)for(t in r)n&&t in n||O(e.style,t,``);if(n)for(t in n)r&&n[t]==r[t]||O(e.style,t,n[t])}}else if(t[0]==`o`&&t[1]==`n`)a=t!=(t=t.replace(d,`$1`)),o=t.toLowerCase(),t=o in e||t==`onFocusOut`||t==`onFocusIn`?o.slice(2):t.slice(2),e.l||={},e.l[t+a]=n,n?r?n[u]=r[u]:(n[u]=f,e.addEventListener(t,a?m:p,a)):e.removeEventListener(t,a?m:p,a);else{if(i==`http://www.w3.org/2000/svg`)t=t.replace(/xlink(H|:h)/,`h`).replace(/sName$/,`s`);else if(t!=`width`&&t!=`height`&&t!=`href`&&t!=`list`&&t!=`form`&&t!=`tabIndex`&&t!=`download`&&t!=`rowSpan`&&t!=`colSpan`&&t!=`role`&&t!=`popover`&&t in e)try{e[t]=n??``;break n}catch{}typeof n==`function`||(n==null||!1===n&&t[4]!=`-`?e.removeAttribute(t):e.setAttribute(t,t==`popover`&&n==1?``:n))}}function A(e){return function(t){if(this.l){var r=this.l[t.type+e];if(t[l]==null)t[l]=f++;else if(t[l]0?e:y(e)?e.map(le):e.constructor===void 0?b({},e):null}function M(e,r,i,a,o,s,c,l,u){var d,f,p,m,h,_,v,b=i.props||g,x=r.props,S=r.type;if(S==`svg`?o=`http://www.w3.org/2000/svg`:S==`math`?o=`http://www.w3.org/1998/Math/MathML`:o||=`http://www.w3.org/1999/xhtml`,s!=null){for(d=0;d=n.__.length&&n.__.push({}),n.__[e]}function R(e){return ge=1,we(Pe,e)}function we(e,t,n){var r=Ce(pe++,2);if(r.t=e,!r.__c&&(r.__=[n?n(t):Pe(void 0,t),function(e){var t=r.__N?r.__N[0]:r.__[0],n=r.t(t,e);t!==n&&(r.__N=[n,r.__[1]],r.__c.setState({}))}],r.__c=F,!F.__f)){var i=function(e,t,n){if(!r.__c.__H)return!0;var i=!1,o=r.__c.props!==e;if(r.__c.__H.__.some(function(e){if(e.__N){i=!0;var t=e.__[0];e.__=e.__N,e.__N=void 0,t!==e.__[0]&&(o=!0)}}),a){var s=a.call(this,e,t,n);return i?s||o:s}return!i||o};F.__f=!0;var a=F.shouldComponentUpdate,o=F.componentWillUpdate;F.componentWillUpdate=function(e,t,n){if(this.__e){var r=a;a=void 0,i(e,t,n),a=r}o&&o.call(this,e,t,n)},F.shouldComponentUpdate=i}return r.__N||r.__}function z(e,t){var n=Ce(pe++,3);!I.__s&&Ne(n.__H,t)&&(n.__=e,n.u=t,F.__H.__h.push(n))}function B(e){return ge=5,Te(function(){return{current:e}},[])}function Te(e,t){var n=Ce(pe++,7);return Ne(n.__H,t)&&(n.__=e(),n.__H=t,n.__h=e),n.__}function Ee(e,t){return ge=8,Te(function(){return e},t)}function De(e){var t=F.context[e.__c],n=Ce(pe++,9);return n.c=e,t?(n.__??(n.__=!0,t.sub(F)),t.props.value):e.__}function Oe(){var e=Ce(pe++,11);if(!e.__){for(var t=F.__v;t!==null&&!t.__m&&t.__!==null;)t=t.__;var n=t.__m||(t.__m=[0,0]);e.__=`P`+n[0]+`-`+n[1]++}return e.__}function ke(){for(var e;e=_e.shift();){var t=e.__H;if(e.__P&&t)try{t.__h.some(Me),t.__h.some(V),t.__h=[]}catch(n){t.__h=[],I.__e(n,e.__v)}}}I.__b=function(e){F=null,L&&L(e)},I.__=function(e,t){e&&t.__k&&t.__k.__m&&(e.__m=t.__k.__m),Se&&Se(e,t)},I.__r=function(e){ve&&ve(e),pe=0;var t=(F=e.__c).__H;t&&(me===F?(t.__h=[],F.__h=[],t.__.some(function(e){e.__N&&(e.__=e.__N),e.u=e.__N=void 0})):(t.__h.some(Me),t.__h.some(V),t.__h=[],pe=0)),me=F},I.diffed=function(e){ye&&ye(e);var t=e.__c;t&&t.__H&&(t.__H.__h.length&&(_e.push(t)!==1&&he===I.requestAnimationFrame||((he=I.requestAnimationFrame)||je)(ke)),t.__H.__.some(function(e){e.u&&=(e.__H=e.u,void 0)})),me=F=null},I.__c=function(e,t){t.some(function(e){try{e.__h.some(Me),e.__h=e.__h.filter(function(e){return!e.__||V(e)})}catch(n){t.some(function(e){e.__h&&=[]}),t=[],I.__e(n,e.__v)}}),be&&be(e,t)},I.unmount=function(e){xe&&xe(e);var t,n=e.__c;n&&n.__H&&(n.__H.__.some(function(e){try{Me(e)}catch(e){t=e}}),n.__H=void 0,t&&I.__e(t,n.__v))};var Ae=typeof requestAnimationFrame==`function`;function je(e){var t,n=function(){clearTimeout(r),Ae&&cancelAnimationFrame(t),setTimeout(e)},r=setTimeout(n,35);Ae&&(t=requestAnimationFrame(n))}function Me(e){var t=F,n=e.__c;typeof n==`function`&&(e.__c=void 0,n()),F=t}function V(e){var t=F;e.__c=e.__(),F=t}function Ne(e,t){return!e||e.length!==t.length||t.some(function(t,n){return t!==e[n]})}function Pe(e,t){return typeof t==`function`?t(e):t}var Fe=0;Array.isArray;function H(e,t,r,i,a,o){t||={};var s,c,l=t;if(`ref`in l)for(c in l={},t)c==`ref`?s=t[c]:l[c]=t[c];var u={type:e,props:l,key:r,ref:s,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--Fe,__i:-1,__u:0,__source:a,__self:o};if(typeof e==`function`&&(s=e.defaultProps))for(c in s)l[c]===void 0&&(l[c]=s[c]);return n.vnode&&n.vnode(u),u}var Ie={eye:`M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12Z M12 9a3 3 0 1 0 0 6 3 3 0 0 0 0-6Z`,eyeOff:`M3 3l18 18 M10.6 5.1A10 10 0 0 1 12 5c6.5 0 10 7 10 7a17 17 0 0 1-3.2 4.2 M6.6 6.6A17 17 0 0 0 2 12s3.5 7 10 7a9.6 9.6 0 0 0 5.4-1.6 M9.9 9.9a3 3 0 0 0 4.2 4.2`,copy:`M9 9h11v11H9z M5 15H4V4h11v1`,plus:`M12 5v14 M5 12h14`,star:`M12 3l2.8 5.7 6.2.9-4.5 4.4 1.1 6.2L12 17.3 6.4 20.2l1.1-6.2L3 9.6l6.2-.9Z`,lock:`M6 11h12v10H6z M8 11V7a4 4 0 0 1 8 0v4`,settings:`M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1.1 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1Z`,trash:`M4 7h16 M10 11v6 M14 11v6 M6 7l1 13h10l1-13 M9 7V4h6v3`,back:`M15 18l-6-6 6-6`,check:`M5 12l5 5 9-10`,alert:`M12 3l10 18H2Z M12 10v4 M12 17.5v.5`,key:`M14 10a4 4 0 1 0-3.6 4L13 17h2v2h2v2h3v-3l-6.4-6.4A4 4 0 0 0 14 10Z`,seed:`M4 6h16 M4 12h16 M4 18h10`,shield:`M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6Z`,duplicate:`M8 8h12v12H8z M4 16V4h12`,archive:`M3 4h18v4H3z M5 8v12h14V8 M10 12h4`,x:`M6 6l12 12 M18 6L6 18`,search:`M11 4a7 7 0 1 0 0 14 7 7 0 0 0 0-14Z M20 20l-4-4`,chevron:`M9 6l6 6-6 6`,wallet:`M3 7h15a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H3z M3 7V5h13v2 M16 13.5h.01`,terminal:`M4 6l6 6-6 6 M12 19h8`,mail:`M3 6h18v12H3z M3 7l9 6 9-6`,code:`M8 6l-6 6 6 6 M16 6l6 6-6 6`,list:`M9 6h11 M9 12h11 M9 18h11 M4 6h.01 M4 12h.01 M4 18h.01`,clock:`M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18Z M12 7v5l3 2`,expand:`M7 9l5-5 5 5 M7 15l5 5 5-5`,collapse:`M7 4l5 5 5-5 M7 20l5-5 5 5`,sliders:`M4 6h16 M4 12h16 M4 18h16 M9 4v4 M15 10v4 M7 16v4`,download:`M12 4v11 M7 10l5 5 5-5 M5 20h14`,file:`M6 3h8l4 4v14H6z M14 3v4h4`},U=({name:e,size:t=16,...n})=>H(`svg`,{width:t,height:t,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,"stroke-width":`2`,"stroke-linecap":`round`,"stroke-linejoin":`round`,"aria-hidden":`true`,...n,children:H(`path`,{d:Ie[e]})}),Le=new TextEncoder,Re=new TextDecoder,W=e=>Le.encode(e),ze=e=>Re.decode(e),Be=e=>Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``),Ve=e=>{let t=e.startsWith(`0x`)||e.startsWith(`0X`)?e.slice(2):e;if(t.length%2!=0||/[^0-9a-fA-F]/.test(t))throw Error(`Invalid hex`);let n=new Uint8Array(t.length/2);for(let e=0;e{let t=``;for(let n=0;n{let t=atob(e),n=new Uint8Array(t.length);for(let e=0;eglobalThis.crypto!==void 0&&globalThis.crypto.subtle!==void 0,K=e=>e,We=async e=>new Uint8Array(await crypto.subtle.digest(`SHA-256`,K(e))),Ge=async(e,t)=>{let n=await crypto.subtle.importKey(`raw`,K(e),{name:`HMAC`,hash:`SHA-512`},!1,[`sign`]);return new Uint8Array(await crypto.subtle.sign(`HMAC`,n,K(t)))},Ke=(e,t)=>{if(e.length!==t.length)return!1;for(let n=0;n{let t=new Uint8Array(e);return crypto.getRandomValues(t),t},qe=()=>typeof crypto.randomUUID==`function`?crypto.randomUUID():Be(q(16)),Je=[`mnemonic`,`privateKey`,`sshKey`,`pgpKey`,`apiKey`,`genericKey`,`recoveryCodes`,`other`],J={mnemonic:{label:`Seed phrase`,one:`seed phrase`,plural:`seed phrases`,group:`crypto`,secret:`words`,secretLabel:`Seed phrase`,passphraseLabel:`Passphrase (25th word)`,passphraseHint:`Optional BIP39 passphrase. A different passphrase opens a different wallet.`,serviceLabel:`Chain / coin`,accountLabel:`Wallet / device`,expires:!1,backupReminders:!0},privateKey:{label:`Wallet key`,one:`wallet key`,plural:`wallet keys`,group:`crypto`,secret:`key`,secretLabel:`Private key`,secretPlaceholder:`Hex, WIF, xprv, nsec, base58, keystore JSON…`,passphraseLabel:`Keystore password`,passphraseHint:`Only for encrypted keystores (e.g. Ethereum JSON keystores).`,serviceLabel:`Chain / coin`,accountLabel:`Wallet / device`,expires:!1,backupReminders:!0},sshKey:{label:`SSH key`,one:`SSH key`,plural:`SSH keys`,group:`keys`,secret:`key`,secretLabel:`Private key`,secretPlaceholder:`-----BEGIN OPENSSH PRIVATE KEY-----`,passphraseLabel:`Key passphrase`,passphraseHint:`The passphrase that unlocks the key file, if it has one.`,publicKey:{label:`Public key`,placeholder:`ssh-ed25519 AAAA… user@host`,fingerprintLabel:`Fingerprint`,fingerprintPlaceholder:`SHA256:…`},serviceLabel:`Hosts / service`,accountLabel:`User / account`,expires:!0,backupReminders:!1},pgpKey:{label:`PGP key`,one:`PGP key`,plural:`PGP keys`,group:`keys`,secret:`key`,secretLabel:`Private key`,secretPlaceholder:`-----BEGIN PGP PRIVATE KEY BLOCK-----`,passphraseLabel:`Key passphrase`,passphraseHint:`The passphrase that protects the secret key.`,publicKey:{label:`Public key`,placeholder:`-----BEGIN PGP PUBLIC KEY BLOCK-----`,fingerprintLabel:`Fingerprint`,fingerprintPlaceholder:`40 hex characters`},serviceLabel:`Used for`,accountLabel:`User ID / email`,expires:!0,backupReminders:!0},apiKey:{label:`API key or token`,one:`API key`,plural:`API keys`,group:`keys`,secret:`token`,secretLabel:`Key or token`,secretPlaceholder:`Paste the key or token`,serviceLabel:`Service`,accountLabel:`Account / project`,expires:!0,backupReminders:!1},genericKey:{label:`Other key`,one:`other key`,plural:`other keys`,group:`keys`,secret:`key`,secretLabel:`Secret key`,secretPlaceholder:`age, WireGuard, PEM, JSON Web Key, Nostr…`,passphraseLabel:`Passphrase`,passphraseHint:`If the key is encrypted.`,publicKey:{label:`Public key`,placeholder:`Public key or recipient`,fingerprintLabel:`Fingerprint / key ID`,fingerprintPlaceholder:`Optional`},serviceLabel:`Used for`,accountLabel:`Account / owner`,expires:!0,backupReminders:!1},recoveryCodes:{label:`Recovery codes`,one:`set of recovery codes`,plural:`sets of recovery codes`,group:`secrets`,secret:`codes`,secretLabel:`Recovery codes`,secretPlaceholder:`One code per line`,serviceLabel:`Service`,accountLabel:`Account`,expires:!1,backupReminders:!0},other:{label:`Other secret`,one:`other secret`,plural:`other secrets`,group:`secrets`,secret:`fields`,secretLabel:`Fields`,serviceLabel:`Service`,accountLabel:`Account`,expires:!1,backupReminders:!1}},Ye={crypto:`Crypto`,keys:`Keys`,secrets:`Secrets`},Xe=e=>J[e].group===`crypto`,Ze=`keyfold`,Qe=`Managed by the Keyfold editor for Standard Notes (https://github.com/nickstruglia/standard-notes-keyfold). Open it with Keyfold; do not edit it as plain text or convert it to Super, which can damage the data. `,$e=Qe+`The vault below lists each entry with its label, kind and secret; seed phrase words are in order, and \\n in a value is a line break.`,et=e=>`The vault below is encrypted with ${e}: PBKDF2-SHA256 (password NFC-normalized, the salt and iteration count below) gives an AES-256-GCM key; the IV is below, the ciphertext ends with the 16-byte tag, the associated data is "keyfold|1|PBKDF2-SHA256||AES-256-GCM", and the plaintext is the vault as JSON.`,tt=Qe+et(`your vault password`),Y={autoHideSeconds:30,clipboardClearSeconds:30,hideOnBlur:!0,privacyScreen:!1,autoLockMinutes:5,backupReminderMonths:12,layout:`stacked`,density:`comfortable`,singleExpand:!1,groupBy:`kind`,sort:`updated`,lastExportedAt:``},nt=()=>{let e=new Date,t=e=>String(e).padStart(2,`0`);return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())}`},rt=()=>({entries:[],settings:{...Y}}),it=(e,t={})=>{let n=new Date().toISOString();return{id:qe(),kind:e,label:``,description:``,chain:``,wallet:``,service:``,account:``,createdOn:nt(),expiresOn:``,tags:[],favorite:!1,archived:!1,scheme:`bip39`,words:e===`mnemonic`?Array(12).fill(``):[],passphrase:``,passphraseHint:``,secret:``,derivationPath:``,fingerprint:``,publicInfo:``,backups:[],customFields:[],notes:``,addedAt:n,updatedAt:n,...t}},X=(e,t=``)=>typeof e==`string`?e:t,at=(e,t=!1)=>typeof e==`boolean`?e:t,ot=(e,t)=>typeof e==`number`&&Number.isFinite(e)&&e>=0?e:t,st=e=>Array.isArray(e)?e:[],ct=(e,t,n)=>t.includes(e)?e:n,lt=e=>e&&typeof e==`object`&&!Array.isArray(e)?e:{},ut=[`bip39`,`electrum`,`aezeed`,`slip39`,`monero`,`other`],dt=e=>{let t=lt(e),n=it(`other`);return{...t,id:X(t.id)||n.id,kind:Je.includes(t.kind)?t.kind:`other`,label:X(t.label),description:X(t.description),chain:X(t.chain),wallet:X(t.wallet),service:X(t.service),account:X(t.account),createdOn:X(t.createdOn),expiresOn:X(t.expiresOn),tags:st(t.tags).filter(e=>typeof e==`string`),favorite:at(t.favorite),archived:at(t.archived),scheme:ut.includes(t.scheme)?t.scheme:`bip39`,words:st(t.words).map(e=>X(e)),passphrase:X(t.passphrase),passphraseHint:X(t.passphraseHint),secret:X(t.secret),derivationPath:X(t.derivationPath),fingerprint:X(t.fingerprint),publicInfo:X(t.publicInfo),backups:st(t.backups).map(e=>{let t=lt(e);return{...t,id:X(t.id)||qe(),location:X(t.location),verifiedOn:X(t.verifiedOn)}}),customFields:st(t.customFields).map(e=>{let t=lt(e);return{...t,id:X(t.id)||qe(),label:X(t.label),value:X(t.value),hidden:at(t.hidden,!0),multiline:t.multiline===!0||X(t.value).includes(` +`)}}),notes:X(t.notes),addedAt:X(t.addedAt)||n.addedAt,updatedAt:X(t.updatedAt)||n.updatedAt}},ft={layout:[`stacked`,`split`],density:[`comfortable`,`compact`],groupBy:[`none`,`kind`,`chain`,`wallet`,`tag`],sort:[`updated`,`label`,`created`]},pt=new WeakSet,mt=e=>pt.has(e),ht=(e,t)=>st(e.entries).some(e=>{let t=lt(e);return t.kind!==void 0&&!Je.includes(t.kind)||t.scheme!==void 0&&!ut.includes(t.scheme)})||Object.entries(ft).some(([e,n])=>t[e]!==void 0&&!n.includes(t[e])),gt=(e,t,n)=>{let r=ot(e,t);return r>n?t:r},_t=e=>{let t=lt(e),n=lt(t.settings),r={...t,entries:st(t.entries).map(dt),settings:{...n,autoHideSeconds:gt(n.autoHideSeconds,Y.autoHideSeconds,86400),clipboardClearSeconds:gt(n.clipboardClearSeconds,Y.clipboardClearSeconds,86400),hideOnBlur:at(n.hideOnBlur,Y.hideOnBlur),privacyScreen:at(n.privacyScreen,Y.privacyScreen),autoLockMinutes:gt(n.autoLockMinutes,Y.autoLockMinutes,10080),backupReminderMonths:gt(n.backupReminderMonths,Y.backupReminderMonths,1200),layout:ct(n.layout,[`stacked`,`split`],Y.layout),density:ct(n.density,[`comfortable`,`compact`],Y.density),singleExpand:at(n.singleExpand,Y.singleExpand),groupBy:ct(n.groupBy,[`none`,`kind`,`chain`,`wallet`,`tag`],Y.groupBy),sort:ct(n.sort,[`updated`,`label`,`created`],Y.sort),lastExportedAt:X(n.lastExportedAt)}};return ht(t,n)&&pt.add(r),r},vt=e=>{let t=lt(e);return t.kdf===`PBKDF2-SHA256`&&t.cipher===`AES-256-GCM`&&typeof t.iterations==`number`&&Number.isInteger(t.iterations)&&t.iterations>=1e3&&t.iterations<=1e7&&typeof t.salt==`string`&&typeof t.iv==`string`&&typeof t.ciphertext==`string`},yt=e=>{let t=e?.replace(/^\uFEFF/,``);if(!t||!t.trim())return{kind:`empty`};let n;try{n=JSON.parse(t)}catch{return{kind:`foreign`,text:t}}let r=lt(n);if(r.app!==`keyfold`)return{kind:`foreign`,text:t};let i=typeof r.version==`number`?r.version:0;return i>1?{kind:`newer`,version:i}:r.encryption===void 0?{kind:`plain`,vault:_t(r.vault)}:vt(r.encryption)?typeof r.exportedAt==`string`?{kind:`encrypted`,blob:r.encryption,exportedAt:r.exportedAt}:{kind:`encrypted`,blob:r.encryption}:{kind:`unsupported`}},bt=e=>JSON.stringify({app:Ze,version:1,readme:$e,vault:e},null,1),xt=e=>JSON.stringify({app:Ze,version:1,readme:tt,encryption:e},null,1),St=e=>{if(!e)return`Keyfold (password protected)`;let t=e.entries.filter(e=>!e.archived),n=Je.flatMap(e=>{let n=t.filter(t=>t.kind===e).length;return n?[`${n} ${n===1?J[e].one:J[e].plural}`]:[]});return`Keyfold: ${n.length?n.join(`, `):`empty`}`},Ct=e=>e.backups.map(e=>e.verifiedOn).filter(Boolean).sort().pop()??``,wt=(e,t,n=new Date)=>{if(t<=0||e.archived||!J[e.kind].backupReminders)return!1;let r=Ct(e);if(!r)return!0;let i=new Date(`${r}T00:00:00`);return i.setMonth(i.getMonth()+t),i.getTime()<=n.getTime()},Tt=(e,t=new Date)=>{if(!e.expiresOn||!J[e.kind].expires)return null;let n=new Date(`${e.expiresOn}T00:00:00`);if(Number.isNaN(n.getTime()))return null;let r=new Date(t.getFullYear(),t.getMonth(),t.getDate());return Math.round((n.getTime()-r.getTime())/864e5)},Et=(e,t=new Date)=>{let n=Tt(e,t);return n!==null&&n<=30&&!e.archived},Dt=fe({settings:Y,readOnly:!1,hideEpoch:0,copy:()=>void 0,toast:()=>void 0,confirm:async()=>!1,sectionOpen:(e,t)=>t,setSectionOpen:()=>void 0}),Z=()=>De(Dt),Ot=(e,t)=>{let{sectionOpen:n,setSectionOpen:r}=Z();return[n(e,t),t=>r(e,t)]},kt=(e=!0)=>{let t=B(null);return z(()=>{e&&t.current?.focus()},[]),t},At=(e,t)=>{let[n,r]=R(void 0),i=B(0);return z(()=>{let t=++i.current;e().then(e=>t===i.current&&r(()=>e),()=>t===i.current&&r(void 0))},t),n},jt=e=>{let{hideEpoch:t,settings:n}=Z(),[r,i]=R(!1);return z(()=>i(!1),[t]),z(()=>{if(!r||!n.autoHideSeconds)return;let e=setTimeout(()=>i(!1),n.autoHideSeconds*1e3);return()=>clearTimeout(e)},[r,n.autoHideSeconds,e]),[r,i]},Mt=()=>typeof matchMedia==`function`&&matchMedia(`(pointer: coarse)`).matches,Nt={autocomplete:`off`,autocorrect:`off`,autocapitalize:`off`,spellcheck:!1,"data-1p-ignore":`true`,"data-lpignore":`true`,"data-bwignore":`true`,"data-form-type":`other`,"data-secret":``},Pt={autocorrect:`off`,autocapitalize:`off`,spellcheck:!1},Ft=({value:e,onInput:t,label:n,placeholder:r,multiline:i,mono:a,id:o,onMultilinePaste:s})=>{let{readOnly:c,copy:l}=Z(),[u,d]=jt(e),f=`input ${a?`mono`:``}`,p=B(null),[m,h]=R(!1);z(()=>{m&&u&&(p.current?.focus(),h(!1))},[m,u]);let g;return g=i&&!u?H(`button`,{type:`button`,class:`input masked-placeholder`,"aria-label":`${n} (hidden). Reveal to view or edit`,onClick:()=>{d(!0),h(!0)},children:e?`${`•`.repeat(12)} ${e.length} characters, hidden`:r||`Empty`}):i?H(`textarea`,{ref:p,id:o,class:f,value:e,rows:e.length>120?6:3,placeholder:r,"aria-label":n,readOnly:c,onInput:e=>t(e.currentTarget.value),...Nt}):H(`input`,{id:o,class:f,type:u?`text`:`password`,value:e,placeholder:r,"aria-label":n,readOnly:c,onInput:e=>t(e.currentTarget.value),onPaste:t=>{let n=t.clipboardData?.getData(`text`)??``;if(!s||!/[\r\n]/.test(n))return;t.preventDefault();let r=t.currentTarget,i=r.selectionStart??e.length,a=r.selectionEnd??e.length;s(e.slice(0,i)+n+e.slice(a))},...Nt}),H(`div`,{class:`secret ${i?`secret-multiline`:``}`,children:[g,H(`div`,{class:`secret-actions`,children:[H(`button`,{type:`button`,class:`icon-button`,title:u?`Hide`:`Reveal`,"aria-label":`${u?`Hide`:`Reveal`} ${n}`,onClick:()=>d(!u),children:H(U,{name:u?`eyeOff`:`eye`})}),H(`button`,{type:`button`,class:`icon-button`,title:`Copy`,"aria-label":`Copy ${n}`,disabled:!e,onClick:()=>l(e,n),children:H(U,{name:`copy`})})]})]})},It=`abandon ability able about above absent absorb abstract + absurd abuse access accident account accuse achieve acid + acoustic acquire across act action actor actress actual + adapt add addict address adjust admit adult advance + advice aerobic affair afford afraid again age agent + agree ahead aim air airport aisle alarm album + alcohol alert alien all alley allow almost alone + alpha already also alter always amateur amazing among + amount amused analyst anchor ancient anger angle angry + animal ankle announce annual another answer antenna antique + anxiety any apart apology appear apple approve april + arch arctic area arena argue arm armed armor + army around arrange arrest arrive arrow art artefact + artist artwork ask aspect assault asset assist assume + asthma athlete atom attack attend attitude attract auction + audit august aunt author auto autumn average avocado + avoid awake aware away awesome awful awkward axis + baby bachelor bacon badge bag balance balcony ball + bamboo banana banner bar barely bargain barrel base + basic basket battle beach bean beauty because become + beef before begin behave behind believe below belt + bench benefit best betray better between beyond bicycle + bid bike bind biology bird birth bitter black + blade blame blanket blast bleak bless blind blood + blossom blouse blue blur blush board boat body + boil bomb bone bonus book boost border boring + borrow boss bottom bounce box boy bracket brain + brand brass brave bread breeze brick bridge brief + bright bring brisk broccoli broken bronze broom brother + brown brush bubble buddy budget buffalo build bulb + bulk bullet bundle bunker burden burger burst bus + business busy butter buyer buzz cabbage cabin cable + cactus cage cake call calm camera camp can + canal cancel candy cannon canoe canvas canyon capable + capital captain car carbon card cargo carpet carry + cart case cash casino castle casual cat catalog + catch category cattle caught cause caution cave ceiling + celery cement census century cereal certain chair chalk + champion change chaos chapter charge chase chat cheap + check cheese chef cherry chest chicken chief child + chimney choice choose chronic chuckle chunk churn cigar + cinnamon circle citizen city civil claim clap clarify + claw clay clean clerk clever click client cliff + climb clinic clip clock clog close cloth cloud + clown club clump cluster clutch coach coast coconut + code coffee coil coin collect color column combine + come comfort comic common company concert conduct confirm + congress connect consider control convince cook cool copper + copy coral core corn correct cost cotton couch + country couple course cousin cover coyote crack cradle + craft cram crane crash crater crawl crazy cream + credit creek crew cricket crime crisp critic crop + cross crouch crowd crucial cruel cruise crumble crunch + crush cry crystal cube culture cup cupboard curious + current curtain curve cushion custom cute cycle dad + damage damp dance danger daring dash daughter dawn + day deal debate debris decade december decide decline + decorate decrease deer defense define defy degree delay + deliver demand demise denial dentist deny depart depend + deposit depth deputy derive describe desert design desk + despair destroy detail detect develop device devote diagram + dial diamond diary dice diesel diet differ digital + dignity dilemma dinner dinosaur direct dirt disagree discover + disease dish dismiss disorder display distance divert divide + divorce dizzy doctor document dog doll dolphin domain + donate donkey donor door dose double dove draft + dragon drama drastic draw dream dress drift drill + drink drip drive drop drum dry duck dumb + dune during dust dutch duty dwarf dynamic eager + eagle early earn earth easily east easy echo + ecology economy edge edit educate effort egg eight + either elbow elder electric elegant element elephant elevator + elite else embark embody embrace emerge emotion employ + empower empty enable enact end endless endorse enemy + energy enforce engage engine enhance enjoy enlist enough + enrich enroll ensure enter entire entry envelope episode + equal equip era erase erode erosion error erupt + escape essay essence estate eternal ethics evidence evil + evoke evolve exact example excess exchange excite exclude + excuse execute exercise exhaust exhibit exile exist exit + exotic expand expect expire explain expose express extend + extra eye eyebrow fabric face faculty fade faint + faith fall false fame family famous fan fancy + fantasy farm fashion fat fatal father fatigue fault + favorite feature february federal fee feed feel female + fence festival fetch fever few fiber fiction field + figure file film filter final find fine finger + finish fire firm first fiscal fish fit fitness + fix flag flame flash flat flavor flee flight + flip float flock floor flower fluid flush fly + foam focus fog foil fold follow food foot + force forest forget fork fortune forum forward fossil + foster found fox fragile frame frequent fresh friend + fringe frog front frost frown frozen fruit fuel + fun funny furnace fury future gadget gain galaxy + gallery game gap garage garbage garden garlic garment + gas gasp gate gather gauge gaze general genius + genre gentle genuine gesture ghost giant gift giggle + ginger giraffe girl give glad glance glare glass + glide glimpse globe gloom glory glove glow glue + goat goddess gold good goose gorilla gospel gossip + govern gown grab grace grain grant grape grass + gravity great green grid grief grit grocery group + grow grunt guard guess guide guilt guitar gun + gym habit hair half hammer hamster hand happy + harbor hard harsh harvest hat have hawk hazard + head health heart heavy hedgehog height hello helmet + help hen hero hidden high hill hint hip + hire history hobby hockey hold hole holiday hollow + home honey hood hope horn horror horse hospital + host hotel hour hover hub huge human humble + humor hundred hungry hunt hurdle hurry hurt husband + hybrid ice icon idea identify idle ignore ill + illegal illness image imitate immense immune impact impose + improve impulse inch include income increase index indicate + indoor industry infant inflict inform inhale inherit initial + inject injury inmate inner innocent input inquiry insane + insect inside inspire install intact interest into invest + invite involve iron island isolate issue item ivory + jacket jaguar jar jazz jealous jeans jelly jewel + job join joke journey joy judge juice jump + jungle junior junk just kangaroo keen keep ketchup + key kick kid kidney kind kingdom kiss kit + kitchen kite kitten kiwi knee knife knock know + lab label labor ladder lady lake lamp language + laptop large later latin laugh laundry lava law + lawn lawsuit layer lazy leader leaf learn leave + lecture left leg legal legend leisure lemon lend + length lens leopard lesson letter level liar liberty + library license life lift light like limb limit + link lion liquid list little live lizard load + loan lobster local lock logic lonely long loop + lottery loud lounge love loyal lucky luggage lumber + lunar lunch luxury lyrics machine mad magic magnet + maid mail main major make mammal man manage + mandate mango mansion manual maple marble march margin + marine market marriage mask mass master match material + math matrix matter maximum maze meadow mean measure + meat mechanic medal media melody melt member memory + mention menu mercy merge merit merry mesh message + metal method middle midnight milk million mimic mind + minimum minor minute miracle mirror misery miss mistake + mix mixed mixture mobile model modify mom moment + monitor monkey monster month moon moral more morning + mosquito mother motion motor mountain mouse move movie + much muffin mule multiply muscle museum mushroom music + must mutual myself mystery myth naive name napkin + narrow nasty nation nature near neck need negative + neglect neither nephew nerve nest net network neutral + never news next nice night noble noise nominee + noodle normal north nose notable note nothing notice + novel now nuclear number nurse nut oak obey + object oblige obscure observe obtain obvious occur ocean + october odor off offer office often oil okay + old olive olympic omit once one onion online + only open opera opinion oppose option orange orbit + orchard order ordinary organ orient original orphan ostrich + other outdoor outer output outside oval oven over + own owner oxygen oyster ozone pact paddle page + pair palace palm panda panel panic panther paper + parade parent park parrot party pass patch path + patient patrol pattern pause pave payment peace peanut + pear peasant pelican pen penalty pencil people pepper + perfect permit person pet phone photo phrase physical + piano picnic picture piece pig pigeon pill pilot + pink pioneer pipe pistol pitch pizza place planet + plastic plate play please pledge pluck plug plunge + poem poet point polar pole police pond pony + pool popular portion position possible post potato pottery + poverty powder power practice praise predict prefer prepare + present pretty prevent price pride primary print priority + prison private prize problem process produce profit program + project promote proof property prosper protect proud provide + public pudding pull pulp pulse pumpkin punch pupil + puppy purchase purity purpose purse push put puzzle + pyramid quality quantum quarter question quick quit quiz + quote rabbit raccoon race rack radar radio rail + rain raise rally ramp ranch random range rapid + rare rate rather raven raw razor ready real + reason rebel rebuild recall receive recipe record recycle + reduce reflect reform refuse region regret regular reject + relax release relief rely remain remember remind remove + render renew rent reopen repair repeat replace report + require rescue resemble resist resource response result retire + retreat return reunion reveal review reward rhythm rib + ribbon rice rich ride ridge rifle right rigid + ring riot ripple risk ritual rival river road + roast robot robust rocket romance roof rookie room + rose rotate rough round route royal rubber rude + rug rule run runway rural sad saddle sadness + safe sail salad salmon salon salt salute same + sample sand satisfy satoshi sauce sausage save say + scale scan scare scatter scene scheme school science + scissors scorpion scout scrap screen script scrub sea + search season seat second secret section security seed + seek segment select sell seminar senior sense sentence + series service session settle setup seven shadow shaft + shallow share shed shell sheriff shield shift shine + ship shiver shock shoe shoot shop short shoulder + shove shrimp shrug shuffle shy sibling sick side + siege sight sign silent silk silly silver similar + simple since sing siren sister situate six size + skate sketch ski skill skin skirt skull slab + slam sleep slender slice slide slight slim slogan + slot slow slush small smart smile smoke smooth + snack snake snap sniff snow soap soccer social + sock soda soft solar soldier solid solution solve + someone song soon sorry sort soul sound soup + source south space spare spatial spawn speak special + speed spell spend sphere spice spider spike spin + spirit split spoil sponsor spoon sport spot spray + spread spring spy square squeeze squirrel stable stadium + staff stage stairs stamp stand start state stay + steak steel stem step stereo stick still sting + stock stomach stone stool story stove strategy street + strike strong struggle student stuff stumble style subject + submit subway success such sudden suffer sugar suggest + suit summer sun sunny sunset super supply supreme + sure surface surge surprise surround survey suspect sustain + swallow swamp swap swarm swear sweet swift swim + swing switch sword symbol symptom syrup system table + tackle tag tail talent talk tank tape target + task taste tattoo taxi teach team tell ten + tenant tennis tent term test text thank that + theme then theory there they thing this thought + three thrive throw thumb thunder ticket tide tiger + tilt timber time tiny tip tired tissue title + toast tobacco today toddler toe together toilet token + tomato tomorrow tone tongue tonight tool tooth top + topic topple torch tornado tortoise toss total tourist + toward tower town toy track trade traffic tragic + train transfer trap trash travel tray treat tree + trend trial tribe trick trigger trim trip trophy + trouble truck true truly trumpet trust truth try + tube tuition tumble tuna tunnel turkey turn turtle + twelve twenty twice twin twist two type typical + ugly umbrella unable unaware uncle uncover under undo + unfair unfold unhappy uniform unique unit universe unknown + unlock until unusual unveil update upgrade uphold upon + upper upset urban urge usage use used useful + useless usual utility vacant vacuum vague valid valley + valve van vanish vapor various vast vault vehicle + velvet vendor venture venue verb verify version very + vessel veteran viable vibrant vicious victory video view + village vintage violin virtual virus visa visit visual + vital vivid vocal voice void volcano volume vote + voyage wage wagon wait walk wall walnut want + warfare warm warrior wash wasp waste water wave + way wealth weapon wear weasel weather web wedding + weekend weird welcome west wet whale what wheat + wheel when where whip whisper wide width wife + wild will win window wine wing wink winner + winter wire wisdom wise wish witness wolf woman + wonder wood wool word work world worry worth + wrap wreck wrestle wrist write wrong yard year + yellow you young youth zebra zero zone zoo`.split(/\s+/),Lt=[{id:`bip39`,label:`BIP39 (English)`,counts:[12,15,18,21,24]},{id:`electrum`,label:`Electrum`,counts:[12]},{id:`aezeed`,label:`Aezeed (LND)`,counts:[24]},{id:`slip39`,label:`SLIP-39 share (Shamir)`,counts:[20,33]},{id:`monero`,label:`Monero`,counts:[25,13,16]},{id:`other`,label:`Other`,counts:[]}],Rt=[12,13,15,16,18,20,21,24,25,33],zt=e=>e===`bip39`||e===`electrum`||e===`aezeed`,Bt=new Map(It.map((e,t)=>[e,t])),Vt=e=>e.normalize(`NFKD`).trim().toLowerCase(),Ht=e=>Bt.has(Vt(e)),Ut=/[\u200B-\u200D\u2060\uFEFF]/g,Wt=/^[^\p{L}\p{M}\p{N}]+|[^\p{L}\p{M}\p{N}]+$/gu,Gt=e=>{let t=e.replace(Ut,` `).replace(/(?1){let e=[...n].sort((e,t)=>e.n-t.n);if(e.every((t,n)=>t.n===e[0].n+n)&&e[0].n>=1)return{words:e.map(e=>e.word),firstNumber:e[0].n,reordered:e.some((e,t)=>e!==n[t])}}return{words:r,reordered:!1}},Kt=e=>Gt(e).words,qt=e=>{let t=Vt(e);if(t.length<4||Bt.has(t))return t;let n=It.filter(e=>e.startsWith(t));return n.length===1?n[0]:t},Jt=(e,t)=>{let n=Array.from({length:t.length+1},(e,t)=>t);for(let r=1;r<=e.length;r++){let i=n[0];n[0]=r;for(let a=1;a<=t.length;a++){let o=n[a];n[a]=Math.min(n[a]+1,n[a-1]+1,i+(e[r-1]===t[a-1]?0:1)),i=o}}return n[t.length]},Yt=(e,t=3)=>{let n=Vt(e);if(!n||n.length>10)return[];let r=It.filter(e=>e.startsWith(n.slice(0,4)));return r.length>0&&r.length<=t?r:It.map(e=>[e,Jt(n,e)]).filter(([,e])=>e<=2).sort((e,t)=>e[1]-t[1]).slice(0,t).map(([e])=>e)},Xt=async e=>{let t=e.length*11,n=t/33,r=t-n,i=e.map(e=>e.toString(2).padStart(11,`0`)).join(``),a=new Uint8Array(r/8);for(let e=0;ee.toString(2).padStart(8,`0`)).join(``);return i.slice(r)===s.slice(0,n)},Zt=[[`01`,`standard`],[`100`,`segwit`],[`101`,`2fa`],[`102`,`2fa-segwit`]],Qt=async e=>{let t=e.map(e=>Vt(e).replace(/[̀-ͯ]/g,``)).join(` `),n=Be(await Ge(W(`Seed version`),W(t)));return Zt.find(([e])=>n.startsWith(e))?.[1]??null},$t=async(e,t)=>{let n=t.map(Vt),r=n.filter(Boolean).length,i=zt(e)?n.flatMap((e,t)=>e&&!Bt.has(e)?[t]:[]):[];if(r===0)return{status:`incomplete`,message:`No words entered yet.`,unknownWords:i};if(r0)return{status:`invalid`,message:`Not in the English BIP39 wordlist: ${i.map(e=>`#${e+1}`).join(`, `)}. For other languages or old Electrum seeds, choose Other.`,unknownWords:i};if(!Ue()&&(e===`bip39`||e===`electrum`))return{status:`unchecked`,message:`Checksum check needs a secure (https) context.`,unknownWords:i};switch(e){case`bip39`:{if(![12,15,18,21,24].includes(n.length))return{status:`invalid`,message:`BIP39 phrases have 12, 15, 18, 21 or 24 words (this has ${n.length}).`,unknownWords:i};if(await Xt(n.map(e=>Bt.get(e))))return{status:`valid`,message:`Valid BIP39 checksum (${n.length} words).`,unknownWords:i};let e=n.length===12?await Qt(n):null;return{status:`invalid`,message:e?`Not a BIP39 phrase, but these words are a valid Electrum seed (${e}). Choose the Electrum scheme.`:`Checksum mismatch. Check the spelling and order of every word.`,unknownWords:i}}case`electrum`:{let e=await Qt(n);return e?{status:`valid`,message:`Valid Electrum seed (${e}).`,unknownWords:i}:{status:`invalid`,message:`Not a valid Electrum 2.0+ seed. Check the words, or pick another scheme.`,unknownWords:i}}case`monero`:if(n.length!==25&&n.length!==13)break;return tn(n)?{status:`valid`,message:`Monero checksum word OK (${n.length} words).`,unknownWords:i}:{status:`invalid`,message:`The last word does not match the Monero checksum. Check the spelling and order of every word.`,unknownWords:i};case`aezeed`:return{status:`unchecked`,message:`All words are in the wordlist. The aezeed checksum is not checked here.`,unknownWords:i}}return{status:`unchecked`,message:`${n.length} words. Checksums for this scheme are not checked here.`,unknownWords:i}},en=e=>{let t=4294967295;for(let n of e){let e=(t^n)&255;for(let t=0;t<8;t++)e=e&1?e>>>1^3988292384:e>>>1;t=t>>>8^e}return(t^4294967295)>>>0},tn=e=>{let t=e.slice(0,-1).map(e=>e.normalize(`NFC`)),n=e[e.length-1].normalize(`NFC`);return[3,4,1].some(e=>{let r=t.map(t=>[...t].slice(0,e).join(``)).join(``);return t[en(W(r))%t.length]===n})},nn=({words:e,scheme:t,unknownWords:n,onChange:r})=>{let{readOnly:i,copy:a,settings:o}=Z(),[s,c]=jt(e),[l,u]=R(null),[d,f]=R(null),[p,m]=R(``),h=B([]),g=zt(t),_=!Mt();z(()=>{if(d===null||!o.autoHideSeconds)return;let e=setTimeout(()=>f(null),o.autoHideSeconds*1e3);return()=>clearTimeout(e)},[d,e,o.autoHideSeconds]);let v=(t,n)=>{let i=[...e];i[t]=n,r(i)},y=(t,n)=>{let i=Math.min(48,Math.max(e.length,t+n.length)),a=Array.from({length:i},(t,n)=>e[n]??``);n.slice(0,i-t).forEach((e,n)=>a[t+n]=e),r(a),h.current[Math.min(t+n.length,i-1)]?.focus()},b=(e,t)=>{let n=Gt(t.clipboardData?.getData(`text`)??``);if(n.words.length<2)return;t.preventDefault();let r=n.firstNumber!==void 0&&n.firstNumber-1<48?n.firstNumber-1:e;y(r,n.words),m(n.reordered?`Placed the pasted words by their numbers. Check the order.`:``)},ee=(e,t)=>{let n=t.currentTarget,r=n.value;t.isComposing?v(e,r):x(e,n)},x=(e,t)=>{let n=t.value;if(!/\s/.test(n)){let r=n.toLowerCase();if(r!==n){let[e,n]=[t.selectionStart,t.selectionEnd];t.value=r,e!==null&&n!==null&&t.setSelectionRange(e,n)}v(e,r);return}let r=Kt(n);r.length>1?y(e,r):(v(e,r[0]??``),r.length===1&&h.current[e+1]?.focus())},S=(t,n)=>{n.isComposing||n.keyCode===229||(n.key===` `||n.key===`Enter`?(n.preventDefault(),h.current[t+1]?.focus()):n.key===`Backspace`&&!e[t]&&t>0?(n.preventDefault(),h.current[t-1]?.focus()):_&&(n.key.length===1||n.key===`Backspace`)&&!n.ctrlKey&&!n.metaKey&&f(t))},C=()=>{u(null),f(null)},te=(e,t)=>{v(e,t),h.current[e]?.focus()},w=g?n.map(t=>[t,qt(e[t]??``)]).filter(([t,n])=>n!==e[t]&&Ht(n)):[],T=w.length>0&&w.length===n.length,ne=()=>{let t=[...e];for(let[e,n]of w)t[e]=n;r(t)},E=e.filter(Boolean),D=e=>s||_&&d===e,re=l!==null&&n.includes(l)&&e[l]&&D(l)?Yt(e[l]):[];return H(`div`,{class:`word-grid-wrap`,children:[H(`div`,{class:`word-toolbar`,children:[H(`button`,{type:`button`,class:`button small`,onClick:()=>c(!s),children:[H(U,{name:s?`eyeOff`:`eye`}),` `,s?`Hide words`:`Reveal words`]}),H(`button`,{type:`button`,class:`button small`,disabled:E.length===0,onClick:()=>a(E.join(` `),E.length===e.length?`Seed phrase`:`Seed phrase (only ${E.length} of ${e.length} words)`),children:[H(U,{name:`copy`}),` Copy phrase`]}),H(`span`,{class:`muted small helper`,children:[`Tip: paste a whole phrase into word 1.`,Mt()?` Phrases in other scripts (Japanese, Chinese…) can only be pasted on phones.`:``]})]}),H(`ol`,{class:`word-grid`,"aria-label":`Seed words`,children:e.map((t,r)=>{let a=D(r),o=n.includes(r)&&l!==r;return H(`li`,{class:`word ${o?`word-invalid`:``}`,children:[H(`span`,{class:`word-index`,"aria-hidden":`true`,children:r+1}),H(`input`,{ref:e=>{e&&!h.current[r]&&e.type===`text`&&(e.type=`password`,e.type=`text`),h.current[r]=e},class:`input mono`,type:a?`text`:`password`,value:t,"aria-label":`Word ${r+1}`,"aria-invalid":o,list:g&&a?`bip39-words`:void 0,enterkeyhint:r===e.length-1?`done`:`next`,readOnly:i,onInput:e=>ee(r,e),onPaste:e=>b(r,e),onKeyDown:e=>S(r,e),onFocus:()=>u(r),onBlur:C,oncompositionend:e=>x(r,e.currentTarget),...Nt})]},r)})}),re.length>0&&H(`p`,{class:`hint`,role:`status`,children:[`Not in the wordlist. Did you mean:`,` `,re.map(e=>H(`button`,{type:`button`,class:`link-button`,onMouseDown:e=>e.preventDefault(),onClick:()=>te(l,e),children:e},e)),`?`]}),T&&!i&&H(`p`,{class:`hint`,children:[H(`button`,{type:`button`,class:`button small`,onClick:ne,children:`Expand abbreviated words`}),` `,H(`span`,{class:`muted small`,children:`Only for English BIP39 phrases.`})]}),p&&H(`p`,{class:`hint`,role:`status`,children:p})]})},rn=Object.fromEntries(Object.entries(J).map(([e,t])=>[e,t.label])),an={mnemonic:`Seed phrases`,privateKey:`Wallet keys`,sshKey:`SSH keys`,pgpKey:`PGP keys`,apiKey:`API keys and tokens`,genericKey:`Other keys`,recoveryCodes:`Recovery codes`,other:`Other secrets`},on={mnemonic:`seed`,privateKey:`wallet`,sshKey:`terminal`,pgpKey:`mail`,apiKey:`code`,genericKey:`key`,recoveryCodes:`list`,other:`lock`},sn=[[`none`,`No grouping`],[`kind`,`Type`],[`chain`,`Chain or service`],[`wallet`,`Wallet or account`],[`tag`,`First tag`]],cn=e=>`Untitled ${/^[A-Z][A-Z]/.test(e)?e:e.toLowerCase()}`,ln=e=>{let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleDateString(void 0,{year:`numeric`,month:`long`,day:`numeric`})},un=new Map([...`123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`].map((e,t)=>[e,BigInt(t)])),dn=e=>{let t=0n;for(let n of e){let e=un.get(n);if(e===void 0)return null;t=t*58n+e}let n=[];for(;t>0n;)n.unshift(Number(t%256n)),t/=256n;let r=0;for(;r{let t=dn(e);if(!t||t.length<5)return null;let n=t.slice(0,-4);return Ke((await We(await We(n))).slice(0,4),t.slice(-4))?n:null},pn=`qpzry9x8gf2tvdw0s3jn54khce6mua7l`,mn=1,hn=734539939,gn=e=>{let t=[996825010,642813549,513874426,1027748829,705979059],n=1;for(let r of e){let e=n>>>25;n=(n&33554431)<<5^r;for(let r=0;r<5;r++)e>>>r&1&&(n^=t[r])}return n>>>0},_n=e=>[...[...e].map(e=>e.charCodeAt(0)>>5),0,...[...e].map(e=>e.charCodeAt(0)&31)],vn=/^(nsec|npub|bc|tb|ltc|age|age-secret-key-)$|_x?[sv]k$|xprv|xpub|^addr|^stake/,yn=e=>{if(e!==e.toLowerCase()&&e!==e.toUpperCase())return null;let t=e.toLowerCase(),n=t.lastIndexOf(`1`);if(n<1||n+7>t.length)return null;let r=t.slice(0,n),i=[];for(let e of t.slice(n+1)){let t=pn.indexOf(e);if(t===-1)return null;i.push(t)}let a=gn([..._n(r),...i]),o=a===mn?`bech32`:a===hn?`bech32m`:null;return o?{hrp:r,variant:o,words:i.slice(0,-6)}:null},bn=e=>{let t=0,n=0,r=[];for(let i of e)for(t=t<<5|i,n+=5;n>=8;)n-=8,r.push(t>>n&255);return n>=5||t&(1<Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``),wn=e=>{let t;try{t=JSON.parse(e)}catch{return null}if(Array.isArray(t)&&t.length===0)return{level:`info`,label:`Empty list`};if(Array.isArray(t)&&t.every(e=>Number.isInteger(e)&&e>=0&&e<=255))return t.length===64?{level:`ok`,label:`Byte array, 64 bytes`,detail:`Solana CLI keypair file format.`}:{level:`info`,label:`Byte array, ${t.length} bytes`};if(t&&typeof t==`object`){let e=t;if(e.crypto&&Number(e.version)===4&&typeof e.pubkey==`string`)return{level:`ok`,label:`Encrypted keystore (EIP-2335, Ethereum validator)`,detail:`Store its password in the keystore password field.`};if((e.crypto||e.Crypto)&&Number(e.version)===3)return{level:`ok`,label:`Encrypted keystore (Web3 Secret Storage v3)`,detail:`Store its password in the keystore password field.`};if(e.type===`service_account`&&typeof e.private_key==`string`)return{level:`ok`,label:`Google Cloud service account key`,detail:`JSON key file with a private key.`};let n=Array.isArray(e.keys)?e.keys.filter(e=>e&&typeof e==`object`):[e],r=n.find(e=>`d`in e||`k`in e)??n[0];return r&&typeof r.kty==`string`?`d`in r||`k`in r?{level:`ok`,label:`JSON Web Key (${r.kty}, private)`}:{level:`warn`,label:`JSON Web Key (${r.kty}, public)`,detail:Q}:{level:`info`,label:`JSON document`}}return null},Tn={"ssh-ed25519":`Ed25519`,"ssh-rsa":`RSA`,"ssh-dss":`DSA`,"ecdsa-sha2-nistp256":`ECDSA P-256`,"ecdsa-sha2-nistp384":`ECDSA P-384`,"ecdsa-sha2-nistp521":`ECDSA P-521`,"sk-ssh-ed25519@openssh.com":`Ed25519 security key`,"sk-ecdsa-sha2-nistp256@openssh.com":`ECDSA security key`},En=e=>{let t;try{t=G(e.replace(/\s+/g,``))}catch{return null}if(ze(t.slice(0,15))!==`openssh-key-v1\0`)return null;let n=15,r=new DataView(t.buffer,t.byteOffset,t.byteLength),i=()=>{if(n+4>t.length)throw Error(`truncated`);let e=r.getUint32(n);if(n+=4,n+e>t.length)throw Error(`truncated`);let i=t.slice(n,n+e);return n+=e,i};try{let e=ze(i());i(),i(),n+=4;let t=i(),r=i(),a=new DataView(t.buffer,t.byteOffset).getUint32(0),o=ze(t.slice(4,4+a)),s=e!==`none`;if(!s){let e=new DataView(r.buffer,r.byteOffset,r.byteLength);if(r.length<8||e.getUint32(0)!==e.getUint32(4))return null}return{keyType:o,encrypted:s}}catch{return null}},Dn=e=>{let t=11994318;for(let n of e){t^=n<<16;for(let e=0;e<8;e++)t<<=1,t&16777216&&(t^=25578747)}return t&16777215},On=e=>{let t=e.split(/\r?\n/).map(e=>e.trim()),n=t.indexOf(``),r=t.slice(n===-1?1:n+1).filter(e=>e&&!e.startsWith(`-----`)),i=r.findIndex(e=>/^=[A-Za-z0-9+/]{4}$/.test(e));if(i===-1)return null;try{let e=G(r.slice(0,i).join(``)),t=G(r[i].slice(1));return Dn(e)===(t[0]<<16|t[1]<<8|t[2])}catch{return!1}},kn={"PUBLIC KEY":`PEM public key`,"RSA PUBLIC KEY":`PEM RSA public key`,CERTIFICATE:`Certificate`,"PGP PUBLIC KEY BLOCK":`PGP public key block`},An={"PGP MESSAGE":`PGP message`,"PGP SIGNATURE":`PGP signature`,"PGP SIGNED MESSAGE":`PGP signed message`},jn=e=>{if(e.includes(`:`))return null;let t;try{t=G(e.replace(/\s+/g,``))}catch{return!1}if(t.length<2||t[0]!==48)return!1;let n=t[1],r=2;if(n&128){let e=n&127;if(e<1||e>4||t.length<2+e)return!1;n=0;for(let r=0;r{let r=/Proc-Type:\s*4,ENCRYPTED/i.test(t);if(An[e])return{level:`warn`,label:An[e],detail:`This is not a key.`};if(kn[e])return{level:`warn`,label:kn[e],detail:Q};if(/PRIVATE KEY$/.test(e)&&e!==`OPENSSH PRIVATE KEY`&&jn(t)===!1)return{level:`error`,label:`Private key block is damaged or incomplete`,detail:`A line may be missing or changed.`};switch(e){case`OPENSSH PRIVATE KEY`:{let e=En(t);return e?{level:`ok`,label:`OpenSSH private key (${Tn[e.keyType]??e.keyType})`,detail:e.encrypted?`Protected by a passphrase.`:`Not passphrase-protected.`}:{level:`error`,label:`OpenSSH private key, but it could not be read`,detail:`Check that it was copied completely.`}}case`PGP PRIVATE KEY BLOCK`:{let e=On(n);return e===!1?{level:`error`,label:`PGP private key, but the checksum fails`,detail:`Check for a typo or missing line.`}:{level:`ok`,label:`PGP private key block`,detail:e?`Checksum OK.`:void 0}}case`RSA PRIVATE KEY`:return{level:`ok`,label:`PEM RSA private key (PKCS#1)`,detail:r?`Protected by a passphrase.`:void 0};case`EC PRIVATE KEY`:return{level:`ok`,label:`PEM EC private key (SEC1)`,detail:r?`Protected by a passphrase.`:void 0};case`DSA PRIVATE KEY`:return{level:`ok`,label:`PEM DSA private key`,detail:r?`Protected by a passphrase.`:void 0};case`PRIVATE KEY`:return{level:`ok`,label:`PEM private key (PKCS#8)`};case`ENCRYPTED PRIVATE KEY`:return{level:`ok`,label:`PEM private key (PKCS#8)`,detail:`Protected by a passphrase.`};default:return{level:`info`,label:`PEM block (${e.toLowerCase()})`}}},Nn=e=>/PRIVATE KEY/.test(e),Pn=e=>{let t=[...e.matchAll(/-----BEGIN ([A-Z0-9 ]+)-----([\s\S]*?)-----END \1-----/g)],n=(e.match(/-----BEGIN [A-Z0-9 ]+-----/g)??[]).length,r={level:`error`,label:`Key block is incomplete`,detail:`The matching -----END ...----- line is missing.`},i=t.find(e=>Nn(e[1]));if(i)return Mn(i[1],i[2],i[0]);let a=/-----BEGIN (PGP MESSAGE|PGP SIGNATURE|PGP SIGNED MESSAGE)-----/.exec(e);if(a)return{level:`warn`,label:An[a[1]],detail:`This is not a key.`};if(n>t.length)return r;if(!t.length)return null;let o=t.map(e=>Mn(e[1],e[2],e[0]));return o.find(e=>e.level===`warn`)??o[0]},Fn=[{pattern:/^gh[pousr]_[A-Za-z0-9]{36,}$/,label:`GitHub token`},{pattern:/^github_pat_\w{50,}$/,label:`GitHub fine-grained token`},{pattern:/^glpat-[\w-]{20,}$/,label:`GitLab access token`},{pattern:/^npm_[A-Za-z0-9]{36}$/,label:`npm access token`},{pattern:/^(sk|rk)_(live|test)_[A-Za-z0-9]{16,}$/,label:`Stripe secret key`},{pattern:/^pk_(live|test)_[A-Za-z0-9]{16,}$/,label:`Stripe publishable key`,level:`warn`,detail:Q},{pattern:/^xox[abposr]-[A-Za-z0-9-]{10,}$/,label:`Slack token`},{pattern:/^AIza[\w-]{35}$/,label:`Google API key`},{pattern:/^(AKIA|ASIA)[0-9A-Z]{16}$/,label:`AWS access key ID`,level:`info`,detail:`The 40-character secret access key is a separate value; store it as well.`},{pattern:/^SG\.[\w-]{22}\.[\w-]{43}$/,label:`SendGrid API key`},{pattern:/^dop_v1_[a-f0-9]{64}$/,label:`DigitalOcean token`},{pattern:/^sk-[\w-]{20,}$/,label:`API secret key (sk-…)`},{pattern:/^eyJ[\w-]+\.eyJ[\w-]+\.[\w-]*$/,label:`JSON Web Token`,level:`info`,detail:`Tokens like this usually expire.`}],In=async e=>{let t=e.trim();if(!t)return null;if(/^\[[\w .-]+\]\s*$/m.test(t.split(` +`)[0])&&/^\s*[\w.-]+\s*=/m.test(t))return/aws_secret_access_key\s*=/i.test(t)?{level:`ok`,label:`AWS credentials file`,detail:`Contains a secret access key.`}:{level:`info`,label:`Settings file (INI)`};if(t.startsWith(`{`)||t.startsWith(`[`))return wn(t)??{level:`warn`,label:`Looks like JSON, but it does not parse.`};let n=/^AGE-SECRET-KEY-1[0-9A-Z]+$/m.exec(t);if(n&&t.includes(` +`))return In(n[0]);if(/^---- BEGIN SSH2 PUBLIC KEY ----/m.test(t))return{level:`warn`,label:`SSH public key (SSH2 format)`,detail:Q};let r=Pn(t);if(r)return r;let i=/^PuTTY-User-Key-File-\d+:\s*(\S+)/.exec(t);if(i){let e=/^Private-Lines:\s*(\d+)\s*$/m.exec(t);if(e&&(t.slice(e.index+e[0].length).split(` +`).map(e=>e.trim()).filter(e=>e&&!/^Private-MAC:/.test(e)).filter(e=>/^[A-Za-z0-9+/=]+$/.test(e)).lengthe.pattern.test(t));if(o)return{level:o.level??`ok`,label:o.label,detail:o.detail};let s=Kt(t);if(s.length>=12&&s.length<=48&&s.every(Ht))return{level:`warn`,label:`Looks like a ${s.length}-word seed phrase`,detail:`Use a "Seed phrase" entry to get word-by-word checks.`};if(/^(0x)?[0-9a-fA-F]+$/i.test(t)&&t.replace(/^0x/i,``).length%2==0){let e=Ve(t.replace(/^0X/,`0x`)),n=/^0x/i.test(t);return e.length===32?{level:`ok`,label:`Hex, 32 bytes${n?` (0x-prefixed)`:``}`,detail:`Raw 256-bit private key (Ethereum/EVM, Bitcoin, Cosmos and others).`}:e.length===20?{level:`warn`,label:`Hex, 20 bytes`,detail:Q+` (EVM address length)`}:e.length===33||e.length===65?{level:`warn`,label:`Hex, ${e.length} bytes`,detail:Q+` (public key length)`}:{level:`info`,label:`Hex, ${e.length} bytes`}}let c=yn(t);if(c){let e=c.variant===`bech32`?bn(c.words):null;switch(c.hrp){case`age-secret-key-`:return e?.length===32?{level:`ok`,label:`age secret key`,detail:`Checksum OK.`}:{level:`error`,label:`age secret key with unexpected length`,detail:`Check that it was copied completely.`};case`age`:return{level:`warn`,label:`age recipient (public key)`,detail:Q};case`nsec`:return e?.length===32?{level:`ok`,label:`Nostr private key (nsec)`,detail:`Checksum OK.`}:{level:`error`,label:`nsec with unexpected length`};case`npub`:return{level:`warn`,label:`Nostr public key (npub)`,detail:Q};case`bc`:case`tb`:case`ltc`:return{level:`warn`,label:`Address (bech32)`,detail:Q};default:return/_x?sk$/.test(c.hrp)||c.hrp.includes(`xprv`)?{level:`ok`,label:`Bech32 secret key (${c.hrp})`,detail:`Checksum OK.`}:/_x?vk$/.test(c.hrp)||c.hrp.includes(`xpub`)||c.hrp.startsWith(`addr`)||c.hrp.startsWith(`stake`)?{level:`warn`,label:`Bech32 (${c.hrp})`,detail:Q}:{level:`info`,label:`Bech32 data (${c.hrp})`,detail:`Checksum OK.`}}}{let e=t.toLowerCase(),n=/^([a-z0-9_-]+)1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]{6,}$/.exec(e);if(n&&(t===e||t===t.toUpperCase())&&vn.test(n[1]))return{level:`error`,label:`Bech32 checksum fails`,detail:`Check for a typo.`}}if(/^[A-Za-z0-9+/]+={0,2}$/.test(t)&&t.length%4==0&&/[+/=]/.test(t))try{let e=G(t);return e.length===32?{level:`ok`,label:`Base64, 32 bytes`,detail:`The format of WireGuard keys and many other 256-bit keys.`}:{level:`info`,label:`Base64, ${e.length} bytes`}}catch{}if(t.length<=200&&/^[1-9A-HJ-NP-Za-km-z]+$/.test(t)){if(Ue()){let e=await fn(t);if(e){if(e.length===78){let t=xn[Cn(e.slice(0,4))];return t?t.private?{level:`ok`,label:`Extended private key (${t.name})`,detail:`${t.note}. Checksum OK.`}:{level:`warn`,label:`Extended public key (${t.name})`,detail:Q}:{level:`info`,label:`Extended key (unknown version)`,detail:`Checksum OK.`}}let t=Sn[e[0]];return t&&(e.length===33||e.length===34&&e[33]===1)?{level:`ok`,label:`WIF private key (${t}, ${e.length===34?`compressed`:`uncompressed`})`,detail:`Checksum OK.`}:e.length===21?{level:`warn`,label:`Address (Base58Check)`,detail:Q}:{level:`info`,label:`Base58Check, ${e.length} bytes`,detail:`Checksum OK.`}}let n=dn(t);if(n&&(n.length===37||n.length===38)&&Sn[n[0]])return{level:`error`,label:`Looks like WIF, but the checksum fails`,detail:`Check for a typo.`};if(/^[xyztuvYZUV](prv|pub)/.test(t)){if(t.length===111)return{level:`error`,label:`Looks like an extended key, but the checksum fails`,detail:`Check for a typo.`};if(t.length===110||t.length===112)return{level:`error`,label:`Looks like an extended key, but a character may be missing or extra`,detail:`Extended keys are 111 characters.`}}}let e=dn(t);if(e?.length===64)return{level:`ok`,label:`Base58, 64 bytes`,detail:`Solana-style keypair (Phantom/Solflare export).`};if(e?.length===32)return{level:`info`,label:`Base58, 32 bytes`,detail:`Could be an ed25519 secret seed, or a Solana address.`};if(e)return{level:`info`,label:`Base58, ${e.length} bytes`}}return{level:`info`,label:`Unrecognized format`,detail:`Stored as typed.`}},Ln=async e=>{let t=e.trim();if(!t)return null;if(/-----BEGIN [A-Z0-9 ]*PRIVATE KEY[A-Z0-9 ]*-----/.test(t))return`a private key block`;let n=t.split(/[\s,;()[\]]+/).map(e=>e.split(`/`)[0]).filter(e=>e.length>=40);for(let e of[t,...n]){let t=await In(e);if(t?.level===`ok`&&!/^(Hex|Base64)/.test(t.label))return t.label}return null},Rn=`Bitcoin.Ethereum.Solana.Cardano.Monero.Litecoin.Dogecoin.Polkadot.Cosmos.Avalanche.Polygon.BNB Chain.Arbitrum.Base.Optimism.Tron.XRP Ledger.Tezos.Algorand.Stellar.Near.Sui.Aptos.Lightning (LND).Nostr.Multi-chain`.split(`.`),zn=[`Ledger`,`Trezor`,`Coldcard`,`BitBox02`,`Keystone`,`Blockstream Jade`,`Foundation Passport`,`Sparrow`,`Electrum`,`Nunchuk`,`BlueWallet`,`Phoenix`,`MetaMask`,`Rabby`,`Rainbow`,`Phantom`,`Solflare`,`Exodus`,`Trust Wallet`,`Coinbase Wallet`,`Cake Wallet`,`Feather`,`Monero GUI`],Bn=[`GitHub`,`GitLab`,`Bitbucket`,`AWS`,`Google Cloud`,`Azure`,`Cloudflare`,`DigitalOcean`,`Vercel`,`Stripe`,`Slack`,`npm`,`Docker Hub`,`Apple ID`,`Google account`,`Microsoft account`,`Proton`,`Standard Notes`,`Coinbase`,`Kraken`,`Binance`,`Gemini`,`Bitstamp`],Vn=[[`m/44'/0'/0'`,`BTC legacy (BIP44)`],[`m/49'/0'/0'`,`BTC nested SegWit (BIP49)`],[`m/84'/0'/0'`,`BTC native SegWit (BIP84)`],[`m/86'/0'/0'`,`BTC Taproot (BIP86)`],[`m/48'/0'/0'/2'`,`BTC multisig (BIP48)`],[`m/44'/60'/0'/0/0`,`Ethereum / EVM`],[`m/44'/501'/0'/0'`,`Solana`],[`m/1852'/1815'/0'`,`Cardano`],[`m/44'/118'/0'/0/0`,`Cosmos`]],Hn=()=>H(C,{children:[H(`datalist`,{id:`chains`,children:Rn.map(e=>H(`option`,{value:e}))}),H(`datalist`,{id:`wallets`,children:zn.map(e=>H(`option`,{value:e}))}),H(`datalist`,{id:`services`,children:Bn.map(e=>H(`option`,{value:e}))}),H(`datalist`,{id:`paths`,children:Vn.map(([e,t])=>H(`option`,{value:e,label:t}))})]}),Un=(e,t,n=`${t}s`)=>`${e} ${e===1?t:n}`,$=({label:e,hint:t,children:n,wide:r,safety:i})=>H(`div`,{class:`field ${r?`field-wide`:``}`,children:[H(`label`,{class:`field-control`,children:[H(`span`,{class:`field-label`,children:e}),n]}),t&&H(`span`,{class:`hint ${i?`hint-safety`:``}`,children:t})]}),Wn=({id:e,title:t,icon:n,summary:r,defaultOpen:i,action:a,children:o})=>{let[s]=R(i),[c,l]=Ot(e,s),u=`section-${e.replace(/[^a-z0-9]/gi,`-`)}`;return H(`section`,{class:`section ${c?`open`:`closed`}`,children:[H(`header`,{class:`section-header`,children:[H(`h3`,{class:`section-heading`,children:H(`button`,{type:`button`,class:`section-toggle`,"aria-expanded":c,"aria-controls":u,onClick:()=>l(!c),children:[H(U,{name:`chevron`,size:14,class:`chevron`}),n&&H(U,{name:n}),H(`span`,{children:t}),!c&&r&&H(`span`,{class:`section-summary`,children:r})]})}),a&&H(`button`,{type:`button`,class:`button small`,onClick:()=>{a.onClick(),l(!0)},children:[H(U,{name:`plus`}),` `,a.label]})]}),c&&H(`div`,{class:`section-body`,id:u,children:o})]})},Gn={valid:`ok`,invalid:`error`,incomplete:`info`,unchecked:`info`},Kn=({entry:e,update:t,showLabel:n,focusLabel:r})=>{let{readOnly:i}=Z(),a=B(null);z(()=>{r&&a.current?.focus()},[]);let o=J[e.kind],s=Xe(e.kind),c=Tt(e),l=[e.description&&`description`,e.createdOn&&`created ${e.createdOn}`,e.expiresOn&&o.expires&&`expires ${e.expiresOn}`].filter(Boolean).join(` · `);return H(Wn,{id:`${e.id}:details`,title:`Details`,summary:l||`empty`,defaultOpen:!e.label,children:[n&&H($,{label:`Label`,wide:!0,children:H(`input`,{ref:a,class:`input`,value:e.label,placeholder:cn(rn[e.kind]),readOnly:i,onInput:e=>t({label:e.currentTarget.value})})}),H($,{label:`Description`,wide:!0,children:H(`textarea`,{class:`input`,rows:2,value:e.description,placeholder:`What is this wallet or key for?`,readOnly:i,onInput:e=>t({description:e.currentTarget.value}),...Nt,"data-secret":void 0})}),Xn(e,e.description)&&H(`p`,{class:`status status-error`,role:`status`,children:[H(U,{name:`alert`}),` This text repeats the entry's secret, and it is not hidden.`]}),H(`div`,{class:`row`,children:[s?H(C,{children:[H($,{label:o.serviceLabel,children:H(`input`,{class:`input`,list:`chains`,value:e.chain,readOnly:i,onInput:e=>t({chain:e.currentTarget.value})})}),H($,{label:o.accountLabel,children:H(`input`,{class:`input`,list:`wallets`,value:e.wallet,readOnly:i,onInput:e=>t({wallet:e.currentTarget.value})})})]}):H(C,{children:[H($,{label:o.serviceLabel,children:H(`input`,{class:`input`,list:`services`,value:e.service,readOnly:i,onInput:e=>t({service:e.currentTarget.value})})}),H($,{label:o.accountLabel,children:H(`input`,{class:`input`,value:e.account,readOnly:i,onInput:e=>t({account:e.currentTarget.value}),...Pt})})]}),H($,{label:`Date created`,children:H(`input`,{class:`input`,type:`date`,value:e.createdOn,readOnly:i,onInput:e=>t({createdOn:e.currentTarget.value})})}),o.expires&&H($,{label:`Expires on`,hint:c===null?`Optional. You are warned 30 days ahead.`:void 0,children:H(`input`,{class:`input`,type:`date`,value:e.expiresOn,readOnly:i,onInput:e=>t({expiresOn:e.currentTarget.value})})})]}),c!==null&&c<=30&&H(`p`,{class:`status ${c<0?`status-error`:`status-warn`}`,children:[H(U,{name:`clock`}),` `,c<0?`Expired on ${e.expiresOn}.`:c===0?`Expires today.`:`Expires in ${c} day${c===1?``:`s`}.`]}),H($,{label:`Tags`,hint:`Comma separated.`,wide:!0,children:H(ur,{tags:e.tags,onChange:e=>t({tags:e})})})]})},qn=({entry:e,update:t})=>{let{readOnly:n,confirm:r}=Z(),i=At(()=>$t(e.scheme,e.words),[e.scheme,e.words.join(` `)]),a=Lt.find(t=>t.id===e.scheme),o=[...new Set([...a.counts,...Rt])].sort((e,t)=>e-t),s=e.words.filter(Boolean).length,[c,l]=R(!1),u=async n=>{if(!Number.isInteger(n)||n<1||n>48||n===e.words.length)return!1;let i=e.words.slice(n).filter(Boolean).length;return i>0&&!await r({title:`Remove words?`,message:`Shrinking to ${n} words removes ${i} word${i===1?``:`s`} you entered.`,confirmLabel:`Remove`,danger:!0})?!1:(t({words:Array.from({length:n},(t,n)=>e.words[n]??``)}),!0)},d=n=>{let r=Lt.find(e=>e.id===n);s===0&&r.counts.length&&!r.counts.includes(e.words.length)?t({scheme:n,words:Array(r.counts[0]).fill(``)}):t({scheme:n})},f=`${a.label} · ${s===e.words.length?Un(s,`word`):`${s} of ${e.words.length} words`}${e.passphrase?` + passphrase`:``}`;return H(Wn,{id:`${e.id}:seed`,title:`Seed phrase`,icon:`seed`,summary:f,defaultOpen:!0,children:[H(`div`,{class:`row`,children:[H($,{label:`Scheme`,children:H(`select`,{class:`input`,value:e.scheme,disabled:n,onChange:e=>d(e.currentTarget.value),children:Lt.map(e=>H(`option`,{value:e.id,children:e.label}))})}),H($,{label:`Words`,children:H(`select`,{class:`input`,value:c||!o.includes(e.words.length)?`custom`:String(e.words.length),disabled:n,onChange:async t=>{let n=t.currentTarget,r=n.value;r===`custom`?l(!0):(l(!1),await u(Number(r))||(n.value=o.includes(e.words.length)?String(e.words.length):`custom`))},children:[o.map(e=>H(`option`,{value:String(e),children:[e,a.counts.includes(e)?``:` (non-standard)`]})),H(`option`,{value:`custom`,children:`Custom…`})]})}),(c||!o.includes(e.words.length))&&H($,{label:`Custom count`,children:H(`input`,{class:`input`,type:`number`,min:1,max:48,value:e.words.length,readOnly:n,onChange:e=>u(Number(e.currentTarget.value))})})]}),H(nn,{words:e.words,scheme:e.scheme,unknownWords:i?.unknownWords??[],onChange:e=>t({words:e})}),i&&H(`p`,{class:`status status-${Gn[i.status]}`,role:`status`,children:[H(U,{name:i.status===`valid`?`check`:i.status===`invalid`?`alert`:`shield`}),` `,i.message]}),H(Zn,{entry:e,update:t})]})},Jn=e=>setTimeout(()=>document.querySelector(`[data-row="${e}"] input`)?.focus()),Yn=e=>e.passphrase.length>=4&&e.passphraseHint.toLowerCase().includes(e.passphrase.toLowerCase()),Xn=(e,t)=>{let n=t.toLowerCase();if(!n)return!1;if(e.secret.trim().length>=12&&n.includes(e.secret.trim().toLowerCase()))return!0;let r=e.words.filter(Boolean).map(e=>e.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g,`\\$&`));for(let e=0;e+4<=r.length;e++)if(RegExp(`\\b${r.slice(e,e+4).join(`\\s+`)}\\b`).test(n))return!0;return!1},Zn=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=J[e.kind];return r.passphraseLabel?H(`div`,{class:`row`,children:[H($,{label:r.passphraseLabel,hint:r.passphraseHint,safety:!0,children:H(Ft,{label:r.passphraseLabel,value:e.passphrase,onInput:e=>t({passphrase:e}),placeholder:`None`})}),H($,{label:`Passphrase hint`,hint:`Not hidden. Never write the passphrase itself here.`,safety:!0,children:H(`input`,{class:`input`,value:e.passphraseHint,readOnly:n,onInput:e=>t({passphraseHint:e.currentTarget.value}),...Pt})}),Yn(e)&&H(`p`,{class:`status status-error field-wide`,role:`status`,children:[H(U,{name:`alert`}),` The hint contains the passphrase. Anyone who opens this note can read it.`]})]}):null},Qn={ok:`ok`,info:`info`,warn:`warn`,error:`error`},$n=({entry:e,update:t})=>{let n=J[e.kind],r=At(()=>In(e.secret),[e.secret]);return H(Wn,{id:`${e.id}:key`,title:n.secretLabel,icon:`key`,summary:e.secret?r?.label??`set`:`empty`,defaultOpen:!0,children:[H($,{label:n.secretLabel,wide:!0,children:H(Ft,{label:n.secretLabel,value:e.secret,onInput:e=>t({secret:e}),placeholder:n.secretPlaceholder,multiline:n.secret===`key`&&(e.kind!==`privateKey`||e.secret.includes(` +`)),onMultilinePaste:e=>t({secret:e}),mono:!0})}),H(`p`,{class:`status ${r?`status-${Qn[r.level]}`:``}`,role:`status`,children:r&&H(C,{children:[H(U,{name:r.level===`ok`?`check`:r.level===`info`?`shield`:`alert`}),` `,r.label,r.detail&&H(`span`,{class:`muted`,children:[` · `,r.detail]})]})}),H(Zn,{entry:e,update:t})]})},er=({entry:e,update:t})=>{let n=e.secret.split(/\n/).filter(e=>e.trim()).length;return H(Wn,{id:`${e.id}:codes`,title:`Recovery codes`,icon:`list`,summary:n?`${n} code${n===1?``:`s`}`:`empty`,defaultOpen:!0,children:H($,{label:`Codes`,hint:`One per line. Delete or mark a code once used.`,wide:!0,children:H(Ft,{label:`Recovery codes`,value:e.secret,onInput:e=>t({secret:e}),placeholder:`One code per line`,multiline:!0,mono:!0})})})},tr=({text:e})=>{let t=At(()=>Ln(e),[e]);return t?H(`p`,{class:`status status-error`,role:`status`,children:[H(U,{name:`alert`}),` This looks like private key material (`,t,`). This field is not hidden: move it to the secret field.`]}):null},nr=(e,t)=>{let n=e.trim();return t&&(n=n.replace(/^\[([0-9a-fA-F]{8})[^\]]*\].*$/,`$1`).replace(/^0x/i,``).replace(/\s+/g,``)),n},rr=e=>e.trim().replace(/[’‘′`]/g,`'`).replace(/^M\//,`m/`),ir=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=J[e.kind].publicKey;if(!r)return null;let i=At(()=>Ln(e.fingerprint),[e.fingerprint]),a=[e.publicInfo&&`public key`,e.fingerprint&&(i?`fingerprint`:e.fingerprint)].filter(Boolean).join(` · `),o=e.kind===`pgpKey`&&e.fingerprint&&!/^([0-9a-fA-F]{40}|[0-9a-fA-F]{64})$/.test(e.fingerprint.replace(/\s/g,``));return H(Wn,{id:`${e.id}:public`,title:`Public info`,icon:`eye`,summary:a||`empty`,defaultOpen:!1,children:[H(`p`,{class:`muted small helper`,children:`Not secret. Lets you match this entry to a server, keyring or recipient.`}),H($,{label:r.label,wide:!0,children:H(`textarea`,{class:`input mono`,rows:e.publicInfo?3:2,value:e.publicInfo,placeholder:r.placeholder,readOnly:n,onInput:e=>t({publicInfo:e.currentTarget.value}),...Pt})}),H(tr,{text:e.publicInfo}),H($,{label:r.fingerprintLabel,wide:!0,children:H(`input`,{class:`input mono`,value:e.fingerprint,placeholder:r.fingerprintPlaceholder,readOnly:n,onInput:e=>t({fingerprint:e.currentTarget.value}),onBlur:n=>{let r=nr(n.currentTarget.value,!1);r!==e.fingerprint&&t({fingerprint:r})},...Pt})}),H(tr,{text:e.fingerprint}),o&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` PGP fingerprints are 40 hex characters (64 for newer v6 keys).`]})]})},ar=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=!!(e.derivationPath||e.fingerprint||e.publicInfo),i=At(()=>Ln(e.fingerprint),[e.fingerprint]),a=[e.derivationPath,e.fingerprint&&(i?`fingerprint`:e.fingerprint),e.publicInfo&&`addresses`].filter(Boolean).join(` · `),o=e.derivationPath.trim();return H(Wn,{id:`${e.id}:public`,title:`Public info`,icon:`eye`,summary:a||`empty`,defaultOpen:!1,children:[H(`p`,{class:`muted small helper`,children:`Not secret. Helps you recognize the wallet without revealing the secret.`}),H(`div`,{class:`row`,children:[H($,{label:`Derivation path`,children:H(`input`,{class:`input mono`,list:`paths`,value:e.derivationPath,placeholder:`m/84'/0'/0'`,readOnly:n,onInput:e=>t({derivationPath:e.currentTarget.value}),onBlur:n=>{let r=rr(n.currentTarget.value);r!==e.derivationPath&&t({derivationPath:r})},...Pt})}),H($,{label:`Master fingerprint`,children:H(`input`,{class:`input mono`,value:e.fingerprint,placeholder:`e.g. 73c5da0a`,readOnly:n,onInput:e=>t({fingerprint:e.currentTarget.value}),onBlur:n=>{let r=nr(n.currentTarget.value,!0);r!==e.fingerprint&&t({fingerprint:r})},...Pt})})]}),o&&!/^m(\/\d+['hH]?)*$/.test(o)&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` `,/[’‘′`]/.test(o)?`Use straight apostrophes (') in derivation paths; curly ones are fixed when you leave the field.`:`Derivation paths look like m/84'/0'/0'.`]}),e.fingerprint&&!i&&!/^[0-9a-fA-F]{8}$/.test(e.fingerprint.trim())&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` A master fingerprint is 8 hex characters.`]}),H($,{label:`Addresses / xpub`,wide:!0,children:H(`textarea`,{class:`input mono`,rows:r?3:2,value:e.publicInfo,placeholder:`First receive address, xpub/zpub…`,readOnly:n,onInput:e=>t({publicInfo:e.currentTarget.value}),...Pt})}),H(tr,{text:e.publicInfo}),H(tr,{text:e.fingerprint})]})},or=({entry:e,update:t,reminderMonths:n})=>{let{readOnly:r}=Z(),i=(n,r)=>t({backups:e.backups.map(e=>e.id===n?{...e,...r}:e)}),a=wt(e,n),o=Ct(e),s=H(`span`,{class:a?`status-warn`:void 0,children:[e.backups.length?Un(e.backups.length,`location`):`none recorded`,o?` · checked ${o}`:``,a?` · check due`:``]});return H(Wn,{id:`${e.id}:backups`,title:`Backups`,icon:`shield`,summary:s,defaultOpen:!1,action:r?void 0:{label:`Add location`,onClick:()=>{let n=qe();t({backups:[...e.backups,{id:n,location:``,verifiedOn:``}]}),Jn(n)}},children:[H(`p`,{class:`status ${a?`status-warn`:`status-info`}`,children:[H(U,{name:a?`alert`:`check`}),` `,o?`Last checked ${o}.`:`No backup check recorded.`,a&&n>0&&` Check your backups at least every ${n} months.`]}),e.backups.length===0&&H(`p`,{class:`muted small helper`,children:`Record where copies are kept, like "steel plate in home safe". Do not record the secret itself here.`}),e.backups.map(n=>H(`div`,{class:`row backup-row`,"data-row":n.id,children:[H(`input`,{class:`input grow`,value:n.location,placeholder:`Location, e.g. steel plate in safe`,"aria-label":`Backup location`,readOnly:r,onInput:e=>i(n.id,{location:e.currentTarget.value}),...Pt}),H(`input`,{class:`input`,type:`date`,value:n.verifiedOn,"aria-label":`Last checked`,readOnly:r,onInput:e=>i(n.id,{verifiedOn:e.currentTarget.value})}),!r&&H(C,{children:[H(`button`,{type:`button`,class:`button small`,onClick:()=>i(n.id,{verifiedOn:nt()}),children:`Checked today`}),H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Remove backup location`,title:`Remove`,onClick:()=>t({backups:e.backups.filter(e=>e.id!==n.id)}),children:H(U,{name:`x`})})]})]},n.id))]})},sr=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=(n,r)=>t({customFields:e.customFields.map(e=>e.id===n?{...e,...r}:e)}),i=J[e.kind].secret===`fields`;return H(Wn,{id:`${e.id}:fields`,title:i?`Fields`:`Extra fields`,icon:`plus`,summary:e.customFields.length?Un(e.customFields.length,`field`):`none`,defaultOpen:i,action:n?void 0:{label:`Add field`,onClick:()=>{let n=qe();t({customFields:[...e.customFields,{id:n,label:``,value:``,hidden:!0}]}),Jn(n)}},children:[e.customFields.length===0&&H(`p`,{class:`muted small helper`,children:`For PINs, keystore passwords, 2FA backup codes, multisig details or anything else.`}),e.customFields.map(i=>H(`div`,{class:`custom-field`,"data-row":i.id,children:[H(`input`,{class:`input custom-label`,value:i.label,placeholder:`Label`,"aria-label":`Field label`,readOnly:n,onInput:e=>r(i.id,{label:e.currentTarget.value})}),H(`div`,{class:`custom-value`,children:i.hidden?H(Ft,{label:i.label||`Field`,value:i.value,multiline:i.multiline,onInput:e=>r(i.id,{value:e}),onMultilinePaste:e=>r(i.id,{value:e,multiline:!0})}):i.multiline?H(`textarea`,{class:`input`,rows:3,value:i.value,"aria-label":i.label||`Field value`,readOnly:n,onInput:e=>r(i.id,{value:e.currentTarget.value}),...Pt}):H(`input`,{class:`input`,value:i.value,"aria-label":i.label||`Field value`,readOnly:n,onInput:e=>r(i.id,{value:e.currentTarget.value}),...Pt,onPaste:e=>{let t=e.clipboardData?.getData(`text`)??``;if(!/[\r\n]/.test(t))return;e.preventDefault();let n=e.currentTarget,a=n.selectionStart??i.value.length,o=n.selectionEnd??i.value.length;r(i.id,{value:i.value.slice(0,a)+t+i.value.slice(o),multiline:!0})}})}),!n&&H(`div`,{class:`custom-actions`,children:[H(`label`,{class:`check small`,children:[H(`input`,{type:`checkbox`,checked:i.hidden,"aria-label":`Hide ${i.label||`field`} value`,onChange:e=>r(i.id,{hidden:e.currentTarget.checked})}),` `,`Hidden`]}),H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Remove field`,title:`Remove`,onClick:()=>t({customFields:e.customFields.filter(e=>e.id!==i.id)}),children:H(U,{name:`x`})})]})]},i.id))]})},cr=({entry:e,update:t})=>{let{readOnly:n}=Z();return H(Wn,{id:`${e.id}:notes`,title:`Notes`,summary:e.notes?Un(e.notes.length,`character`):`empty`,defaultOpen:!!e.notes&&e.kind===`other`,children:[H(`textarea`,{class:`input`,rows:4,value:e.notes,placeholder:`Recovery instructions, inheritance notes, history…`,"aria-label":`Notes`,readOnly:n,onInput:e=>t({notes:e.currentTarget.value}),...Nt}),Xn(e,e.notes)&&H(`p`,{class:`status status-error`,role:`status`,children:[H(U,{name:`alert`}),` This text repeats the entry's secret, and it is not hidden.`]})]})},lr=e=>{let t=new Set;return e.split(`,`).map(e=>e.trim()).filter(e=>e&&!t.has(e.toLowerCase())&&t.add(e.toLowerCase()))},ur=({tags:e,onChange:t})=>{let{readOnly:n}=Z(),[r,i]=R(e.join(`, `));z(()=>{lr(r).join(`,`)!==e.join(`,`)&&i(e.join(`, `))},[e.join(`,`)]);let a=n=>{i(n);let r=lr(n);r.join(`,`)!==e.join(`,`)&&t(r)},o=()=>i(lr(r).join(`, `));return H(`input`,{class:`input`,value:r,placeholder:`cold storage, inheritance`,readOnly:n,onInput:e=>a(e.currentTarget.value),onBlur:o,onKeyDown:e=>e.key===`Enter`&&o()})},dr=({entry:e,onUpdate:t,onDelete:n,onDuplicate:r})=>{let{readOnly:i}=Z();return i?null:H(`div`,{class:`entry-actions`,children:[H(`button`,{type:`button`,class:`icon-button ${e.favorite?`active`:``}`,"aria-pressed":e.favorite,"aria-label":`Favorite`,title:`Favorite`,disabled:i,onClick:()=>t({favorite:!e.favorite}),children:H(U,{name:`star`,fill:e.favorite?`currentColor`:`none`})}),!i&&H(C,{children:[H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Duplicate`,title:`Duplicate`,onClick:r,children:H(U,{name:`duplicate`})}),H(`button`,{type:`button`,class:`icon-button ${e.archived?`active`:``}`,"aria-label":e.archived?`Unarchive`:`Archive`,title:e.archived?`Unarchive`:`Archive (e.g. an emptied or retired wallet)`,onClick:()=>t({archived:!e.archived}),children:H(U,{name:`archive`})}),H(`button`,{type:`button`,class:`icon-button danger`,"aria-label":`Delete`,title:`Delete`,onClick:n,children:H(U,{name:`trash`})})]})]})},fr=e=>{let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString()},pr=({entry:e,reminderMonths:t,onUpdate:n,showLabel:r,focusLabel:i=!1})=>{let{readOnly:a}=Z(),o=e=>!a&&n(e),s=J[e.kind].secret;return H(`div`,{class:`entry-body`,children:[H(Kn,{entry:e,update:o,showLabel:r,focusLabel:i}),s===`words`&&H(qn,{entry:e,update:o}),(s===`key`||s===`token`)&&H($n,{entry:e,update:o}),s===`codes`&&H(er,{entry:e,update:o}),s===`fields`&&H(sr,{entry:e,update:o}),Xe(e.kind)?H(ar,{entry:e,update:o}):H(ir,{entry:e,update:o}),s!==`fields`&&H(sr,{entry:e,update:o}),H(or,{entry:e,update:o,reminderMonths:t}),H(cr,{entry:e,update:o}),H(`footer`,{class:`editor-footer muted small`,children:[`Added `,fr(e.addedAt),` · Updated `,fr(e.updatedAt)]})]})},mr=({entry:e,reminderMonths:t,onUpdate:n,onDelete:r,onDuplicate:i,onBack:a,focusLabel:o})=>{let{readOnly:s}=Z(),c=B(null);return z(()=>{o&&c.current?.focus()},[]),H(`article`,{class:`editor`,"aria-label":e.label||`Untitled entry`,children:[H(`header`,{class:`editor-header`,children:[H(`button`,{type:`button`,class:`icon-button back-button`,"aria-label":`Back to list`,title:`Back`,onClick:a,children:H(U,{name:`back`})}),H(`input`,{ref:c,class:`input title-input`,value:e.label,placeholder:cn(rn[e.kind]),"aria-label":`Label`,readOnly:s,onInput:e=>!s&&n({label:e.currentTarget.value})}),H(`span`,{class:`badge badge-${e.kind}`,children:rn[e.kind]}),H(dr,{entry:e,onUpdate:n,onDelete:r,onDuplicate:i})]}),H(`div`,{class:`editor-body`,children:H(pr,{entry:e,reminderMonths:t,onUpdate:n,showLabel:!1})})]})},hr=[[`all`,`All`],[`crypto`,`Crypto`],...Je.map(e=>[e,an[e]]),[`favorites`,`Favorites`],[`attention`,`Backup check due`],[`expiring`,`Expiring or expired`],[`archived`,`Archived`]],gr=new Intl.Collator(void 0,{numeric:!0,sensitivity:`base`}),_r=(e,t)=>{if(!t)return!0;let n=[e.label,e.description,e.chain,e.wallet,e.service,e.account,e.notes,e.derivationPath,e.fingerprint,e.publicInfo,...e.tags,...e.customFields.flatMap(e=>e.hidden?[e.label]:[e.label,e.value]),...e.backups.map(e=>e.location)].join(` `).toLowerCase();return t.toLowerCase().split(/\s+/).every(e=>n.includes(e))},vr=(e,t,n,r,i)=>e.filter(e=>t===`archived`?e.archived:!e.archived).filter(e=>{switch(t){case`all`:case`archived`:return!0;case`crypto`:return Xe(e.kind);case`favorites`:return e.favorite;case`attention`:return wt(e,i);case`expiring`:return Et(e);default:return e.kind===t}}).filter(e=>_r(e,r.trim())).sort((e,t)=>e.favorite===t.favorite?n===`label`?!e.label==!t.label?gr.compare(e.label,t.label):e.label?-1:1:n===`created`?(t.createdOn||``).localeCompare(e.createdOn||``):t.updatedAt.localeCompare(e.updatedAt):e.favorite?-1:1),yr=Je,br={none:``,kind:``,chain:`No chain or service`,wallet:`No wallet or account`,tag:`Untagged`},xr=(e,t)=>{if(t===`none`)return[{key:`all`,label:``,entries:e}];let n=e=>t===`kind`?e.kind:t===`chain`?(e.chain||e.service).trim():t===`wallet`?(e.wallet||e.account).trim():(e.tags[0]??``).trim(),r=new Map;for(let i of e){let e=n(i),a=`${t}:${e.toLowerCase()}`,o=r.get(a);o||(o={key:a,label:t===`kind`?an[e]:e||br[t],entries:[]},r.set(a,o)),o.entries.push(i)}let i=[...r.values()];if(t===`kind`)return i.sort((e,t)=>yr.indexOf(e.entries[0].kind)-yr.indexOf(t.entries[0].kind));let a=e=>e.key.endsWith(`:`);return i.sort((e,t)=>Number(a(e))-Number(a(t))||gr.compare(e.label,t.label))},Sr=e=>({order:e.flatMap(e=>e.entries.map(e=>e.id)),groupOf:new Map(e.flatMap(e=>e.entries.map(t=>[t.id,e.key]))),labelOf:new Map(e.map(e=>[e.key,e.label]))}),Cr=(e,t)=>{let n=new Map(t.order.map((e,t)=>[e,t])),r=new Map(e.flatMap(e=>e.entries.map(t=>[t.id,e.key]))),i=new Map(e.map(e=>[e.key,e.label])),a=e.flatMap(e=>e.entries).sort((e,t)=>(n.get(e.id)??-1)-(n.get(t.id)??-1)),o=new Map;for(let e of a){let n=t.groupOf.get(e.id)??r.get(e.id),a=o.get(n);a||(a={key:n,label:t.labelOf.get(n)??i.get(n)??``,entries:[]},o.set(n,a)),a.entries.push(e)}return[...new Set([...t.labelOf.keys(),...e.map(e=>e.key)])].flatMap(e=>o.get(e)??[])},wr=({entry:e})=>{let t=At(()=>$t(e.scheme,e.words),[e.scheme,e.words.join(` `)]);return!t||t.status===`incomplete`||t.status===`unchecked`?null:t.status===`valid`?H(`span`,{class:`pill pill-ok`,title:t.message,children:[H(U,{name:`check`,size:12}),` checksum`]}):H(`span`,{class:`pill pill-error`,title:t.message,children:[H(U,{name:`alert`,size:12}),` check words`]})},Tr=({entry:e})=>{let t=Tt(e);return t===null||!Et(e)?null:t<0?H(`span`,{class:`pill pill-error`,title:`Expired ${e.expiresOn}`,children:`expired`}):H(`span`,{class:`pill pill-warn`,title:`Expires ${e.expiresOn}`,children:t===0?`expires today`:`expires in ${t} day${t===1?``:`s`}`})},Er=({entry:e,reminderMonths:t,idPrefix:n})=>{let r=(Xe(e.kind)?[e.chain,e.wallet,e.kind===`mnemonic`?`${e.words.length} words`:``]:[rn[e.kind],e.service,e.account]).filter(Boolean).join(` · `);return H(C,{children:[H(`span`,{class:`entry-icon badge-${e.kind}`,title:rn[e.kind],children:H(U,{name:on[e.kind]})}),H(`span`,{class:`entry-main`,children:[H(`span`,{class:`entry-title`,id:n&&`${n}-title`,children:[e.favorite&&H(U,{name:`star`,size:12,fill:`currentColor`,class:`star`}),e.label||H(`em`,{class:`muted`,children:cn(rn[e.kind])})]}),r&&H(`span`,{class:`entry-meta`,id:n&&`${n}-meta`,children:r}),H(`span`,{class:`entry-pills`,id:n&&`${n}-pills`,children:[e.kind===`mnemonic`&&H(wr,{entry:e}),e.passphrase&&H(`span`,{class:`pill`,children:`+ passphrase`}),e.archived&&H(`span`,{class:`pill`,children:`archived`}),H(Tr,{entry:e}),wt(e,t)&&H(`span`,{class:`pill pill-warn`,children:e.backups.length?`backup check due`:`no backup recorded`}),e.tags.map(e=>H(`span`,{class:`pill`,children:e},e))]})]}),e.createdOn&&H(`span`,{class:`entry-date`,children:e.createdOn})]})},Dr=({group:e,bare:t,collapsed:n,onToggle:r,children:i})=>{let a=`group-${e.key.replace(/[^a-z0-9]/gi,`-`)}`;return!e.label||t?H(`section`,{class:`group bare`,children:H(`div`,{id:a,children:i})}):H(`section`,{class:`group ${n?`collapsed`:``}`,children:[H(`h2`,{class:`group-heading`,children:H(`button`,{type:`button`,class:`group-toggle`,"aria-expanded":!n,"aria-controls":a,onClick:r,children:[H(U,{name:`chevron`,size:14,class:`chevron`}),H(`span`,{children:e.label}),H(`span`,{class:`count`,children:e.entries.length})]})}),!n&&H(`div`,{id:a,children:i})]})},Or=({groups:e,collapsedGroups:t,selectedId:n,reminderMonths:r,onSelect:i,onToggleGroup:a})=>H(`div`,{class:`entry-list`,children:e.map(o=>H(Dr,{group:o,bare:e.length===1,collapsed:t.has(o.key)&&e.length>1,onToggle:()=>a(o.key),children:H(`ul`,{class:`entry-rows`,"aria-label":o.label||`Entries`,children:o.entries.map(e=>H(`li`,{children:H(`button`,{type:`button`,class:`entry-item ${e.id===n?`selected`:``}`,"aria-current":e.id===n,onClick:()=>i(e.id),children:H(Er,{entry:e,reminderMonths:r})})},e.id))})},o.key))}),kr=(e,t)=>{let n=Object.keys(e);return n.length===Object.keys(t).length&&n.every(n=>Object.is(e[n],t[n]))},Ar=(e=>class extends te{shouldComponentUpdate(e){return!kr(this.props,e)}render(t){return x(e,t)}})(({entry:e,open:t,reminderMonths:n,isNew:r,onToggle:i,...a})=>{let o=B(null);z(()=>{r&&o.current?.scrollIntoView({block:`nearest`})},[r]);let s=`entry-${e.id}`;return H(`li`,{ref:o,class:`card-entry ${t?`open`:``}`,children:[H(`div`,{class:`card-header`,children:[H(`button`,{type:`button`,class:`card-toggle`,"aria-expanded":t,"aria-controls":s,"aria-labelledby":`${s}-title`,"aria-describedby":`${s}-meta ${s}-pills`,onClick:()=>i(e.id),children:[H(U,{name:`chevron`,size:14,class:`chevron`}),H(Er,{entry:e,reminderMonths:n,idPrefix:s})]}),t&&H(dr,{entry:e,...a})]}),t&&H(`div`,{class:`card-body`,id:s,children:H(pr,{entry:e,reminderMonths:n,onUpdate:a.onUpdate,showLabel:!0,focusLabel:r})})]})}),jr=({groups:e,expanded:t,collapsedGroups:n,reminderMonths:r,newId:i,onToggle:a,onToggleGroup:o,handlersFor:s})=>H(`div`,{class:`stack`,children:e.map(c=>H(Dr,{group:c,bare:e.length===1,collapsed:n.has(c.key)&&e.length>1,onToggle:()=>o(c.key),children:H(`ul`,{class:`cards`,"aria-label":c.label||`Entries`,children:c.entries.map(e=>H(Ar,{entry:e,open:t.has(e.id),reminderMonths:r,isNew:e.id===i,onToggle:a,...s(e.id)},e.id))})},c.key))}),Mr=({label:e,icon:t,kind:n,buttonClass:r=`button small`,children:i})=>{let[a,o]=R(!1),s=B(null),c=B(null);return z(()=>{if(!a)return;let e=e=>{s.current?.contains(e.target)||o(!1)};return document.addEventListener(`pointerdown`,e),()=>document.removeEventListener(`pointerdown`,e)},[a]),H(`div`,{class:`popover-wrap`,ref:s,onKeyDown:e=>{e.key===`Escape`&&a&&(e.stopPropagation(),o(!1),c.current?.focus())},onFocusOut:e=>{let t=e.relatedTarget;t&&!s.current?.contains(t)&&o(!1)},children:[H(`button`,{type:`button`,ref:c,class:r,"aria-expanded":a,"aria-label":e,title:e,onClick:()=>o(!a),children:[H(U,{name:t}),` `,H(`span`,{class:`button-text`,children:e})]}),a&&H(`div`,{class:`popover popover-${n}`,children:i(()=>o(!1))})]})},Nr=[`crypto`,`keys`,`secrets`],Pr=({icon:e,label:t,onClick:n,disabled:r})=>H(`button`,{type:`button`,class:`button small`,"aria-label":t,title:t,onClick:n,disabled:r,children:[H(U,{name:e}),` `,H(`span`,{class:`button-text`,children:t})]}),Fr=e=>{let t=e.view.layout===`stacked`;return H(`div`,{class:`toolbar`,children:[H(`div`,{class:`toolbar-row`,children:[H(`div`,{class:`search`,children:[H(U,{name:`search`}),H(`input`,{class:`input`,type:`search`,placeholder:`Search labels, tags, notes`,"aria-label":`Search`,value:e.query,onInput:t=>e.onQuery(t.currentTarget.value),spellcheck:!1})]}),H(`select`,{class:`input`,"aria-label":`Filter`,value:e.filter,onChange:t=>e.onFilter(t.currentTarget.value),children:hr.map(([t,n])=>H(`option`,{value:t,children:[n,t===`attention`&&e.dueCount?` (${e.dueCount})`:``]}))}),!e.readOnly&&H(Mr,{label:`Add`,icon:`plus`,kind:`menu`,buttonClass:`button small primary`,children:t=>Nr.map(n=>H(`div`,{role:`group`,"aria-label":Ye[n],class:`menu-group`,children:[H(`div`,{class:`menu-heading`,"aria-hidden":`true`,children:Ye[n]}),Je.filter(e=>J[e].group===n).map(n=>H(`button`,{type:`button`,class:`menu-item`,onClick:()=>{t(),e.onAdd(n)},children:[H(U,{name:on[n]}),` `,rn[n]]}))]}))})]}),H(`div`,{class:`toolbar-row`,children:[H(`span`,{class:`muted small count`,role:`status`,children:e.shown===e.total?`${e.total} ${e.total===1?`entry`:`entries`}`:`${e.shown} of ${e.total} entries`}),H(`span`,{class:`spacer`}),t&&H(C,{children:[H(Pr,{icon:`expand`,label:`Expand all`,onClick:e.onExpandAll,disabled:e.view.singleExpand||e.shown===0}),H(Pr,{icon:`collapse`,label:`Collapse all`,onClick:e.onCollapseAll,disabled:e.shown===0})]}),H(Mr,{label:`View`,icon:`sliders`,kind:`dialog`,children:()=>H(`div`,{class:`view-options`,children:[H(`fieldset`,{children:[H(`legend`,{children:`Layout`}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`layout`,checked:t,onChange:()=>e.onView({layout:`stacked`})}),` Expandable cards`]}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`layout`,checked:!t,onChange:()=>e.onView({layout:`split`})}),` List + editor side by side`]})]}),H(`fieldset`,{children:[H(`legend`,{children:`Density`}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`density`,checked:e.view.density===`comfortable`,onChange:()=>e.onView({density:`comfortable`})}),` `,`Comfortable`]}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`density`,checked:e.view.density===`compact`,onChange:()=>e.onView({density:`compact`})}),` Compact`]})]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Group by`}),H(`select`,{class:`input`,value:e.view.groupBy,onChange:t=>e.onView({groupBy:t.currentTarget.value}),children:sn.map(([e,t])=>H(`option`,{value:e,children:t}))})]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Sort`}),H(`select`,{class:`input`,value:e.view.sort,onChange:t=>e.onView({sort:t.currentTarget.value}),children:[H(`option`,{value:`updated`,children:`Recently updated`}),H(`option`,{value:`label`,children:`Label`}),H(`option`,{value:`created`,children:`Date created`})]})]}),t&&H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:e.view.singleExpand,onChange:t=>e.onView({singleExpand:t.currentTarget.checked})}),` Open one entry at a time`]})]})}),H(Pr,{icon:`settings`,label:`Settings`,onClick:e.onSettings}),e.hasPassword&&H(Pr,{icon:`lock`,label:`Lock`,onClick:e.onLock}),H(Pr,{icon:`eyeOff`,label:`Hide all`,onClick:e.onHideAll})]})]})},Ir=6e5,Lr=16,Rr=12,zr=Ue,Br=1,Vr=e=>W(`${Ze}|${Br}|PBKDF2-SHA256|${e}|AES-256-GCM`),Hr=async(e,t=q(Lr),n=Ir)=>{let r=await crypto.subtle.importKey(`raw`,K(W(e.normalize(`NFC`))),`PBKDF2`,!1,[`deriveKey`]);return{key:await crypto.subtle.deriveKey({name:`PBKDF2`,hash:`SHA-256`,salt:K(t),iterations:n},r,{name:`AES-GCM`,length:256},!1,[`encrypt`,`decrypt`]),salt:t,iterations:n}},Ur=async(e,t)=>{let n=q(Rr),r=await crypto.subtle.encrypt({name:`AES-GCM`,iv:K(n),additionalData:K(Vr(t.iterations))},t.key,K(W(JSON.stringify(e))));return{kdf:`PBKDF2-SHA256`,iterations:t.iterations,salt:He(t.salt),cipher:`AES-256-GCM`,iv:He(n),ciphertext:He(new Uint8Array(r))}},Wr=class extends Error{constructor(){super(`Wrong password, or the vault data is damaged.`)}},Gr=class extends Error{constructor(){super(`The vault data in this note is damaged. Restore an earlier version from note history.`)}},Kr=e=>{try{return G(e)}catch{throw new Gr}},qr=class extends Error{constructor(){super(`This browser cannot decrypt vaults here: encryption needs a secure (https) page. Open the note in the Standard Notes app or at app.standardnotes.com.`)}},Jr=async(e,t)=>{let n=Kr(e.iv),r=Kr(e.ciphertext),i;try{i=await crypto.subtle.decrypt({name:`AES-GCM`,iv:K(n),additionalData:K(Vr(e.iterations))},t.key,K(r))}catch{throw new Wr}try{return _t(JSON.parse(ze(new Uint8Array(i))))}catch{throw new Gr}},Yr=async(e,t)=>{if(!zr())throw new qr;let n=await Hr(t,Kr(e.salt),e.iterations);return{vault:await Jr(e,n),vaultKey:n}},Xr=(e,t)=>e.salt===He(t.salt)&&e.iterations===t.iterations,Zr=`keyfold-viewer.html`,Qr=`Encrypted backup of a Keyfold vault (https://github.com/nickstruglia/standard-notes-keyfold). To read it without Standard Notes, open ${Zr} (keep a copy next to this file; it is also at https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/${Zr}) in a browser and choose this file; it works offline. To restore it, paste the whole text of this file into a new Standard Notes note, change the note type to Keyfold and unlock it with the backup password. `+et(`the password chosen when the backup was made`),$r=(e=nt())=>`keyfold-backup-${e}.json`,ei=async(e,t,n=Ir)=>{let r=new Date().toISOString(),i=await Ur({...e,settings:{...e.settings,lastExportedAt:r}},await Hr(t,void 0,n));return{text:JSON.stringify({app:Ze,version:1,readme:Qr,exportedAt:r,encryption:i},null,1)+` +`,fileName:$r(),exportedAt:r,entries:e.entries.length}},ti=e=>{let t=e.settings.lastExportedAt;return t?e.entries.filter(e=>e.updatedAt>t||e.addedAt>t).length:e.entries.length},ni=e=>e===0?`Never`:e<60?`${e} seconds`:`${e/60} minute${e===60?``:`s`}`,ri=({value:e,options:t,format:n,onChange:r,disabled:i})=>H(`select`,{class:`input`,value:String(e),disabled:i,onChange:e=>r(Number(e.currentTarget.value)),children:[...new Set([...t,e])].sort((e,t)=>e-t).map(e=>H(`option`,{value:String(e),children:n(e)}))}),ii=new Set([`1234567890`,`12345678910`,`0123456789`,`1111111111`,`qwertyuiop`,`asdfghjkl;`,`password12`,`password123`,`password1!`,`password123!`,`iloveyou12`,`letmein123`,`welcome123`,`abcdefghij`,`qwerty1234`,`1q2w3e4r5t`,`q1w2e3r4t5`,`zaq12wsxcde`,`passw0rd123`,`administrator`,`trustno1234`,`football123`,`baseball12`]),ai=e=>{if(ii.has(e.toLowerCase()))return{bits:0,label:`Very common`,tone:`error`};let t=(/[a-z]/.test(e)?26:0)+(/[A-Z]/.test(e)?26:0)+(/[0-9]/.test(e)?10:0)+(/[^a-zA-Z0-9]/.test(e)?33:0),n=new Set(e).size,r=Math.round(Math.min(e.length,n*2)*Math.log2(Math.max(t,1)));return r<50?{bits:r,label:`Weak`,tone:`error`}:r<75?{bits:r,label:`Fair`,tone:`warn`}:{bits:r,label:`Strong`,tone:`ok`}},oi=10,si={set:`Set password`,change:`Change password`,remove:`Remove password`,export:`Encrypt backup`},ci=({mode:e,onSubmit:t,onCancel:n})=>{let r=e===`change`||e===`remove`,i=e===`export`,a=kt(r),o=kt(!r),[s,c]=R(``),[l,u]=R(``),[d,f]=R(``),[p,m]=R(!1),[h,g]=R(!1),_={strength:Oe(),mismatch:Oe()},[v,y]=R(!1),[b,ee]=R(``),x=ai(l),S=x.tone===`error`,te=e!==`remove`,w=d!==``&&d!==l,T=(!r||s.length>0)&&(!te||l.length>=oi&&l===d&&p&&(!S||h));return H(`form`,{class:`password-form`,onSubmit:async e=>{if(e.preventDefault(),T&&!v){y(!0),ee(``);try{await t(s,l)}catch(e){ee(e instanceof Error?e.message:String(e)),y(!1)}}},children:[r&&H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Current vault password`}),H(`input`,{class:`input`,type:`password`,autocomplete:`current-password`,value:s,onInput:e=>c(e.currentTarget.value),ref:a})]}),te&&H(C,{children:[H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:i?`Backup password`:`New vault password`}),H(`input`,{class:`input`,type:`password`,autocomplete:`new-password`,value:l,onInput:e=>u(e.currentTarget.value),ref:o,"aria-describedby":l?_.strength:void 0}),l&&H(`span`,{id:_.strength,class:`hint status-${x.tone}`,children:[x.label,` (~`,x.bits,` bits).`,` `,l.lengthf(e.currentTarget.value),"aria-invalid":w,"aria-describedby":w?_.mismatch:void 0}),w&&H(`span`,{id:_.mismatch,class:`hint status-error`,role:`alert`,children:`Passwords do not match.`})]}),S&&l.length>=oi&&H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:h,onChange:e=>g(e.currentTarget.checked)}),H(`span`,{children:i?`Use this weak password anyway. Anyone who finds the backup file could guess it quickly.`:`Use this weak password anyway. Someone with access to your Standard Notes account could guess it quickly.`})]}),e===`change`&&H(`p`,{class:`small status-warn`,children:[H(U,{name:`alert`}),` Older versions of this note in Standard Notes' note history still open with the old password. If it leaked, delete those revisions too.`]}),H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:p,onChange:e=>m(e.currentTarget.checked)}),H(`span`,{children:i?`I understand that if I forget this password, no one (not Standard Notes, not the developer) can open this backup.`:`I understand that if I forget this password, no one (not Standard Notes, not the developer) can recover the secrets in this note.`})]})]}),b&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` `,b]}),H(`div`,{class:`row`,children:[H(`button`,{type:`submit`,class:`button ${e===`remove`?`danger`:`primary`}`,disabled:!T||v,children:v?i?`Encrypting…`:`Working…`:si[e]}),H(`button`,{type:`button`,class:`button`,onClick:n,disabled:v,children:`Cancel`})]})]})},li=e=>`${(e/1024).toFixed(+(e<10240))} KB`,ui=({vault:e,mobileApp:t,onExport:n,onExported:r,onCopy:i})=>{let{toast:a}=Z(),[o,s]=R(!1),[c,l]=R(null),u=Te(()=>{if(!c)return null;let e=new Blob([c.text],{type:`application/json`});return{url:URL.createObjectURL(e),size:e.size}},[c]);z(()=>{if(u)return()=>{setTimeout(()=>URL.revokeObjectURL(u.url),6e4)}},[u]);let d=B(null),f=B(null);z(()=>(t?f:d).current?.focus(),[u]);let p=e.settings.lastExportedAt,m=p?ti(e):0,h=zr()?mt(e)?`This vault was saved by a newer version of Keyfold. Update Keyfold first, so the backup leaves nothing out.`:e.entries.length===0?`There is nothing to back up yet.`:``:`Your browser does not provide WebCrypto here, so a backup cannot be encrypted.`,g=async()=>{c&&(await i(c.text)?(r(c),a(`Backup copied. Paste it into a text file or another app; only its password opens it.`,`success`)):a(`Could not copy the backup: clipboard access was blocked.`,`error`))},_=c&&u&&H(`a`,{ref:d,class:`button ${t?``:`primary`}`,href:u.url,download:c.fileName,onClick:()=>r(c),children:[H(U,{name:`download`}),` Save file`]}),v=H(`button`,{ref:f,type:`button`,class:`button ${t?`primary`:``}`,onClick:g,children:[H(U,{name:`copy`}),` Copy as text`]});return H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`download`}),` Backup file`]}),H(`p`,{class:`small`,children:`Save an encrypted copy of this vault outside Standard Notes, for example on a flash drive, so you can still read it if Standard Notes is ever unavailable. The Keyfold offline viewer opens it in any browser, with no account and no internet connection.`}),H(`p`,{class:`muted small`,children:[p?`Last backup file: ${ln(p)}.`:`No backup file made yet.`,m>0&&` ${m} ${m===1?`entry was`:`entries were`} added or changed since.`]}),c&&u?H(`div`,{class:`backup-ready`,children:[H(`p`,{class:`status status-ok`,role:`status`,children:[H(U,{name:`check`}),` Encrypted `,c.entries,` `,c.entries===1?`entry`:`entries`,` into `,c.fileName,` (`,li(u.size),`).`]}),H(`div`,{class:`row`,children:[t?v:_,t?_:v,H(`button`,{type:`button`,class:`button`,onClick:()=>l(null),children:`Done`})]}),(t||Mt())&&H(`p`,{class:`small`,children:[t?`The Standard Notes phone app may not save files from plugins. `:``,`If Save file does nothing, copy the text and paste it into a file or another app, or make the backup on a computer.`]}),H(`p`,{class:`muted small`,children:`Keep it somewhere other than Standard Notes, with the offline viewer next to it, and make a new one after adding or changing keys.`})]}):o?H(C,{children:[H(`p`,{class:`small`,children:`Choose a password for this backup. It can be your vault password or a different one, as long as you will still remember it in years.`}),H(ci,{mode:`export`,onSubmit:async(e,t)=>{l(await n(t)),s(!1)},onCancel:()=>s(!1)})]}):H(C,{children:[h&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` `,h]}),H(`div`,{class:`row`,children:[H(`button`,{type:`button`,class:`button primary`,disabled:!!h,onClick:()=>s(!0),children:[H(U,{name:`download`}),` Make a backup file`]}),H(`a`,{class:`button`,href:`https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/${Zr}`,target:`_blank`,rel:`noopener noreferrer`,children:`Get the offline viewer`})]})]})]})},di=({vault:e,settings:t,hasPassword:n,onChange:r,onSetPassword:i,onChangePassword:a,onRemovePassword:o,onExport:s,onExported:c,onCopyBackup:l,mobileApp:u,onLock:d,onClose:f})=>{let{readOnly:p}=Z(),[m,h]=R(null);return H(`article`,{class:`editor settings`,children:[H(`header`,{class:`editor-header`,children:[H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Close settings`,title:`Back`,onClick:f,children:H(U,{name:`back`})}),H(`h2`,{children:`Vault settings`})]}),H(`div`,{class:`editor-body`,children:[H(`p`,{class:`muted small`,children:`Settings are saved in this note, so every device uses the same ones.`}),H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`eye`}),` Privacy`]}),H(`div`,{class:`row`,children:[H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Hide revealed secrets after`}),H(ri,{value:t.autoHideSeconds,options:[0,10,30,60,120,300],format:ni,disabled:p,onChange:e=>r({autoHideSeconds:e})})]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Clear clipboard after`}),H(ri,{value:t.clipboardClearSeconds,options:[0,10,20,30,60,120],format:ni,disabled:p,onChange:e=>r({clipboardClearSeconds:e})})]})]}),H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:t.hideOnBlur,disabled:p,onChange:e=>r({hideOnBlur:e.currentTarget.checked})}),H(`span`,{children:`Hide revealed secrets when the editor loses focus`})]}),H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:t.privacyScreen,disabled:p,onChange:e=>r({privacyScreen:e.currentTarget.checked})}),H(`span`,{children:`Privacy screen: blur the whole vault while the editor is not focused`})]})]}),H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`shield`}),` Backup reminders`]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Flag entries whose backups were not checked within`}),H(ri,{value:t.backupReminderMonths,options:[0,3,6,12,24],format:e=>e===0?`Off`:`${e} months`,disabled:p,onChange:e=>r({backupReminderMonths:e})})]})]}),H(ui,{vault:e,mobileApp:u,onExport:s,onExported:c,onCopy:l}),H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`lock`}),` Vault password`]}),H(`p`,{class:`small`,children:`Standard Notes already end-to-end encrypts this note. A vault password adds a second layer: the note stays unreadable even to someone using your unlocked Standard Notes account, until the password is entered.`}),H(`p`,{class:`muted small`,children:[`AES-256-GCM, key derived with PBKDF2-SHA256 (`,Ir.toLocaleString(),` iterations). The key is kept only in memory while the vault is unlocked.`]}),!n&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` Older versions of this note in Standard Notes' note history are not re-encrypted. To keep no unprotected copy, set the password on a new, empty vault note before adding secrets, or delete the old revisions.`]}),zr()?m?H(ci,{mode:m,onSubmit:async(e,t)=>{m===`set`&&await i(t),m===`change`&&await a(e,t),m===`remove`&&await o(e),h(null)},onCancel:()=>h(null)}):n?H(C,{children:[H(`p`,{class:`status status-ok`,children:[H(U,{name:`check`}),` This vault is password protected.`]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Lock automatically after inactivity`}),H(ri,{value:t.autoLockMinutes,options:[0,1,2,5,10,15,30,60],format:e=>e===0?`Never`:`${e} minute${e===1?``:`s`}`,disabled:p,onChange:e=>r({autoLockMinutes:e})})]}),H(`div`,{class:`row`,children:[H(`button`,{type:`button`,class:`button primary`,onClick:d,children:[H(U,{name:`lock`}),` Lock now`]}),H(`button`,{type:`button`,class:`button`,disabled:p,onClick:()=>h(`change`),children:`Change password`}),H(`button`,{type:`button`,class:`button danger`,disabled:p,onClick:()=>h(`remove`),children:`Remove password`})]})]}):H(`button`,{type:`button`,class:`button primary`,disabled:p,onClick:()=>h(`set`),children:[H(U,{name:`lock`}),` Set a vault password`]}):H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` Your browser does not provide WebCrypto here, so a vault password is not available.`]})]}),H(`section`,{class:`section`,children:[H(`h3`,{children:`About`}),H(`p`,{class:`small`,children:[`Keyfold `,`1.0.23 (9f45f89)`,`, from `,`https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/`,`. Open source (MIT):`,` `,H(`a`,{href:`https://github.com/nickstruglia/standard-notes-keyfold`,target:`_blank`,rel:`noopener noreferrer`,children:`github.com/nickstruglia/standard-notes-keyfold`}),`. Its Content Security Policy blocks all outgoing connections, images and fonts from other sites; only your Standard Notes theme's stylesheets load.`]})]})]})]})},fi=({onUnlock:e,autoFocus:t,exportedAt:n})=>{let r=n?`Backup password`:`Vault password`,i=zr(),a=kt(t&&i),[o,s]=R(``),[c,l]=R(!1),[u,d]=R(``);return H(`div`,{class:`screen`,children:H(`form`,{class:`card lock-card`,onSubmit:async t=>{if(t.preventDefault(),o&&!c){l(!0),d(``);try{await e(o)}catch(e){d(e instanceof Error?e.message:String(e)),l(!1)}}},children:[H(U,{name:`lock`,size:32}),H(`h2`,{children:n?`Encrypted backup`:`Vault locked`}),H(`p`,{class:`muted small`,children:n?`Made ${ln(n)}. Enter the password chosen when the backup was made.`:`This note has an extra vault password. Standard Notes cannot recover it for you.`}),!i&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` This page cannot decrypt vaults: encryption needs a secure (https) connection. Open the note in the Standard Notes app or at app.standardnotes.com.`]}),H(`input`,{class:`input`,type:`password`,autocomplete:`current-password`,placeholder:r,"aria-label":r,value:o,disabled:!i,onInput:e=>s(e.currentTarget.value),ref:a}),u&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` `,u]}),H(`button`,{type:`submit`,class:`button primary`,disabled:!o||c,children:c?`Unlocking…`:`Unlock`})]})})},pi=({length:e,readOnly:t,onConvert:n})=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(U,{name:`alert`,size:32}),H(`h2`,{children:`This note already has other content`}),H(`p`,{class:`small`,children:[`It holds `,e.toLocaleString(),` characters that are not a Keyfold vault. Nothing has been changed.`]}),H(`p`,{class:`small`,children:`To keep the note as it is, switch it back to another editor in Standard Notes. Or convert it: the existing text is kept, line breaks included, in a hidden field of a new "Imported note" entry.`}),H(`button`,{type:`button`,class:`button primary`,disabled:t,onClick:n,children:`Convert to a vault`})]})}),mi=({version:e})=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(U,{name:`alert`,size:32}),H(`h2`,{children:`Saved by a newer version`}),H(`p`,{class:`small`,children:[`This vault uses format version `,e,`, which this copy of Keyfold does not understand yet. Nothing has been changed. Update the plugin in Standard Notes (Preferences → Plugins) to open it.`]})]})}),hi=()=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(U,{name:`alert`,size:32}),H(`h2`,{children:`Vault encryption not recognized`}),H(`p`,{class:`small`,children:`This is a Keyfold vault, but its password protection uses settings this copy of Keyfold cannot read, or the data is damaged. Nothing has been changed. Update the plugin in Standard Notes (Preferences → Plugins), or restore an earlier version from note history.`})]})}),gi=({slow:e})=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(`p`,{class:`muted`,children:`Connecting to Standard Notes…`}),e&&H(`p`,{class:`small muted`,children:`Still waiting. If Standard Notes asks to activate Keyfold, choose Continue; otherwise, close and reopen the note.`})]})}),_i=({dialog:e,onClose:t})=>{let[n]=R(()=>document.activeElement),r=kt();return z(()=>()=>{n?.isConnected&&n.focus()},[]),z(()=>{let e=e=>e.key===`Escape`&&t(!1);return document.addEventListener(`keydown`,e),()=>document.removeEventListener(`keydown`,e)},[t]),H(`div`,{class:`overlay`,role:`presentation`,onClick:e=>e.target===e.currentTarget&&t(!1),onKeyDown:e=>{if(e.key!==`Tab`)return;let t=Array.from(e.currentTarget.querySelectorAll(`button`)),n=t[0],r=t[t.length-1];e.shiftKey&&document.activeElement===n?(e.preventDefault(),r.focus()):!e.shiftKey&&document.activeElement===r&&(e.preventDefault(),n.focus())},children:H(`div`,{class:`card dialog`,role:`alertdialog`,"aria-modal":`true`,"aria-labelledby":`dialog-title`,"aria-describedby":`dialog-message`,children:[H(`h2`,{id:`dialog-title`,children:e.title}),H(`p`,{id:`dialog-message`,class:`small`,children:e.message}),H(`div`,{class:`row end`,children:[H(`button`,{type:`button`,class:`button`,onClick:()=>t(!1),ref:r,children:`Cancel`}),H(`button`,{type:`button`,class:`button ${e.danger?`danger`:`primary`}`,onClick:()=>t(!0),children:e.confirmLabel??`OK`})]})]})})},vi=({toasts:e,onDismiss:t})=>H(`div`,{class:`toasts`,role:`status`,"aria-live":`polite`,children:e.map(e=>H(`div`,{class:`toast toast-${e.tone}`,children:[H(`span`,{children:e.message}),e.action&&H(`button`,{type:`button`,class:`button small`,onClick:()=>{e.action.run(),t(e.id)},children:e.action.label}),H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Dismiss`,onClick:()=>t(e.id),children:H(U,{name:`x`,size:14})})]},e.id))}),yi=e=>{let t=document.activeElement,n=t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement?t:null,r=n?[n.selectionStart,n.selectionEnd]:null,i=document.createElement(`textarea`);i.value=e,i.setAttribute(`readonly`,``),i.style.position=`fixed`,i.style.opacity=`0`,document.body.appendChild(i),i.select(),i.setSelectionRange(0,e.length);let a=!1;try{a=document.execCommand(`copy`)}catch{a=!1}if(i.remove(),t?.focus?.({preventScroll:!0}),n&&r&&r[0]!==null&&r[1]!==null)try{n.setSelectionRange(r[0],r[1])}catch{}return a},bi=async e=>{if(yi(e))return!0;try{if(navigator.clipboard?.writeText)return await navigator.clipboard.writeText(e),!0}catch{}return!1},xi=()=>yi(` `),Si=async()=>{if(xi())return!0;try{if(navigator.clipboard?.writeText)return await navigator.clipboard.writeText(``),!0}catch{}return!1},Ci=2e3,wi=class{host;onError;delayMs;maxWaitMs;version=0;ready=null;timer;inflight=Promise.resolve();unsentSince=null;readyVersion=0;pending=[];lastText=``;constructor(e,t,n=300,r=1e3){this.host=e,this.onError=t,this.delayMs=n,this.maxWaitMs=r}schedule(e){let t=++this.version;this.unsentSince??=Date.now();let n=async()=>{if(t===this.version)try{let n=await e();if(t!==this.version)return;this.ready=n,this.readyVersion=t,clearTimeout(this.timer);let r=this.unsentSince??Date.now(),i=Math.max(0,Math.min(this.delayMs,r+this.maxWaitMs-Date.now()));this.timer=setTimeout(()=>this.flush(),i)}catch(e){t===this.version&&this.onError(e)}};this.inflight=this.inflight.then(n)}flush(){clearTimeout(this.timer),this.timer=void 0;let e=this.ready;e&&(this.ready=null,this.readyVersion===this.version&&(this.unsentSince=null),this.remember(e.text),this.host.save(e.text,e.preview))}hasUnsent(){return this.unsentSince!==null}async settle(){await this.inflight,this.flush()}cancel(){this.version++,clearTimeout(this.timer),this.timer=void 0,this.ready=null,this.unsentSince=null}isEcho(e){let t=Date.now();this.pending=this.pending.filter(e=>t-e.att.text===e);return n===-1?e!==``&&e===this.lastText:(this.pending.splice(0,n),!0)}forget(){this.cancel(),this.pending=[]}noteSeen(e){this.lastText=e}remember(e){this.lastText=e,this.pending.push({text:e,at:Date.now()}),this.pending.length>20&&this.pending.shift()}},Ti=e=>e instanceof Error?e.message:String(e),Ei=H(`datalist`,{id:`bip39-words`,children:It.map(e=>H(`option`,{value:e}))}),Di=H(Hn,{}),Oi=`The note changed while this was running. Please try again.`,ki=({host:e})=>{let[t,n]=R({name:`connecting`}),[r,i]=R(rt),[a,o]=R(!1),[s,c]=R(!1),[l,u]=R(0),[d,f]=R(()=>document.hasFocus()),[p,m]=R(!1),[h,g]=R({type:`list`}),[_,v]=R(``),[y,b]=R(`all`),[ee,x]=R(()=>new Set),[S,te]=R(()=>new Set),[w,T]=R({}),[ne,E]=R({}),[D,re]=R(null),[ie,ae]=R([]),[oe,O]=R(null),k=B(r),A=B(null),se=B(!1),j=B(0),ce=B(0),le=B(0),M=B(null),ue=Ee(e=>ae(t=>t.filter(t=>t.id!==e)),[]),N=Ee((e,t=`info`,n,r=4e3)=>{let i=++le.current;return ae(r=>{let a=[...r,{id:i,message:e,tone:t,action:n}];for(;a.length>4;){let e=a.findIndex(e=>!e.action&&e.id!==i);a.splice(e===-1?0:e,1)}return a}),setTimeout(()=>ue(i),r),i},[]),P=Te(()=>new wi(e,e=>N(`Could not save: ${Ti(e)}`,`error`,void 0,8e3)),[e]),de=async e=>{let t=A.current;return t?{text:xt(await Ur(e,t)),preview:St(null)}:{text:bt(e),preview:St(e)}},fe=e=>{k.current=e,i(e)},pe=mt(r),F=a||pe||t.name!==`ready`,me=B(F);me.current=F;let he=B(a);he.current=a;let ge=()=>{let e=j.current;return()=>{if(e!==j.current)throw Error(Oi);if(me.current)throw Error(`This note is read-only right now.`)}},_e=()=>{A.current=null,P.cancel(),fe(rt()),u(e=>e+1),g({type:`list`}),x(new Set),T({}),re(null),ae([]),O(e=>(e?.resolve(!1),null))},I=Ee(e=>{if(me.current)return!1;let t=e(k.current);return fe(t),P.schedule(()=>de(t)),!0},[P]);z(()=>{e.subscribe(async e=>{if(o(e.locked),e.metadataOnly||P.isEcho(e.text))return;let t=P.hasUnsent();P.cancel(),P.noteSeen(e.text);let r=++j.current,i=r===1,a=yt(e.text),s=()=>t&&N(`A newer version arrived from another device or note history and replaced your last few keystrokes.`,`error`,void 0,8e3);switch(a.kind){case`empty`:case`plain`:{let e=se.current;A.current&&_e(),se.current=!1,c(!1),fe(a.kind===`plain`?a.vault:rt()),n({name:`ready`}),e&&!i?N(`This vault is no longer password protected: the note was changed on another device or restored from history. Set a password again in Settings if this was not you.`,`error`,void 0,6e4):s();return}case`encrypted`:{c(!0),se.current=!0;let e=A.current;if(e&&Xr(a.blob,e))try{let t=await Jr(a.blob,e);if(r!==j.current)return;P.cancel(),fe(t),n({name:`ready`}),s();return}catch{}if(r!==j.current)return;A.current&&_e(),fe(rt()),n({name:`locked`,blob:a.blob,autoFocus:i||document.hasFocus(),exportedAt:a.exportedAt});return}case`foreign`:case`newer`:case`unsupported`:A.current&&_e(),se.current=!1,c(!1),n(a.kind===`foreign`?{name:`foreign`,text:a.text}:a.kind===`newer`?{name:`newer`,version:a.version}:{name:`unsupported`});return}})},[e,P]),z(()=>{let e=setTimeout(()=>m(!0),5e3);return()=>clearTimeout(e)},[]);let L=r.settings,ve=B(L);ve.current=L,z(()=>{let e=()=>P.flush(),t=()=>{P.flush(),f(!1),ve.current.hideOnBlur&&u(e=>e+1)},n=()=>f(!0),r=()=>document.visibilityState===`hidden`&&P.flush();return window.addEventListener(`blur`,t),window.addEventListener(`focus`,n),window.addEventListener(`pagehide`,e),window.addEventListener(`beforeunload`,e),document.addEventListener(`visibilitychange`,r),()=>{window.removeEventListener(`blur`,t),window.removeEventListener(`focus`,n),window.removeEventListener(`pagehide`,e),window.removeEventListener(`beforeunload`,e),document.removeEventListener(`visibilitychange`,r)}},[P]);let ye=Ee(async(e=!1)=>{e&&M.current&&xi()&&(M.current.blockedToast&&ue(M.current.blockedToast),M.current=null,ce.current++),document.activeElement instanceof HTMLElement&&document.activeElement.blur(),await P.settle();let t=yt(P.lastText);t.kind===`encrypted`?(_e(),n({name:`locked`,blob:t.blob,autoFocus:e||document.hasFocus(),exportedAt:t.exportedAt})):(c(!1),e&&N(`This note is not password protected, so it cannot be locked.`,`error`))},[P]);z(()=>{if(!s||t.name!==`ready`||!L.autoLockMinutes)return;let e=Date.now(),n=()=>e=Date.now(),r=[`pointerdown`,`keydown`,`input`,`wheel`,`touchstart`];r.forEach(e=>window.addEventListener(e,n,{passive:!0}));let i=()=>{Date.now()-e>=L.autoLockMinutes*6e4&&ye()},a=setInterval(i,5e3);return document.addEventListener(`visibilitychange`,i),window.addEventListener(`pageshow`,i),window.addEventListener(`focus`,i),()=>{r.forEach(e=>window.removeEventListener(e,n)),clearInterval(a),document.removeEventListener(`visibilitychange`,i),window.removeEventListener(`pageshow`,i),window.removeEventListener(`focus`,i)}},[s,t.name,L.autoLockMinutes,ye]);let be=async e=>{if(t.name!==`locked`)return;let r=j.current,{vault:i,vaultKey:a}=await Yr(t.blob,e);if(r!==j.current){let e=yt(P.lastText);if(e.kind!==`encrypted`||!Xr(e.blob,a))throw Error(Oi);let t=j.current;if(i=await Jr(e.blob,a),t!==j.current)throw Error(Oi)}if(A.current=a,fe(i),n({name:`ready`}),a.iterations<6e5){let t=ge(),n=await Hr(e);try{t()}catch{return}A.current=n,P.schedule(()=>de(k.current))}},xe=async e=>{await P.settle();let t=yt(P.lastText);if(t.kind!==`encrypted`)throw Error(`The vault is not password protected.`);await Yr(t.blob,e)},Se=async e=>{let t=ge(),n=await Hr(e);t(),A.current=n,c(!0),P.schedule(()=>de(k.current)),N(`Vault password set. The note is now encrypted with it.`,`success`)},Ce=async(e,t)=>{let n=ge();await xe(e);let r=await Hr(t);n(),A.current=r,P.schedule(()=>de(k.current)),N(`Vault password changed.`,`success`)},we=async e=>{let t=ge();await xe(e),t(),A.current=null,c(!1),P.schedule(()=>de(k.current)),N(`Vault password removed. Standard Notes encryption still protects the note.`,`success`)},De=e=>{if(mt(k.current))throw Error(`Update Keyfold before making a backup of this vault.`);return ei(k.current,e)},Oe=async e=>await bi(e)?(ce.current++,M.current?.blockedToast&&ue(M.current.blockedToast),M.current=null,!0):!1,ke=Ee(e=>{let t=ve.current.clipboardClearSeconds,n=++ce.current;M.current?.blockedToast&&ue(M.current.blockedToast),M.current=t?{id:n}:null;let r=Mt(),i=t?`${e} copied. The clipboard is cleared after ${t}s, on your next click or tap here if the browser requires one. It stays copied if you leave this note first.`:`${e} copied.`;if(N(r?`${i} Your keyboard's clipboard history may keep its own copy.`:i,`success`,void 0,r?8e3:6e3),!t)return;let a=()=>{M.current?.blockedToast&&ue(M.current.blockedToast),M.current?.id===n&&(M.current=null),r?N(`Clipboard cleared. Delete it from your keyboard's clipboard history too.`,`info`,void 0,6e3):N(`Clipboard cleared.`,`info`,void 0,3e3)};setTimeout(async()=>{if(n!==ce.current)return;if(await Si()){a();return}let e=[`click`,`touchend`,`pointerup`],t=!1,r=()=>e.forEach(e=>window.removeEventListener(e,i,!0)),i=()=>{if(!t){if(n!==ce.current)return r();xi()&&(t=!0,r(),a())}};e.forEach(e=>window.addEventListener(e,i,!0));let o=N(`Waiting for a click or tap to clear the clipboard.`,`info`,{label:`Clear now`,run:i},2e4);M.current?.id===n&&(M.current.blockedToast=o)},t*1e3)},[N]),Ae=Ee(async(e,t)=>{e&&(await bi(e)?ke(t):N(`Could not copy ${t.toLowerCase()}: clipboard access was blocked.`,`error`))},[ke]);z(()=>{let e=e=>{e.target?.closest?.(`[data-secret]`)&&ke(`Selection`)};return document.addEventListener(`copy`,e,!0),document.addEventListener(`cut`,e,!0),()=>{document.removeEventListener(`copy`,e,!0),document.removeEventListener(`cut`,e,!0)}},[ke]);let je=Ee(e=>new Promise(t=>O({...e,resolve:t})),[]),Me=Te(()=>({settings:L,readOnly:F,hideEpoch:l,copy:Ae,toast:N,confirm:je,sectionOpen:(e,t)=>w[e]??t,setSectionOpen:(e,t)=>T(n=>({...n,[e]:t}))}),[L,F,l,Ae,N,je,w]),V={layout:L.layout,density:L.density,singleExpand:L.singleExpand,groupBy:L.groupBy,sort:L.sort,...ne},Ne=e=>{E(t=>({...t,...e})),I(t=>({...t,settings:{...t.settings,...e}}))},Pe=V.singleExpand,Fe=Ee(e=>{re(null),x(t=>{if(t.has(e)){let n=new Set(t);return n.delete(e),n}return Pe?new Set([e]):new Set(t).add(e)})},[Pe]),Ie=Ee(e=>te(t=>{let n=new Set(t);return n.delete(e)||n.add(e),n}),[]),Le=e=>{b(`all`),v(``),te(new Set),re(e),x(t=>V.singleExpand?new Set([e]):new Set(t).add(e)),g({type:`entry`,id:e})},Re=e=>{let t=it(e);I(e=>({...e,entries:[t,...e.entries]})),Le(t.id)},W=(e,t)=>{I(n=>({...n,entries:n.entries.map(n=>n.id===e?{...n,...t,updatedAt:new Date().toISOString()}:n)}))&&t.archived===!0&&N(`Archived. It is under the "Archived" filter.`,`info`,{label:`Undo`,run:()=>W(e,{archived:!1})},6e3)},ze=e=>{let t=k.current.entries.find(t=>t.id===e);if(!t)return;let n=new Date().toISOString(),r={...JSON.parse(JSON.stringify(t)),id:qe(),label:t.label?`${t.label} (copy)`:``,archived:!1,addedAt:n,updatedAt:n};I(e=>({...e,entries:[r,...e.entries]})),Le(r.id)},Be=async e=>{let t=k.current.entries.findIndex(t=>t.id===e),n=k.current.entries[t];n&&await je({title:`Delete this entry?`,message:`"${n.label||`Untitled`}" will be removed from this note. You can undo right after, and Standard Notes keeps note history.`,confirmLabel:`Delete`,danger:!0})&&k.current.entries.some(t=>t.id===e)&&(I(t=>({...t,entries:t.entries.filter(t=>t.id!==e)}))?(g({type:`list`}),x(t=>{let n=new Set(t);return n.delete(e),n}),N(`Deleted "${n.label||`Untitled`}".`,`info`,{label:`Undo`,run:()=>{k.current.entries.some(e=>e.id===n.id)||I(e=>{let r=[...e.entries];return r.splice(Math.min(t,r.length),0,n),{...e,entries:r}})}},1e4)):N(`Nothing was deleted: the note is read-only right now.`,`error`))},Ve=e=>I(t=>({...t,settings:{...t.settings,...e}})),He=async e=>{let t=j.current;if(!await je({title:`Convert this note?`,message:`The existing text is moved into a hidden field of a new "Imported note" entry, and the note becomes a vault.`,confirmLabel:`Convert`})||t!==j.current||he.current)return;let r=rt();r.entries.push(it(`other`,{label:`Imported note`,customFields:[{id:qe(),label:`Imported text`,value:e,hidden:!0,multiline:!0}]})),fe(r),n({name:`ready`}),c(A.current!==null),P.schedule(()=>de(r))},G=h.type===`entry`?r.entries.find(e=>e.id===h.id)??null:null,Ue=r.entries.filter(e=>wt(e,L.backupReminderMonths)).length,K=V.layout===`stacked`?ee.size>0:G!==null,We=[V.layout,V.sort,V.groupBy,y,_,V.layout===`stacked`?``:G?.id].join(`|`),Ge=B(null),Ke=K&&Ge.current?.key===We?Ge.current.snapshot:null,q=vr(r.entries,y,V.sort,_,L.backupReminderMonths);if(Ke){let e=new Set(q.map(e=>e.id));q=[...q,...r.entries.filter(t=>!e.has(t.id)&&Ke.groupOf.has(t.id))]}let Je=xr(q,V.groupBy);Ke&&(Je=Cr(Je,Ke)),Ge.current={key:We,snapshot:Sr(Je)};let J=B({updateEntry:W,deleteEntry:Be,duplicateEntry:ze});J.current={updateEntry:W,deleteEntry:Be,duplicateEntry:ze};let Ye=B(new Map),Xe=e=>{let t=Ye.current.get(e);return t||(t={onUpdate:t=>J.current.updateEntry(e,t),onDelete:()=>J.current.deleteEntry(e),onDuplicate:()=>J.current.duplicateEntry(e)},Ye.current.set(e,t)),t},Ze=H(`div`,{class:`empty`,children:[H(U,{name:`shield`,size:28}),H(`p`,{children:H(`strong`,{children:`No keys yet.`})}),H(`p`,{class:`small muted`,children:`Keep every seed phrase and wallet key in this note, plus SSH, PGP and API keys and recovery codes. Each one folds into a single line until you open it, and secrets stay hidden until you reveal them.`}),!F&&H(C,{children:[H(`div`,{class:`row tight center`,children:[H(`button`,{type:`button`,class:`button primary small`,onClick:()=>Re(`mnemonic`),children:[H(U,{name:`plus`}),` Seed phrase`]}),H(`button`,{type:`button`,class:`button small`,onClick:()=>Re(`privateKey`),children:[H(U,{name:`plus`}),` Wallet key`]})]}),H(`p`,{class:`small muted`,children:`Other key types are under Add.`})]})]}),Qe=r.entries.length>0&&r.entries.every(e=>e.archived)&&y!==`archived`?H(`p`,{class:`empty small muted`,children:[`Every entry is archived.`,` `,H(`button`,{type:`button`,class:`link-button`,onClick:()=>b(`archived`),children:`Show archived entries`})]}):H(`p`,{class:`empty small muted`,children:`No entries match.`}),$e;switch(t.name){case`connecting`:$e=H(gi,{slow:p});break;case`locked`:$e=H(fi,{onUnlock:be,autoFocus:t.autoFocus,exportedAt:t.exportedAt});break;case`foreign`:$e=H(pi,{length:t.text.length,readOnly:a,onConvert:()=>He(t.text)});break;case`newer`:$e=H(mi,{version:t.version});break;case`unsupported`:$e=H(hi,{});break;case`ready`:{let t=H(Fr,{query:_,onQuery:v,filter:y,onFilter:b,dueCount:Ue,shown:q.length,total:r.entries.filter(e=>y===`archived`?e.archived:!e.archived).length,readOnly:F,onAdd:Re,view:V,onView:Ne,onExpandAll:()=>{te(new Set),x(new Set(q.map(e=>e.id)))},onCollapseAll:()=>{re(null),x(new Set)},onSettings:()=>g({type:`settings`}),hasPassword:s,onLock:()=>ye(!0),onHideAll:()=>u(e=>e+1)});$e=h.type===`settings`?H(`main`,{class:`detail full`,children:H(di,{vault:r,settings:L,hasPassword:s,onChange:Ve,onSetPassword:Se,onChangePassword:Ce,onRemovePassword:we,onExport:De,onExported:e=>Ve({lastExportedAt:e.exportedAt}),onCopyBackup:Oe,mobileApp:e.inMobileApp(),onLock:()=>ye(!0),onClose:()=>g({type:`list`})})}):V.layout===`stacked`?H(C,{children:[t,H(`main`,{class:`detail full`,children:r.entries.length===0?Ze:q.length===0?Qe:H(jr,{groups:Je,expanded:ee,collapsedGroups:S,reminderMonths:L.backupReminderMonths,newId:D,onToggle:Fe,onToggleGroup:Ie,handlersFor:Xe})})]}):H(C,{children:[t,H(`div`,{class:`layout ${G?`has-detail`:``}`,children:[H(`aside`,{class:`sidebar`,children:r.entries.length===0?Ze:q.length===0?Qe:H(Or,{groups:Je,collapsedGroups:S,selectedId:G?.id??null,reminderMonths:L.backupReminderMonths,onSelect:e=>{re(null),g({type:`entry`,id:e})},onToggleGroup:Ie})}),H(`main`,{class:`detail`,children:G?H(mr,{entry:G,reminderMonths:L.backupReminderMonths,focusLabel:G.id===D,onBack:()=>{re(null),g({type:`list`})},...Xe(G.id)},G.id):H(`div`,{class:`placeholder muted`,children:[H(U,{name:`shield`,size:36}),H(`p`,{children:`Select an entry, or add a new one.`})]})})]})]})}}return H(Dt.Provider,{value:Me,children:[H(`div`,{class:`app ${V.density} ${L.privacyScreen&&!d&&t.name===`ready`?`privacy`:``}`,children:[e.mode===`demo`&&H(`div`,{class:`banner banner-warn`,role:`note`,children:[H(U,{name:`alert`}),` Demo mode: not connected to Standard Notes, nothing is saved. Do not type real secrets here. To install, add `,H(`code`,{children:new URL(`ext.json`,location.href).href}),` in Standard Notes → Preferences → Plugins.`,` `,`Lost access to Keyfold? `,H(`a`,{href:`#open`,onClick:()=>setTimeout(()=>location.reload()),children:`Open a backup or note read-only`}),`.`]}),e.mode===`viewer`&&H(`div`,{class:`banner`,role:`note`,children:[H(U,{name:`lock`}),` Read-only viewer: nothing you open here is saved or sent anywhere.`,H(`button`,{type:`button`,class:`link-button`,onClick:()=>location.reload(),children:`Close`})]}),pe&&t.name===`ready`&&H(`div`,{class:`banner`,role:`note`,children:[H(U,{name:`alert`}),` This vault was saved by a newer version of Keyfold, so it is read-only here. Update the plugin in Standard Notes (Preferences → Plugins) to edit it.`]}),a&&e.mode!==`viewer`&&t.name===`ready`&&H(`div`,{class:`banner`,role:`note`,children:[H(U,{name:`lock`}),` "Prevent editing" is on for this note. You can still reveal and copy secrets.`]}),$e,L.privacyScreen&&!d&&t.name===`ready`&&H(`button`,{type:`button`,class:`privacy-cover`,onClick:()=>{window.focus(),f(!0)},children:[H(U,{name:`eyeOff`,size:28}),H(`span`,{children:Mt()?`Tap to show the vault`:`Click to show the vault`})]})]}),Di,Ei,oe&&H(_i,{dialog:oe,onClose:e=>{oe.resolve(e),O(null)}}),H(vi,{toasts:ie,onDismiss:e=>ae(t=>t.filter(t=>t.id!==e))})]})},Ai=()=>typeof crypto.randomUUID==`function`?crypto.randomUUID():Array.from(crypto.getRandomValues(new Uint8Array(16)),e=>e.toString(16).padStart(2,`0`)).join(``),ji=e=>e&&/^https?:\/\//.test(e)?e:`*`,Mi=`https://app.standardnotes.com/components/assets/`,Ni=e=>{if(/^https?:\/\//i.test(e)||/^data:text\/css[;,]/i.test(e))return e;let t=/\/components\/assets\/([a-z0-9][a-z0-9.-]*)\/([\w.-]+(?:\/[\w.-]+)*\.css)$/i.exec(e);if(t&&!t[0].includes(`..`))return`${Mi}${t[1]}/${t[2]}`},Pi=2e3,Fi=[`Shift`,`Alt`,`Control`,`Meta`,`AltGraph`],Ii=class{win;sessionKey;origin;environment;queue=[];callbacks=new Map;themeLoads=new WeakMap;themeGeneration=0;constructor(e=window){this.win=e,e.addEventListener(`message`,this.onMessage),e.addEventListener(`click`,this.onClick),e.addEventListener(`keydown`,this.onKey),e.addEventListener(`keyup`,this.onKey),setTimeout(this.reveal,Pi)}get inMobileApp(){return this.environment===`native-mobile-web`||this.environment===`mobile`}streamContextItem(e){this.send(`stream-context-item`,{},t=>t?.item&&e(t.item),!0)}saveItem(e,t){this.send(`save-items`,{items:[e]},()=>t?.())}send(e,t,n,r=!1){if(!this.sessionKey){this.queue.push({action:e,data:t,callback:n,keep:r});return}let i={action:e,data:t,messageId:Ai(),sessionKey:this.sessionKey,api:`component`};n&&this.callbacks.set(i.messageId,{callback:n,keep:r});let a=this.environment===`mobile`?JSON.stringify(i):i;this.win.parent.postMessage(a,ji(this.origin))}onMessage=e=>{if(e.source!==this.win.parent||this.win.parent===this.win)return;let t;try{t=typeof e.data==`string`?JSON.parse(e.data):e.data}catch{return}if(t&&typeof t==`object`)switch(t.action){case`component-registered`:if(this.sessionKey||!t.sessionKey)return;this.sessionKey=t.sessionKey,this.origin=e.origin,this.environment=t.data?.environment,this.activateThemes(t.data?.activeThemeUrls),this.send(`themes-activated`,{});for(let e of this.queue.splice(0))this.send(e.action,e.data,e.callback,e.keep);return;case`themes`:this.activateThemes(t.data?.themes);return;case`reply`:{let e=t.original?.messageId,n=e?this.callbacks.get(e):void 0;if(!n)return;n.keep||this.callbacks.delete(e),n.callback(t.data);return}}};onClick=()=>{this.sessionKey&&this.send(`click`,{})};onKey=e=>{if(!this.sessionKey)return;let t=Fi.includes(e.key),n=e.type===`keyup`&&t;(!e.getModifierState?.(`AltGraph`)||t)&&(e.ctrlKey||e.metaKey||e.key===`Control`||e.key===`Meta`||n)&&(e.type===`keydown`&&(e.ctrlKey||e.metaKey)&&e.key.toLowerCase()===`s`&&e.preventDefault(),this.send(e.type===`keydown`?`key-down`:`key-up`,{key:e.key,code:e.code,ctrlKey:e.ctrlKey,metaKey:e.metaKey,shiftKey:e.shiftKey,altKey:e.altKey}))};activateThemes(e){let t=Array.isArray(e)?e.filter(e=>typeof e==`string`):[],n=[...new Set(t.map(Ni).filter(e=>!!e))],r=this.win.document,i=[...r.querySelectorAll(`link[data-sn-theme]`)],a=[];for(let e of n){let t=i.find(t=>t.getAttribute(`href`)===e);if(t){a.push(this.themeLoads.get(t)??Promise.resolve());continue}let n=r.createElement(`link`),o=new Promise(e=>{n.onload=n.onerror=e});this.themeLoads.set(n,o),a.push(o),n.rel=`stylesheet`,n.href=e,n.setAttribute(`data-sn-theme`,``),r.head.appendChild(n)}let o=++this.themeGeneration;Promise.all(a).then(()=>{if(o===this.themeGeneration){for(let e of i)n.includes(e.getAttribute(`href`)??``)||e.remove();this.updateColorScheme(),this.reveal()}})}updateColorScheme(){let e=this.win.document,t=/^rgba?\(([^)]*)\)/.exec(this.win.getComputedStyle(e.body).backgroundColor)?.[1].split(/[\s,/]+/).map(Number);if(!t||t.length<3||t[3]===0)return;let n=.2126*t[0]+.7152*t[1]+.0722*t[2];e.documentElement.style.colorScheme=n<128?`dark`:`light`}reveal=()=>{this.win.document.documentElement.classList.remove(`theme-pending`)}},Li=e=>e.content?.appData?.[`org.standardnotes.sn`]?.locked===!0,Ri=()=>{let e=new Ii(window),t=null;return{mode:`standardnotes`,inMobileApp:()=>e.inMobileApp,subscribe(n){e.streamContextItem(e=>{t=e,n({text:e.content?.text??``,locked:Li(e),metadataOnly:e.isMetadataUpdate===!0})})},save(n,r){let i=t;i&&(i.content.text=n,i.content.preview_plain=r,i.content.preview_html=``,e.saveItem(i))}}},zi=e=>{let t=e;return{mode:`demo`,inMobileApp:()=>!1,subscribe(e){queueMicrotask(()=>e({text:t,locked:!1,metadataOnly:!1}))},save(e){t=e}}},Bi=e=>({mode:`viewer`,inMobileApp:()=>!1,subscribe(t){queueMicrotask(()=>t({text:e,locked:!0,metadataOnly:!1}))},save(){}}),Vi=()=>{try{return window.parent!==window}catch{return!0}},Hi=20971520,Ui=e=>new Promise((t,n)=>{let r=new FileReader;r.onload=()=>t(String(r.result??``)),r.onerror=()=>n(r.error),r.readAsText(e)}),Wi=({offlineViewer:e,onOpen:t})=>{let[n,r]=R(``),[i,a]=R(``),[o,s]=R(!1),c=B(null),l=kt(),u=(e,n)=>{let r=yt(e).kind;if(r===`empty`)return a(n===`file`?`This file is empty.`:`Paste the text first.`);if(r===`foreign`)return a(n===`file`?`This file is not a Keyfold backup or note.`:`This is not the text of a Keyfold note. Copy all of it, from the first { to the last }, without editing.`);t(e)},d=async e=>{if(e){if(a(``),e.size>Hi)return a(`This file is too large to be a Keyfold backup.`);try{u(await Ui(e),`file`)}catch{a(`Could not read this file.`)}}};return H(`div`,{class:`app`,children:H(`div`,{class:`screen ${o?`dragging`:``}`,onDragOver:e=>{e.preventDefault(),s(!0)},onDragLeave:e=>{e.currentTarget===e.target&&s(!1)},onDrop:e=>{e.preventDefault(),s(!1),d(e.dataTransfer?.files[0])},children:H(`form`,{class:`card open-note`,onSubmit:e=>{e.preventDefault(),a(``),u(n,`paste`)},children:[H(U,{name:`lock`,size:32}),H(`h2`,{children:e?`Keyfold offline viewer`:`Open a Keyfold backup or note`}),H(`p`,{class:`small`,children:[`Open a Keyfold backup file, or paste the text of a Keyfold note. It opens read-only. Nothing is saved, and this page cannot send anything anywhere`,e?`, so it works offline`:``,`.`]}),H(`input`,{ref:c,type:`file`,hidden:!0,"aria-label":`Backup file`,onChange:e=>{let t=e.currentTarget;d(t.files?.[0]).finally(()=>{t.value=``})}}),H(`button`,{ref:l,type:`button`,class:`button primary`,onClick:()=>c.current?.click(),children:[H(U,{name:`file`}),` Choose backup file`]}),!Mt()&&H(`p`,{class:`muted small`,children:`or drop it on this page`}),i&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` `,i]}),H(`details`,{class:`paste-note`,children:[H(`summary`,{children:`Paste a note's text instead`}),H(`p`,{class:`small`,children:`In Standard Notes, change the note type to Plain text, then select all and copy, without editing.`}),H(`textarea`,{class:`input mono`,rows:8,value:n,"aria-label":`Note text`,placeholder:`{ "app": "keyfold", ... }`,onInput:e=>r(e.currentTarget.value),autocomplete:`off`,spellcheck:!1}),H(`button`,{type:`submit`,class:`button`,disabled:!n.trim(),children:`Open read-only`})]}),location.protocol!==`file:`&&H(`a`,{class:`small`,href:`./keyfold-viewer.html`,download:`keyfold-viewer.html`,children:`Save this viewer as a single file, to keep next to your backups`}),!e&&H(`a`,{class:`small`,href:`./`,children:`Back to the demo`})]})})})},Gi=e=>e.split(` `),Ki=e=>{let t=new Uint8Array(4+e.length);return new DataView(t.buffer).setUint32(0,e.length),t.set(e,4),t},qi=(...e)=>{let t=new Uint8Array(e.reduce((e,t)=>e+t.length,0)),n=0;for(let r of e)t.set(r,n),n+=r.length;return t},Ji=()=>{let e=qi(Ki(W(`ssh-ed25519`)),Ki(q(32)));return{privateKey:`-----BEGIN OPENSSH PRIVATE KEY-----\n${He(qi(W(`openssh-key-v1\0`),Ki(W(`aes256-ctr`)),Ki(W(`bcrypt`)),Ki(q(24)),new Uint8Array([0,0,0,1]),Ki(e),Ki(q(144)))).match(/.{1,70}/g).join(` +`)}\n-----END OPENSSH PRIVATE KEY-----`,publicKey:`ssh-ed25519 ${He(e)} demo@example`}},Yi=(e,t=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`)=>Array.from(q(e),e=>t[e%t.length]).join(``),Xi=e=>{let t=new Date;return t.setDate(t.getDate()+e),t.toISOString().slice(0,10)},Zi=()=>{let e=Ji(),t=rt();return t.entries.push(it(`mnemonic`,{label:`Example: cold storage`,description:`Public BIP39 test vector. Do not send funds to it.`,chain:`Bitcoin`,wallet:`Coldcard`,tags:[`example`,`long-term`],favorite:!0,words:Gi(`legal winner thank year wave sausage worth useful legal winner thank yellow`),passphrase:`example passphrase`,passphraseHint:`Example hint only`,derivationPath:`m/84'/0'/0'`,createdOn:`2021-03-14`,backups:[{id:`b1`,location:`Steel plate in home safe`,verifiedOn:nt()}]}),it(`mnemonic`,{label:`Example: multisig key 2 of 3`,chain:`Bitcoin`,wallet:`Trezor`,tags:[`example`,`multisig`],words:Gi(`letter advice cage absurd amount doctor acoustic avoid letter advice cage above`),derivationPath:`m/48'/0'/0'/2'`,createdOn:`2022-08-02`,backups:[{id:`b2`,location:`Bank deposit box`,verifiedOn:`2025-01-10`}]}),it(`mnemonic`,{label:`Example: DeFi hot wallet`,chain:`Ethereum`,wallet:`MetaMask`,tags:[`example`],words:Gi(`${`abandon `.repeat(23)}art`),derivationPath:`m/44'/60'/0'/0/0`,createdOn:`2023-11-20`}),it(`privateKey`,{label:`Example: paper wallet`,description:`WIF test vector from the Bitcoin wiki.`,chain:`Bitcoin`,tags:[`example`],secret:`5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ`,createdOn:`2013-04-01`}),it(`sshKey`,{label:`Example: deploy key`,description:`Random bytes in OpenSSH format, not a working key.`,service:`github.com`,account:`git`,tags:[`example`],secret:e.privateKey,passphrase:`example passphrase`,publicInfo:e.publicKey,expiresOn:Xi(365)}),it(`apiKey`,{label:`Example: CI token`,description:`Random characters in GitHub token format, not a real token.`,service:`GitHub`,account:`release workflow`,tags:[`example`],secret:`ghp_${Yi(36)}`,expiresOn:Xi(12)}),it(`recoveryCodes`,{label:`Example: exchange 2FA backup codes`,service:`Kraken`,account:`you@example.com`,tags:[`example`],secret:Array.from({length:8},()=>`${Yi(4,`0123456789`)}-${Yi(4,`0123456789`)}`).join(` +`)})),t.entries.forEach((e,t)=>e.updatedAt=new Date(Date.now()-t*6e4).toISOString()),bt(t)},Qi=document.documentElement.hasAttribute(`data-viewer`),$i=!Qi&&Vi();document.documentElement.classList.toggle(`standalone`,!$i),$i||document.documentElement.classList.remove(`theme-pending`);var ea=document.getElementById(`app`);$i?de(H(ki,{host:Ri()}),ea):Qi||location.hash===`#open`?de(H(Wi,{offlineViewer:Qi,onOpen:e=>de(H(ki,{host:Bi(e)}),ea)}),ea):de(H(ki,{host:zi(Zi())}),ea)})(); \ No newline at end of file diff --git a/packages/io.github.nickstruglia.keyfold/prebuilt/icon.svg b/packages/io.github.nickstruglia.keyfold/prebuilt/icon.svg new file mode 100644 index 0000000..0e4b5fd --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/prebuilt/icon.svg @@ -0,0 +1 @@ + diff --git a/packages/io.github.nickstruglia.keyfold/prebuilt/index.html b/packages/io.github.nickstruglia.keyfold/prebuilt/index.html new file mode 100644 index 0000000..c0eb4a1 --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/prebuilt/index.html @@ -0,0 +1,16 @@ + + + + + + + + + Keyfold + + + + +
+ + diff --git a/packages/io.github.nickstruglia.keyfold/prebuilt/keyfold-viewer.html b/packages/io.github.nickstruglia.keyfold/prebuilt/keyfold-viewer.html new file mode 100644 index 0000000..9aad608 --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/prebuilt/keyfold-viewer.html @@ -0,0 +1,282 @@ + + + + + + + + + +Keyfold offline viewer + + + + +
+ + + diff --git a/yarn.lock b/yarn.lock index d06ce55..d1f3956 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27769,6 +27769,12 @@ __metadata: languageName: node linkType: hard +"sn-keyfold@workspace:packages/io.github.nickstruglia.keyfold": + version: 0.0.0-use.local + resolution: "sn-keyfold@workspace:packages/io.github.nickstruglia.keyfold" + languageName: unknown + linkType: soft + "sn-stylekit@npm:2.0.19": version: 2.0.19 resolution: "sn-stylekit@npm:2.0.19" From 0f762b9e0fd1e2c4b734af6cceaeff18360d99d5 Mon Sep 17 00:00:00 2001 From: Nicholas Truglia <89828514+nickstruglia@users.noreply.github.com> Date: Fri, 9 Oct 2026 05:00:35 +0000 Subject: [PATCH 2/2] feat: update Keyfold to 1.0.31 --- .../io.github.nickstruglia.keyfold/README.md | 15 +- .../io.github.nickstruglia.keyfold/SHA256SUMS | 6 +- .../package.json | 2 +- .../prebuilt/assets/index-5lEe8QFz.js | 495 ++++++++++++++++++ .../prebuilt/assets/index-BhYPNPAd.js | 265 ---------- .../prebuilt/index.html | 2 +- .../prebuilt/keyfold-viewer.html | 256 ++++++++- 7 files changed, 751 insertions(+), 290 deletions(-) create mode 100644 packages/io.github.nickstruglia.keyfold/prebuilt/assets/index-5lEe8QFz.js delete mode 100644 packages/io.github.nickstruglia.keyfold/prebuilt/assets/index-BhYPNPAd.js diff --git a/packages/io.github.nickstruglia.keyfold/README.md b/packages/io.github.nickstruglia.keyfold/README.md index b3e0a32..04768df 100644 --- a/packages/io.github.nickstruglia.keyfold/README.md +++ b/packages/io.github.nickstruglia.keyfold/README.md @@ -1,16 +1,17 @@ # Keyfold A key manager for Standard Notes: crypto seed phrases and wallet keys, plus SSH and PGP keys, API tokens and recovery -codes. Each entry folds into a one-line card, secrets stay hidden until revealed, seed phrases and keys are checked for -typos (BIP39 and Electrum checksums, Base58Check, Bech32, PGP armor), and an optional vault password encrypts the -whole note again (AES-256-GCM, PBKDF2-SHA256 with 600,000 iterations). Encrypted backup files open in a single-file -offline viewer, without Standard Notes. +codes. Each entry folds into a one-line card, secrets stay hidden until revealed, saved entries open locked against +accidental changes, seed phrases and keys are checked for typos (BIP39, Electrum, Monero and aezeed checksums, +Base58Check, Bech32, PGP armor), and an optional vault password encrypts the whole note again (AES-256-GCM, +PBKDF2-SHA256 with 600,000 iterations). Encrypted backup files open in a single-file offline viewer, without Standard +Notes, and restore into an empty Keyfold note. Its Content Security Policy blocks every outgoing connection (`connect-src 'none'`), and scripts, images and fonts from other sites. The only runtime dependency is Preact. - Source, tests and documentation: https://github.com/nickstruglia/standard-notes-keyfold (MIT) -- This copy: version 1.0.23, built from commit [`9f45f89`](https://github.com/nickstruglia/standard-notes-keyfold/commit/9f45f89f194865a94d26670187a58817eb2f2854) +- This copy: version 1.0.31, built from commit [`77e7bd8`](https://github.com/nickstruglia/standard-notes-keyfold/commit/77e7bd8bac96194cc162e63c118a7ac24687e712) ## Why the files are prebuilt @@ -25,9 +26,9 @@ With Node 22.12 or newer: ```sh git clone https://github.com/nickstruglia/standard-notes-keyfold.git cd standard-notes-keyfold -git checkout 9f45f89f194865a94d26670187a58817eb2f2854 +git checkout 77e7bd8bac96194cc162e63c118a7ac24687e712 npm ci --ignore-scripts -node scripts/directory-package.mjs 1.0.23 +node scripts/directory-package.mjs 1.0.31 diff -r directory-package/io.github.nickstruglia.keyfold/prebuilt /prebuilt diff directory-package/io.github.nickstruglia.keyfold/SHA256SUMS /SHA256SUMS ``` diff --git a/packages/io.github.nickstruglia.keyfold/SHA256SUMS b/packages/io.github.nickstruglia.keyfold/SHA256SUMS index 8f01156..fdc4da6 100644 --- a/packages/io.github.nickstruglia.keyfold/SHA256SUMS +++ b/packages/io.github.nickstruglia.keyfold/SHA256SUMS @@ -1,4 +1,4 @@ -db954df76375f52c561eae1cc8f7db8d4e373fd7dfd51c6e07d26ecc866c352c assets/index-BhYPNPAd.js +68c5e8303d6404139810f4922454a4b63147d7df30523db485de62aa30656417 assets/index-5lEe8QFz.js 0e0ccb766d5e6a479278c3c98865189e0f0bde69ae739d75a1d26470613de64c icon.svg -cfa422d04a596927bdae7f380128398e36accc9392da7a07e3ce66c161a10473 index.html -a13eaf8f351acab9939769e7be2d6f17189d5f489924575861a7becb7e91a587 keyfold-viewer.html +b3e4d9d442990d877b3a95de634c3c70c74e4fd93c0f0902ec77822dc5a13deb index.html +7a444a29f7d33c083f56424000729be5572e7b91db735bc67f2153fff7e4ea9c keyfold-viewer.html diff --git a/packages/io.github.nickstruglia.keyfold/package.json b/packages/io.github.nickstruglia.keyfold/package.json index e5b5c7d..a7dac28 100644 --- a/packages/io.github.nickstruglia.keyfold/package.json +++ b/packages/io.github.nickstruglia.keyfold/package.json @@ -1,6 +1,6 @@ { "name": "sn-keyfold", - "version": "1.0.23", + "version": "1.0.31", "private": true, "description": "A key manager for Standard Notes: seed phrases, wallet, SSH and PGP keys, API tokens and recovery codes, in collapsible cards with hidden fields and checksum checks.", "author": "Nicholas Truglia", diff --git a/packages/io.github.nickstruglia.keyfold/prebuilt/assets/index-5lEe8QFz.js b/packages/io.github.nickstruglia.keyfold/prebuilt/assets/index-5lEe8QFz.js new file mode 100644 index 0000000..d1969b0 --- /dev/null +++ b/packages/io.github.nickstruglia.keyfold/prebuilt/assets/index-5lEe8QFz.js @@ -0,0 +1,495 @@ +(function(){var e=document.createElement(`style`);e.textContent=`:root{--bg:var(--sn-stylekit-background-color,#fff);--fg:var(--sn-stylekit-foreground-color,#1d1d20);--muted:var(--sn-stylekit-passive-color-0,var(--sn-stylekit-neutral-color,#6c7079));--border:var(--sn-stylekit-border-color,#e0e2e6);--panel:var(--sn-stylekit-secondary-background-color,#f6f7f9);--contrast:var(--sn-stylekit-contrast-background-color,#eef0f3);--info:var(--sn-stylekit-info-color,#086dd6);--info-fg:var(--sn-stylekit-info-contrast-color,#fff);--success:var(--sn-stylekit-success-color,#1e8a34);--warning:var(--sn-stylekit-warning-color,#a96500);--danger:var(--sn-stylekit-danger-color,#cc1f36);--danger-fg:var(--sn-stylekit-danger-contrast-color,#fff);--placeholder:var(--sn-stylekit-input-placeholder-color,var(--muted));--success-text:color-mix(in srgb, var(--success) 70%, var(--fg));--warning-text:color-mix(in srgb, var(--warning) 55%, var(--fg));--danger-text:color-mix(in srgb, var(--danger) 75%, var(--fg));--keys:color-mix(in srgb, var(--info) 60%, var(--danger));--font:var(--sn-stylekit-sans-serif-font,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);--mono:var(--sn-stylekit-monospace-font,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);--radius:6px;--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark}@media (prefers-color-scheme:dark){:root{--lightningcss-light: ;--lightningcss-dark:initial}html.standalone{--bg:#17181b;--fg:#e7e8ea;--muted:#9a9ea6;--border:#2e3036;--panel:#1d1f23;--contrast:#262930;--info:#4c9df0;--success:#4fbf63;--warning:#e3a33a;--danger:#f0566a;--placeholder:#6d7179}}html.theme-pending{opacity:0}*{box-sizing:border-box}html,body{background:var(--bg);height:100%;color:var(--fg);font:14px/1.45 var(--font);margin:0}#app,.app{flex-direction:column;height:100%;min-height:0;display:flex}h2,h3{margin:0;font-weight:600}h2{font-size:1.15rem}h3{align-items:center;gap:6px;font-size:.95rem;display:flex}a{color:var(--info)}code{font-family:var(--mono);word-break:break-all;font-size:.9em}.muted{color:var(--muted)}.small{font-size:.85rem}.input{width:100%;min-width:0;font:inherit;color:var(--fg);background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);outline:none;padding:7px 9px}.input::placeholder{color:var(--placeholder)}.input:focus-visible,.button:focus-visible,.icon-button:focus-visible,.entry-item:focus-visible{outline:2px solid var(--info);outline-offset:1px}.input[readonly]{background:var(--panel)}textarea.input{resize:vertical;min-height:2.6em}select.input{width:auto;padding-right:4px}.mono{font-family:var(--mono)}.masked-placeholder{text-align:left;cursor:pointer;color:var(--muted);letter-spacing:2px}.button{font:inherit;color:var(--fg);background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);cursor:pointer;white-space:nowrap;align-items:center;gap:6px;padding:7px 12px;font-weight:500;display:inline-flex}.button.small{padding:4px 9px;font-size:.85rem}.button.primary{background:var(--info);border-color:var(--info);color:var(--info-fg)}.button.danger{color:var(--danger);border-color:var(--danger)}.button:disabled,.icon-button:disabled{opacity:.5;cursor:not-allowed}.icon-button{width:30px;height:30px;color:var(--muted);border-radius:var(--radius);cursor:pointer;background:0 0;border:1px solid #0000;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.icon-button.active{color:var(--warning)}.check{cursor:pointer;align-items:flex-start;gap:8px;margin:6px 0;display:flex}.check input{margin-top:3px}.row{flex-wrap:wrap;align-items:flex-end;gap:10px;display:flex}.row>.field{flex:180px}.row.tight{gap:6px}.row.end{justify-content:flex-end}.grow{flex:200px}.field{flex-direction:column;gap:4px;min-width:0;margin-bottom:10px;display:flex}.field-control{display:contents}.field-label{color:var(--muted);font-size:.8rem;font-weight:600}.hint{color:var(--muted);margin:0;font-size:.8rem}.status{align-items:baseline;gap:6px;margin:6px 0 10px;font-size:.85rem;display:flex}.status svg{flex:none;align-self:flex-start;margin-top:.2em}.status-ok{color:var(--success-text)}.status-error{color:var(--danger-text)}.status-warn{color:var(--warning-text)}.status-info{color:var(--muted)}.pill{white-space:nowrap;background:var(--contrast);color:var(--muted);border-radius:999px;align-items:center;gap:3px;padding:0 7px;font-size:.72rem;line-height:1.6;display:inline-flex}.pill-ok{color:var(--success-text);background:color-mix(in srgb, var(--success) 13%, transparent)}.pill-error{color:var(--danger-text);background:color-mix(in srgb, var(--danger) 13%, transparent)}.pill-warn{color:color-mix(in srgb, var(--warning) 45%, var(--fg));background:color-mix(in srgb, var(--warning) 15%, transparent)}.badge{border-radius:999px;flex:none;padding:2px 8px;font-size:.75rem;font-weight:600}.badge-mnemonic{color:var(--info);background:color-mix(in srgb, var(--info) 12%, transparent)}.badge-privateKey{color:var(--success);background:color-mix(in srgb, var(--success) 12%, transparent)}.badge-other,.badge-recoveryCodes{color:var(--muted);background:var(--contrast)}.badge-sshKey,.badge-pgpKey,.badge-apiKey,.badge-genericKey{color:var(--keys);background:color-mix(in srgb, var(--keys) 12%, transparent)}.banner{background:var(--contrast);border-bottom:1px solid var(--border);padding:8px 14px;font-size:.85rem}.banner svg{vertical-align:-3px;margin-right:4px}.banner-warn{color:var(--fg);background:color-mix(in srgb, var(--warning) 16%, var(--bg))}.layout{flex:1;grid-template-columns:minmax(260px,340px) minmax(0,1fr);min-height:0;display:grid}.sidebar{border-right:1px solid var(--border);background:var(--panel);flex-direction:column;min-height:0;display:flex}.toolbar{background:var(--panel);border-bottom:1px solid var(--border);flex-direction:column;gap:8px;padding:10px 12px;display:flex}.toolbar-row{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.spacer{flex:1}.search{color:var(--muted);flex:200px;position:relative}.search svg{position:absolute;top:50%;left:9px;transform:translateY(-50%)}.search .input{padding-left:30px}.popover-wrap{position:relative}.popover{z-index:15;background:var(--bg);border:1px solid var(--border);border-radius:8px;min-width:190px;max-height:70vh;padding:6px;position:absolute;top:calc(100% + 4px);right:0;overflow-y:auto;box-shadow:0 8px 24px #00000029}.popover-dialog{width:270px;padding:12px}.menu-heading{letter-spacing:.04em;text-transform:uppercase;color:var(--muted);padding:6px 10px 2px;font-size:.72rem;font-weight:600}.menu-group+.menu-group{border-top:1px solid var(--border);margin-top:4px;padding-top:4px}.menu-item{width:100%;font:inherit;text-align:left;color:var(--fg);border-radius:var(--radius);cursor:pointer;background:0 0;border:0;align-items:center;gap:8px;padding:7px 10px;display:flex}.menu-item:focus-visible{background:var(--contrast)}.view-options fieldset{border:0;margin:0 0 10px;padding:0}.view-options legend{color:var(--muted);margin-bottom:2px;padding:0;font-size:.8rem;font-weight:600}.view-options .check{margin:3px 0}.view-options select.input{width:100%}.group-heading{text-transform:uppercase;letter-spacing:.04em;margin:10px 0 4px;font-size:.78rem}.group:first-child .group-heading{margin-top:0}.group-toggle{width:100%;font:inherit;color:var(--muted);border-radius:var(--radius);cursor:pointer;text-transform:inherit;letter-spacing:inherit;background:0 0;border:0;align-items:center;gap:6px;padding:4px;font-weight:600;display:flex}.count{background:var(--contrast);border-radius:999px;padding:0 6px;font-size:.72rem}.toolbar .count{background:0 0;padding:0;font-size:.8rem}.chevron{flex:none;transition:transform .15s}[aria-expanded=true]>.chevron{transform:rotate(90deg)}.entry-list{flex:1;padding:8px 6px;overflow-y:auto}.entry-rows{margin:0;padding:0;list-style:none}.entry-item{width:100%;font:inherit;text-align:left;color:var(--fg);border-radius:var(--radius);cursor:pointer;background:0 0;border:1px solid #0000;align-items:flex-start;gap:10px;padding:9px 10px;display:flex}.entry-item.selected{background:color-mix(in srgb, var(--info) 10%, var(--bg));border-color:var(--border);box-shadow:inset 3px 0 0 var(--info)}.entry-icon{border-radius:var(--radius);padding:6px;display:inline-flex}.entry-main{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.entry-title{text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.entry-title .star{color:var(--warning);vertical-align:-1px;margin-right:4px}.entry-meta{color:var(--muted);text-overflow:ellipsis;white-space:nowrap;font-size:.8rem;overflow:hidden}.entry-pills{flex-wrap:wrap;gap:4px;display:flex}.entry-pills:empty{display:none}.entry-date{color:var(--muted);flex:none;font-size:.75rem}.empty{text-align:center;color:var(--muted);padding:24px 16px}.empty p{margin:6px 0}.detail{min-width:0;min-height:0;overflow-y:auto}.detail.full{flex:1}.stack{max-width:980px;margin:0 auto;padding:12px 12px 48px}.cards{flex-direction:column;gap:6px;margin:0;padding:0;list-style:none;display:flex}.card-entry{background:var(--bg);border:1px solid var(--border);border-radius:8px}.card-entry.open{box-shadow:0 2px 10px #00000012}.card-header{border-radius:8px;align-items:center;gap:4px;padding-right:6px;display:flex}.card-entry.open .card-header{z-index:3;background:var(--bg);border-bottom:1px solid var(--border);border-radius:8px 8px 0 0;position:sticky;top:0}.card-toggle{min-width:0;font:inherit;text-align:left;color:var(--fg);cursor:pointer;background:0 0;border:0;border-radius:8px;flex:auto;align-items:flex-start;gap:10px;padding:10px 12px;display:flex}.card-toggle>.chevron{color:var(--muted);margin-top:7px}.card-toggle:focus-visible,.group-toggle:focus-visible,.section-toggle:focus-visible{outline:2px solid var(--info);outline-offset:-2px}.card-body{padding:0 16px 12px 46px}.entry-actions{flex:none;display:flex}.empty .row.center{justify-content:center;margin-top:12px}.kind-choices{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:6px;max-width:640px;margin:8px auto 10px;display:grid}.kind-choices .button{white-space:normal;text-align:left;justify-content:flex-start}.kind-choices svg{flex:none}.placeholder{flex-direction:column;justify-content:center;align-items:center;gap:8px;height:100%;display:flex}.editor-header{z-index:2;background:var(--bg);border-bottom:1px solid var(--border);align-items:center;gap:6px;padding:10px 16px;display:flex;position:sticky;top:0}.title-input{border-color:#0000;flex:1;font-size:1.1rem;font-weight:600}.title-input:focus{border-color:var(--border)}.editor-body{max-width:880px;padding:8px 16px 32px}.editor-footer{margin-top:16px}.back-button{display:none}.section{border-bottom:1px solid var(--border);padding:10px 0 6px}.section:last-of-type{border-bottom:none}.section.closed{padding-bottom:10px}.section-header{justify-content:space-between;align-items:center;gap:8px;margin-bottom:10px;display:flex}.section.closed .section-header{margin-bottom:0}.section-heading{flex:1;min-width:0}.section-toggle{width:100%;font:inherit;text-align:left;color:var(--fg);border-radius:var(--radius);cursor:pointer;background:0 0;border:0;align-items:center;gap:6px;padding:2px 4px;font-weight:600;display:flex}.section-toggle>.chevron{color:var(--muted)}.section-summary{min-width:0;color:var(--muted);text-overflow:ellipsis;white-space:nowrap;margin-left:4px;font-size:.82rem;font-weight:400;overflow:hidden}.section>h3{margin-bottom:10px}.section p{margin:0 0 10px}.secret{align-items:center;gap:2px;display:flex}.secret-multiline{align-items:flex-start}.secret-actions{flex:none;display:flex}.secret-multiline .secret-actions{flex-direction:column}.word-toolbar{flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:8px;display:flex}.word-grid{grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:6px;margin:0 0 6px;padding:0;list-style:none;display:grid}.word{position:relative}.word-index{min-width:18px;color:var(--muted);text-align:right;pointer-events:none;font-size:.75rem;position:absolute;top:50%;left:8px;transform:translateY(-50%)}.word .input{padding-left:30px;padding-right:6px}.word .input::-webkit-calendar-picker-indicator{display:none!important}.word .input::-webkit-list-button{display:none!important}.word-invalid .input{border-color:var(--danger);background:color-mix(in srgb, var(--danger) 6%, var(--bg))}.custom-field{grid-template-columns:minmax(110px,.6fr) minmax(0,1.4fr) auto;align-items:center;gap:8px;margin-bottom:8px;display:grid}.custom-actions{align-items:center;gap:4px;display:flex}.custom-actions .check{margin:0}.backup-row{align-items:center;margin-bottom:8px}.backup-row input[type=date]{width:auto}.screen{flex:1;justify-content:center;align-items:center;padding:24px 16px;display:flex;overflow:auto}.card{text-align:center;background:var(--bg);border:1px solid var(--border);border-radius:10px;flex-direction:column;align-items:center;gap:10px;width:100%;max-width:420px;padding:24px;display:flex}.card p{margin:0}.lock-card .input,.lock-card .button{justify-content:center;width:100%}.open-note,.restore-backup{width:100%;max-width:640px}.open-note textarea,.restore-backup textarea{width:100%}.screen.dragging .open-note,.screen.dragging .restore-backup{border-color:var(--info);box-shadow:0 0 0 3px color-mix(in srgb, var(--info) 30%, transparent)}.paste-note{width:100%}.lock-bar{color:var(--muted);background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);align-items:center;gap:8px;margin:10px 0 4px;padding:4px 4px 4px 10px;font-size:.85rem;display:flex}.lock-bar>span{flex:1;min-width:0}.lock-bar>svg{flex:none}.lock-bar.editing{color:var(--fg);border-color:var(--info)}.notices>summary{color:var(--info);cursor:pointer}.notices pre{white-space:pre-wrap;overflow-wrap:anywhere;color:var(--muted)}.paste-note>summary{color:var(--info);cursor:pointer;font-size:.85rem}.paste-note>*+*{margin-top:10px}a.button{text-decoration:none}.backup-ready>.row{margin-bottom:10px}.password-form{max-width:460px}.overlay{z-index:40;background:#00000059;justify-content:center;align-items:center;padding:16px;display:flex;position:fixed;inset:0}.dialog{text-align:left;align-items:stretch;box-shadow:0 10px 30px #0003}.toasts{z-index:30;pointer-events:none;flex-direction:column;align-items:flex-end;gap:8px;display:flex;position:fixed;bottom:16px;left:16px;right:16px}.toast{background:var(--bg);border:1px solid var(--border);border-left:4px solid var(--info);border-radius:var(--radius);pointer-events:auto;align-items:center;gap:8px;max-width:420px;padding:8px 8px 8px 12px;font-size:.85rem;display:flex;box-shadow:0 4px 16px #00000026}.toast-success{border-left-color:var(--success)}.toast-error{border-left-color:var(--danger)}.app.privacy .layout,.app.privacy .toolbar,.app.privacy .detail{filter:blur(10px);pointer-events:none;-webkit-user-select:none;user-select:none}.app.privacy~.overlay,.app.privacy~.toasts{filter:blur(10px)}.privacy-cover{z-index:10;width:100%;font:inherit;cursor:pointer;color:var(--muted);background:0 0;border:0;flex-direction:column;justify-content:center;align-items:center;gap:8px;display:flex;position:fixed;inset:0}.app.compact{font-size:13px}.app.compact .input{padding:4px 7px}.app.compact .button{padding:4px 9px}.app.compact .toolbar{gap:6px;padding:6px 10px}.app.compact .stack{padding-top:8px}.app.compact .cards{gap:4px}.app.compact .card-toggle,.app.compact .entry-item{align-items:center;padding:5px 10px}.app.compact .card-toggle>.chevron{margin-top:0}.app.compact .entry-icon{padding:3px}.app.compact .entry-main{flex-direction:row;align-items:center;gap:8px}.app.compact .entry-title{text-overflow:ellipsis;white-space:nowrap;flex:none;min-width:0;max-width:60%;overflow:hidden}.app.compact .entry-meta{flex:0 10 auto;min-width:0}.app.compact .entry-pills{flex-wrap:nowrap;flex:0 auto;min-width:0;overflow:hidden}.app.compact .sidebar .entry-date,.app.compact .entry-pills .pill:not(.pill-error):not(.pill-warn){display:none}.app.compact .card-body{padding:0 12px 8px 36px}.app.compact .section{padding:6px 0 4px}.app.compact .section.closed{padding-bottom:6px}.app.compact .section-header{margin-bottom:6px}.app.compact .section.closed .section-header{margin-bottom:0}.app.compact .field{margin-bottom:6px}.app.compact .helper,.app.compact .field>.hint:not([class*=status-]):not(.hint-safety){display:none}.app.compact .word-grid{grid-template-columns:repeat(auto-fill,minmax(112px,1fr));gap:4px}.app.compact .word .input{padding-left:28px}.app.compact .search .input{padding-left:30px}.app.compact .editor-footer{margin-top:8px}@media (pointer:coarse){.input,.app.compact .input{font-size:16px}.icon-button{width:40px;height:40px}.entry-actions{gap:6px}}@media (max-width:560px){.toolbar .button-text,.app.compact .entry-meta{display:none}.toolbar .button{padding:5px 8px}.toolbar .search{flex-basis:100%}.toolbar .filter{flex:1 1 0;min-width:0}.toolbar .add-button .button-text{display:inline}.toolbar .add-button{padding:5px 12px}.kind-choices{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width:760px){.card-header{flex-wrap:wrap}.card-entry.open .entry-actions{margin-left:auto}.card-body,.app.compact .card-body{padding:0 10px 10px}.entry-date{display:none}.layout{grid-template-columns:minmax(0,1fr)}.layout.has-detail .sidebar,.layout:not(.has-detail) .detail{display:none}.sidebar{border-right:none}.back-button{display:inline-flex}.editor-header{flex-wrap:wrap;padding:8px 10px}.editor-header .badge{margin-right:auto}.title-input{flex-basis:100%;order:10}.editor-body{padding:4px 12px 24px}.custom-field{grid-template-columns:minmax(0,1fr)}.word-grid{grid-template-columns:repeat(auto-fill,minmax(120px,1fr))}}@media (max-width:560px){.toolbar-row{position:relative}.popover-wrap{position:static}.popover{min-width:0;left:0;right:0}.popover-dialog{width:auto}}@media (max-width:760px),(max-height:560px){.card-entry.open .card-header{position:static}}@media (pointer:coarse){.button,.toolbar .button,.toolbar select.input{min-height:40px}.toolbar .button{min-width:36px}.group-toggle,.section-toggle{min-height:40px}.menu-item{min-height:44px}.check{align-items:center;min-height:40px}.check input{width:20px;height:20px}}@media (hover:hover){.button:hover:not(:disabled){background:var(--contrast)}.button.primary:hover:not(:disabled){background:var(--info);filter:brightness(1.08)}.button.danger:hover:not(:disabled){background:var(--danger);color:var(--danger-fg)}.icon-button:hover:not(:disabled){color:var(--fg);background:var(--contrast)}.icon-button.danger:hover:not(:disabled){color:var(--danger)}.group-toggle:hover{color:var(--fg)}.entry-item:hover{background:var(--contrast)}.card-toggle:hover{background:var(--panel)}.menu-item:hover{background:var(--contrast)}.title-input:hover{border-color:var(--border)}}.input::-webkit-date-and-time-value{text-align:start}@media (forced-colors:active){.pill,.status-error,.entry-item.selected,.word-invalid .input{border:1px solid canvastext}.entry-item.selected{border-color:highlight}.word-invalid .input{border-width:2px}}@supports not (color:color-mix(in srgb, red, red)){:root{--keys:var(--info);--success-text:var(--success);--warning-text:var(--fg);--danger-text:var(--danger)}.pill-ok,.pill-error,.pill-warn,.badge,[class*=badge-],.entry-item.selected,.word-invalid .input{background:var(--contrast)}.pill-warn{color:var(--fg)}}@media print{.app{display:none}}.link-button{font:inherit;color:var(--info);cursor:pointer;background:0 0;border:0;margin:0 .25em;padding:0;text-decoration:underline} +/*$vite$:1*/`,document.head.appendChild(e);var t,n,r,i,a,o,s,c,l,u,d,f,p,m={},h=[],g=/^m(i|n|o|s|text|space)$/,_=Array.isArray,v=h.slice,y=Object.assign;function b(e){e&&e.parentNode&&e.remove()}function x(e,t,n){var r,i,a,o={},s=arguments.length;for(a in t)a==`key`?r=t[a]:a==`ref`&&typeof e!=`function`?i=t[a]:o[a]=t[a];return s>2&&(o.children=s>3?v.call(arguments,2):n),S(e,o,r,i,null)}function S(e,r,i,a,o){var s={type:e,props:r,key:i,ref:a,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:o||++n,__i:-1,__u:0};return!o&&t.vnode&&t.vnode(s),s}function C(e){return e.children}function w(e,t){this.props=e,this.context=t,this.__g=0}function T(e,t){if(t==null)return e.__?T(e.__,e.__i+1):null;for(var n;tn&&r.sort(o),e=r.shift(),n=r.length,8&e.__g&&(s=void 0,c=void 0,l=(c=(i=e).__v).__e,u=[],d=[],(f=i.__P)&&((s=y({constructor:void 0},c)).__v=c.__v+1,t.vnode&&t.vnode(s),oe(f,s,c,i.__n,f.namespaceURI,32&c.__u?[l]:null,u,l||T(c),32&c.__u,d),s.__v=c.__v,s.__.__k[s.__i]=s,ce(u,s,d),c.__=c.__e=null,s.__e!=l&&E(s)))}finally{r.length=a=0}}function ee(e,t,n,r,i,a,o,s,c,l,u){var d,f,p,g,_,v,y=r.__k||h,b=t.length;for(c=te(n,t,y,c,b),d=0;dc?v--:v++,y=!0)):(~l||(i>h?v--:i>1]+!!u){for(i=n-1,a=n+1;i>=0||a=0?i--:a++])&&!(2&l.__u)&&s==l.key&&c==l.type)return o}return-1}function re(e,t,n){n??=``,t[0]==`-`?e.setProperty(t,n):e[t]=n}function ie(e,t,n,r,i){var a;n:if(t==`style`){if(typeof n==`string`)e.style.cssText=n;else{if(typeof r==`string`&&(e.style.cssText=r=``),r)for(t in r)n&&t in n||re(e.style,t,``);if(n)for(t in n)r&&n[t]==r[t]||re(e.style,t,n[t])}}else if(t[0]==`o`&&t[1]==`n`)a=t!=(t=t.replace(l,`$1`)),(t=t.slice(2))[0]<`a`&&(t=t.toLowerCase()),(e.__e||={})[t+a]=n,n?r?n[c]=r[c]:(n[c]=u,e.addEventListener(t,a?f:d,a)):e.removeEventListener(t,a?f:d,a);else{if(i==`http://www.w3.org/2000/svg`)t=t.replace(/xlink(H|:h)/,`h`).replace(/sName$/,`s`);else if(t!=`width`&&t!=`height`&&t!=`href`&&t!=`list`&&t!=`form`&&t!=`tabIndex`&&t!=`download`&&t!=`rowSpan`&&t!=`colSpan`&&t!=`role`&&t!=`popover`&&t in e)try{e[t]=n??``;break n}catch{}typeof n==`function`||(n==null||!1===n&&t[4]!=`-`?e.removeAttribute(t):e.setAttribute(t,t==`popover`&&n==1?``:n))}}function ae(e){return function(n){if(this.__e){var r=this.__e[n.type+e];if(n[s]==null)n[s]=u++;else if(n[s]=n.__.length&&n.__.push({}),n.__[e]}function z(e){return I=1,Se(Pe,e)}function Se(e,t,n){var r=xe(fe++,2);if(r.t=e,!r.__c&&(r.__=[n?n(t):Pe(void 0,t),function(e){var t=r.__N?r.__N[0]:r.__[0],n=r.t(t,e);F(t,n)||(r.__N=[n,r.__[1]],r.__c.setState({}))}],r.__c=N,!N.__f)){N.__f=!0;var i=N.shouldComponentUpdate;N.shouldComponentUpdate=function(e,t,n){var r=this.__H;if(!r)return!0;var a=!1,o=this.props!=e;if(r.__.some(function(e){e.__N&&(a=!0,F(e.__[0],e.__N[0])||(o=!0))}),i){var s=i.call(this,e,t,n);return a?s||o:s}return!a||o}}return r.__}function B(e,t){var n=xe(fe++,3);!L.__s&&Ne(n.__H,t)&&(n.__P=!0,n.__=e,n.u=t,N.__H.__h.push(n))}function V(e){return I=5,Ce(function(){return{current:e}},[])}function Ce(e,t){var n=xe(fe++,7);return Ne(n.__H,t)&&(n.__=e(),n.__H=t),n.__}function we(e,t){return I=8,Ce(function(){return e},t)}function Te(e){var t=N.context[e.__c],n=xe(fe++,9);return n.c=e,t?(n.__??(n.__=!0,t.sub(N)),t.props.value):e.__}function Ee(){var e=xe(fe++,11);if(!e.__){for(var t=N.__v;!t.__m&&t.__;)t=t.__;var n=t.__m||(t.__m=[0,0]);e.__=`P`+n[0]+`-`+n[1]++}return e.__}function De(){var e;do{for(;e=he.shift();)try{je(e)}catch(t){L.__e(t,{__:(e=e.__P)&&e.__v})}for(;e=me.shift();){var t=e.__H;if(e.__P&&t)try{t.__h.some(je),t.__h.some(Me),t.__h=[]}catch(n){t.__h=[],L.__e(n,e.__v)}}}while(he.length)}L.__b=function(e){N=null,ge&&ge(e)},L.__=function(e,t){e&&t.__k&&t.__k.__m&&(e.__m=t.__k.__m),R&&R(e,t)},L.__r=function(e){_e&&_e(e),fe=0;var t=(N=e.__c).__H;t&&(pe==N?N.__h=[]:(t.__h.some(je),t.__h.some(Me),fe=0),t.__h=[],t.__.some(function(e){e.__N&&(e.__=e.__N),e.u=e.__N=void 0})),pe=N},L.diffed=function(e){ve&&ve(e);var t=e.__c;t&&t.__H&&(t.__H.__h.length&&Ae(me.push(t)),t.__H.__.some(function(e){e.u&&(e.__H=e.u)})),pe=N=null},L.__c=function(e,t){t.some(function(e){try{e.__h.some(je),e.__h=e.__h.filter(function(e){return!e.__||Me(e)})}catch(n){t.some(function(e){e.__h&&=[]}),t=[],L.__e(n,e.__v)}}),ye&&ye(e,t)},L.unmount=function(e){be&&be(e);var t,n,r=e.__c;r&&r.__H&&(r.__H.__.some(function(r){try{if(r.__P&&r.__c){if(n===void 0){for(n=e.__;n&&(!n.__c||!n.__c.__P);)n=n.__;n&&=n.__c}r.__P=n,Ae(he.push(r))}else je(r)}catch(e){t=e}}),r.__H=void 0,t&&L.__e(t,r.__v))};var Oe=typeof requestAnimationFrame==`function`;function ke(e){var t,n=function(){clearTimeout(r),Oe&&cancelAnimationFrame(t),setTimeout(e)},r=setTimeout(n,35);Oe&&(t=requestAnimationFrame(n))}function Ae(e){e!=1&&P==L.requestAnimationFrame||((P=L.requestAnimationFrame)||ke)(De)}function je(e){var t=N,n=e.__c;typeof n==`function`&&(e.__c=void 0,n()),N=t}function Me(e){var t=N;e.__c=e.__(),N=t}function Ne(e,t){return!e||e.length!=t.length||t.some(function(t,n){return!F(t,e[n])})}function Pe(e,t){return typeof t==`function`?t(e):t}var Fe=0;Array.isArray;function H(e,n,r,i,a,o){n||={};var s,c,l=n;if(`ref`in l&&typeof e!=`function`)for(c in l={},n)c==`ref`?s=n[c]:l[c]=n[c];var u={type:e,props:l,key:r,ref:s,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--Fe,__i:-1,__u:0};return(a||o)&&(u.__source=a,u.__self=o),t.vnode&&t.vnode(u),u}var Ie={eye:`M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12Z M12 9a3 3 0 1 0 0 6 3 3 0 0 0 0-6Z`,eyeOff:`M3 3l18 18 M10.6 5.1A10 10 0 0 1 12 5c6.5 0 10 7 10 7a17 17 0 0 1-3.2 4.2 M6.6 6.6A17 17 0 0 0 2 12s3.5 7 10 7a9.6 9.6 0 0 0 5.4-1.6 M9.9 9.9a3 3 0 0 0 4.2 4.2`,copy:`M9 9h11v11H9z M5 15H4V4h11v1`,plus:`M12 5v14 M5 12h14`,star:`M12 3l2.8 5.7 6.2.9-4.5 4.4 1.1 6.2L12 17.3 6.4 20.2l1.1-6.2L3 9.6l6.2-.9Z`,lock:`M6 11h12v10H6z M8 11V7a4 4 0 0 1 8 0v4`,settings:`M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1.1 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1Z`,trash:`M4 7h16 M10 11v6 M14 11v6 M6 7l1 13h10l1-13 M9 7V4h6v3`,back:`M15 18l-6-6 6-6`,check:`M5 12l5 5 9-10`,alert:`M12 3l10 18H2Z M12 10v4 M12 17.5v.5`,key:`M14 10a4 4 0 1 0-3.6 4L13 17h2v2h2v2h3v-3l-6.4-6.4A4 4 0 0 0 14 10Z`,seed:`M4 6h16 M4 12h16 M4 18h10`,shield:`M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6Z`,duplicate:`M8 8h12v12H8z M4 16V4h12`,archive:`M3 4h18v4H3z M5 8v12h14V8 M10 12h4`,x:`M6 6l12 12 M18 6L6 18`,search:`M11 4a7 7 0 1 0 0 14 7 7 0 0 0 0-14Z M20 20l-4-4`,chevron:`M9 6l6 6-6 6`,wallet:`M3 7h15a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H3z M3 7V5h13v2 M16 13.5h.01`,terminal:`M4 6l6 6-6 6 M12 19h8`,mail:`M3 6h18v12H3z M3 7l9 6 9-6`,code:`M8 6l-6 6 6 6 M16 6l6 6-6 6`,list:`M9 6h11 M9 12h11 M9 18h11 M4 6h.01 M4 12h.01 M4 18h.01`,clock:`M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18Z M12 7v5l3 2`,expand:`M7 9l5-5 5 5 M7 15l5 5 5-5`,collapse:`M7 4l5 5 5-5 M7 20l5-5 5 5`,sliders:`M4 6h16 M4 12h16 M4 18h16 M9 4v4 M15 10v4 M7 16v4`,download:`M12 4v11 M7 10l5 5 5-5 M5 20h14`,file:`M6 3h8l4 4v14H6z M14 3v4h4`,edit:`M4 20h4L19 9l-4-4L4 16Z M13.5 6.5l4 4`},U=({name:e,size:t=16,...n})=>H(`svg`,{width:t,height:t,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,"stroke-width":`2`,"stroke-linecap":`round`,"stroke-linejoin":`round`,"aria-hidden":`true`,...n,children:H(`path`,{d:Ie[e]})}),W=new TextEncoder,Le=new TextDecoder,G=e=>W.encode(e),Re=e=>Le.decode(e),ze=e=>Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``),Be=e=>{let t=e.startsWith(`0x`)||e.startsWith(`0X`)?e.slice(2):e;if(t.length%2!=0||/[^0-9a-fA-F]/.test(t))throw Error(`Invalid hex`);let n=new Uint8Array(t.length/2);for(let e=0;e{let t=``;for(let n=0;n{let t=atob(e),n=new Uint8Array(t.length);for(let e=0;eglobalThis.crypto!==void 0&&globalThis.crypto.subtle!==void 0,K=e=>e,We=async e=>new Uint8Array(await crypto.subtle.digest(`SHA-256`,K(e))),Ge=async(e,t)=>{let n=await crypto.subtle.importKey(`raw`,K(e),{name:`HMAC`,hash:`SHA-512`},!1,[`sign`]);return new Uint8Array(await crypto.subtle.sign(`HMAC`,n,K(t)))},Ke=(e,t)=>{if(e.length!==t.length)return!1;for(let n=0;n{let t=new Uint8Array(e);return crypto.getRandomValues(t),t},qe=()=>typeof crypto.randomUUID==`function`?crypto.randomUUID():ze(q(16)),Je=[`mnemonic`,`privateKey`,`sshKey`,`pgpKey`,`apiKey`,`genericKey`,`recoveryCodes`,`other`],J={mnemonic:{label:`Seed phrase`,one:`seed phrase`,plural:`seed phrases`,group:`crypto`,secret:`words`,secretLabel:`Seed phrase`,passphraseLabel:`Passphrase (25th word)`,passphraseHint:`Optional BIP39 passphrase. A different passphrase opens a different wallet.`,serviceLabel:`Chain / coin`,accountLabel:`Wallet / device`,expires:!1,backupReminders:!0},privateKey:{label:`Wallet key`,one:`wallet key`,plural:`wallet keys`,group:`crypto`,secret:`key`,secretLabel:`Private key`,secretPlaceholder:`Hex, WIF, xprv, nsec, base58, keystore JSON…`,passphraseLabel:`Keystore password`,passphraseHint:`Only for encrypted keystores (e.g. Ethereum JSON keystores).`,serviceLabel:`Chain / coin`,accountLabel:`Wallet / device`,expires:!1,backupReminders:!0},sshKey:{label:`SSH key`,one:`SSH key`,plural:`SSH keys`,group:`keys`,secret:`key`,secretLabel:`Private key`,secretPlaceholder:`-----BEGIN OPENSSH PRIVATE KEY-----`,passphraseLabel:`Key passphrase`,passphraseHint:`The passphrase that unlocks the key file, if it has one.`,publicKey:{label:`Public key`,placeholder:`ssh-ed25519 AAAA… user@host`,fingerprintLabel:`Fingerprint`,fingerprintPlaceholder:`SHA256:…`},serviceLabel:`Hosts / service`,accountLabel:`User / account`,expires:!0,backupReminders:!1},pgpKey:{label:`PGP key`,one:`PGP key`,plural:`PGP keys`,group:`keys`,secret:`key`,secretLabel:`Private key`,secretPlaceholder:`-----BEGIN PGP PRIVATE KEY BLOCK-----`,passphraseLabel:`Key passphrase`,passphraseHint:`The passphrase that protects the secret key.`,publicKey:{label:`Public key`,placeholder:`-----BEGIN PGP PUBLIC KEY BLOCK-----`,fingerprintLabel:`Fingerprint`,fingerprintPlaceholder:`40 hex characters`},serviceLabel:`Used for`,accountLabel:`User ID / email`,expires:!0,backupReminders:!0},apiKey:{label:`API key or token`,one:`API key`,plural:`API keys`,group:`keys`,secret:`token`,secretLabel:`Key or token`,secretPlaceholder:`Paste the key or token`,serviceLabel:`Service`,accountLabel:`Account / project`,expires:!0,backupReminders:!1},genericKey:{label:`Other key`,one:`other key`,plural:`other keys`,group:`keys`,secret:`key`,secretLabel:`Secret key`,secretPlaceholder:`age, WireGuard, PEM, JSON Web Key, Nostr…`,passphraseLabel:`Passphrase`,passphraseHint:`If the key is encrypted.`,publicKey:{label:`Public key`,placeholder:`Public key or recipient`,fingerprintLabel:`Fingerprint / key ID`,fingerprintPlaceholder:`Optional`},serviceLabel:`Used for`,accountLabel:`Account / owner`,expires:!0,backupReminders:!1},recoveryCodes:{label:`Recovery codes`,one:`set of recovery codes`,plural:`sets of recovery codes`,group:`secrets`,secret:`codes`,secretLabel:`Recovery codes`,secretPlaceholder:`One code per line`,serviceLabel:`Service`,accountLabel:`Account`,expires:!1,backupReminders:!0},other:{label:`Other secret`,one:`other secret`,plural:`other secrets`,group:`secrets`,secret:`fields`,secretLabel:`Fields`,serviceLabel:`Service`,accountLabel:`Account`,expires:!1,backupReminders:!1}},Ye={crypto:`Crypto`,keys:`Keys`,secrets:`Secrets`},Xe=e=>J[e].group===`crypto`,Ze=`keyfold`,Qe=`Managed by the Keyfold editor for Standard Notes (https://github.com/nickstruglia/standard-notes-keyfold). Open it with Keyfold; do not edit it as plain text or convert it to Super, which can damage the data. `,$e=Qe+`The vault below lists each entry with its label, kind and secret; seed phrase words are in order, and \\n in a value is a line break.`,et=e=>`The vault below is encrypted with ${e}: PBKDF2-SHA256 (password NFC-normalized, the salt and iteration count below) gives an AES-256-GCM key; the IV is below, the ciphertext ends with the 16-byte tag, the associated data is "keyfold|1|PBKDF2-SHA256||AES-256-GCM", and the plaintext is the vault as JSON.`,tt=Qe+et(`your vault password`),Y={autoHideSeconds:30,clipboardClearSeconds:30,hideOnBlur:!0,privacyScreen:!1,autoLockMinutes:5,backupReminderMonths:12,layout:`stacked`,density:`comfortable`,singleExpand:!1,lockSavedEntries:!0,groupBy:`kind`,sort:`updated`,lastExportedAt:``},nt=()=>{let e=new Date,t=e=>String(e).padStart(2,`0`);return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())}`},rt=()=>({entries:[],settings:{...Y}}),it=(e,t={})=>{let n=new Date().toISOString();return{id:qe(),kind:e,label:``,description:``,chain:``,wallet:``,service:``,account:``,createdOn:nt(),expiresOn:``,tags:[],favorite:!1,archived:!1,scheme:`bip39`,words:e===`mnemonic`?Array(12).fill(``):[],passphrase:``,passphraseHint:``,secret:``,derivationPath:``,fingerprint:``,publicInfo:``,backups:[],customFields:[],notes:``,addedAt:n,updatedAt:n,...t}},X=(e,t=``)=>typeof e==`string`?e:t,at=(e,t=!1)=>typeof e==`boolean`?e:t,ot=(e,t)=>typeof e==`number`&&Number.isFinite(e)&&e>=0?e:t,st=e=>Array.isArray(e)?e:[],ct=(e,t,n)=>t.includes(e)?e:n,lt=e=>e&&typeof e==`object`&&!Array.isArray(e)?e:{},ut=[`bip39`,`electrum`,`aezeed`,`slip39`,`monero`,`other`],dt=e=>{let t=lt(e),n=it(`other`);return{...t,id:X(t.id)||n.id,kind:Je.includes(t.kind)?t.kind:`other`,label:X(t.label),description:X(t.description),chain:X(t.chain),wallet:X(t.wallet),service:X(t.service),account:X(t.account),createdOn:X(t.createdOn),expiresOn:X(t.expiresOn),tags:st(t.tags).filter(e=>typeof e==`string`),favorite:at(t.favorite),archived:at(t.archived),scheme:ut.includes(t.scheme)?t.scheme:`bip39`,words:st(t.words).map(e=>X(e).normalize(`NFC`)),passphrase:X(t.passphrase),passphraseHint:X(t.passphraseHint),secret:X(t.secret),derivationPath:X(t.derivationPath),fingerprint:X(t.fingerprint),publicInfo:X(t.publicInfo),backups:st(t.backups).map(e=>{let t=lt(e);return{...t,id:X(t.id)||qe(),location:X(t.location),verifiedOn:X(t.verifiedOn)}}),customFields:st(t.customFields).map(e=>{let t=lt(e);return{...t,id:X(t.id)||qe(),label:X(t.label),value:X(t.value),hidden:at(t.hidden,!0),multiline:t.multiline===!0||X(t.value).includes(` +`)}}),notes:X(t.notes),addedAt:X(t.addedAt)||n.addedAt,updatedAt:X(t.updatedAt)||n.updatedAt}},ft={layout:[`stacked`,`split`],density:[`comfortable`,`compact`],groupBy:[`none`,`kind`,`chain`,`wallet`,`tag`],sort:[`updated`,`label`,`created`]},pt=new WeakSet,mt=e=>pt.has(e),ht=(e,t)=>st(e.entries).some(e=>{let t=lt(e);return t.kind!==void 0&&!Je.includes(t.kind)||t.scheme!==void 0&&!ut.includes(t.scheme)})||Object.entries(ft).some(([e,n])=>t[e]!==void 0&&!n.includes(t[e])),gt=(e,t,n)=>{let r=ot(e,t);return r>n?t:r},_t=e=>{let t=lt(e),n=lt(t.settings),r={...t,entries:st(t.entries).map(dt),settings:{...n,autoHideSeconds:gt(n.autoHideSeconds,Y.autoHideSeconds,86400),clipboardClearSeconds:gt(n.clipboardClearSeconds,Y.clipboardClearSeconds,86400),hideOnBlur:at(n.hideOnBlur,Y.hideOnBlur),privacyScreen:at(n.privacyScreen,Y.privacyScreen),autoLockMinutes:gt(n.autoLockMinutes,Y.autoLockMinutes,10080),backupReminderMonths:gt(n.backupReminderMonths,Y.backupReminderMonths,1200),layout:ct(n.layout,[`stacked`,`split`],Y.layout),density:ct(n.density,[`comfortable`,`compact`],Y.density),singleExpand:at(n.singleExpand,Y.singleExpand),lockSavedEntries:at(n.lockSavedEntries,Y.lockSavedEntries),groupBy:ct(n.groupBy,[`none`,`kind`,`chain`,`wallet`,`tag`],Y.groupBy),sort:ct(n.sort,[`updated`,`label`,`created`],Y.sort),lastExportedAt:X(n.lastExportedAt)}};return ht(t,n)&&pt.add(r),r},vt=e=>{let t=lt(e);return t.kdf===`PBKDF2-SHA256`&&t.cipher===`AES-256-GCM`&&typeof t.iterations==`number`&&Number.isInteger(t.iterations)&&t.iterations>=1e3&&t.iterations<=1e7&&typeof t.salt==`string`&&typeof t.iv==`string`&&typeof t.ciphertext==`string`},yt=e=>{let t=e?.replace(/^\uFEFF/,``);if(!t||!t.trim())return{kind:`empty`};let n;try{n=JSON.parse(t)}catch{return{kind:`foreign`,text:t}}let r=lt(n);if(r.app!==`keyfold`)return{kind:`foreign`,text:t};let i=typeof r.version==`number`?r.version:0;return i>1?{kind:`newer`,version:i}:r.encryption===void 0?{kind:`plain`,vault:_t(r.vault)}:vt(r.encryption)?typeof r.exportedAt==`string`?{kind:`encrypted`,blob:r.encryption,exportedAt:r.exportedAt}:{kind:`encrypted`,blob:r.encryption}:{kind:`unsupported`}},bt=e=>JSON.stringify({app:Ze,version:1,readme:$e,vault:e},null,1),xt=e=>JSON.stringify({app:Ze,version:1,readme:tt,encryption:e},null,1),St=e=>{if(!e)return`Keyfold (password protected)`;let t=e.entries.filter(e=>!e.archived),n=Je.flatMap(e=>{let n=t.filter(t=>t.kind===e).length;return n?[`${n} ${n===1?J[e].one:J[e].plural}`]:[]});return`Keyfold: ${n.length?n.join(`, `):`empty`}`},Ct=e=>e.backups.map(e=>e.verifiedOn).filter(Boolean).sort().pop()??``,wt=(e,t,n=new Date)=>{if(t<=0||e.archived||!J[e.kind].backupReminders)return!1;let r=Ct(e);if(!r)return!0;let i=new Date(`${r}T00:00:00`);return i.setMonth(i.getMonth()+t),i.getTime()<=n.getTime()},Tt=(e,t=new Date)=>{if(!e.expiresOn||!J[e.kind].expires)return null;let n=new Date(`${e.expiresOn}T00:00:00`);if(Number.isNaN(n.getTime()))return null;let r=new Date(t.getFullYear(),t.getMonth(),t.getDate());return Math.round((n.getTime()-r.getTime())/864e5)},Et=(e,t=new Date)=>{let n=Tt(e,t);return n!==null&&n<=30&&!e.archived},Dt=de({settings:Y,readOnly:!1,hideEpoch:0,copy:()=>void 0,toast:()=>void 0,confirm:async()=>!1,sectionOpen:(e,t)=>t,setSectionOpen:()=>void 0}),Z=()=>Te(Dt),Ot=(e,t)=>{let{sectionOpen:n,setSectionOpen:r}=Z();return[n(e,t),t=>r(e,t)]},kt=(e=!0)=>{let t=V(null);return B(()=>{e&&t.current?.focus()},[]),t},At=(e,t)=>{let[n,r]=z(void 0),i=V(0);return B(()=>{let t=++i.current;e().then(e=>t===i.current&&r(()=>e),()=>t===i.current&&r(void 0))},t),n},jt=e=>{let{hideEpoch:t,settings:n}=Z(),[r,i]=z(!1);return B(()=>i(!1),[t]),B(()=>{if(!r||!n.autoHideSeconds)return;let e=setTimeout(()=>i(!1),n.autoHideSeconds*1e3);return()=>clearTimeout(e)},[r,n.autoHideSeconds,e]),[r,i]},Mt=()=>typeof matchMedia==`function`&&matchMedia(`(pointer: coarse)`).matches,Nt={autocomplete:`off`,autoCorrect:`off`,autocapitalize:`off`,spellcheck:!1,"data-1p-ignore":`true`,"data-lpignore":`true`,"data-bwignore":`true`,"data-form-type":`other`,"data-secret":``},Pt={autoCorrect:`off`,autocapitalize:`off`,spellcheck:!1},Ft=({value:e,onInput:t,label:n,placeholder:r,multiline:i,mono:a,id:o,onMultilinePaste:s})=>{let{readOnly:c,copy:l}=Z(),[u,d]=jt(e),f=`input ${a?`mono`:``}`,p=V(null),[m,h]=z(!1);B(()=>{m&&u&&(p.current?.focus(),h(!1))},[m,u]);let g;return g=i&&!u?H(`button`,{type:`button`,class:`input masked-placeholder`,"aria-label":`${n} (hidden). Reveal to view or edit`,onClick:()=>{d(!0),h(!0)},children:e?`${`•`.repeat(12)} ${e.length} characters, hidden`:r||`Empty`}):i?H(`textarea`,{ref:p,id:o,class:f,value:e,rows:e.length>120?6:3,placeholder:r,"aria-label":n,readOnly:c,onInput:e=>t(e.currentTarget.value),...Nt}):H(`input`,{id:o,class:f,...u?{type:`text`}:{type:`password`},value:e,placeholder:r,"aria-label":n,readOnly:c,onInput:e=>t(e.currentTarget.value),onPaste:t=>{let n=t.clipboardData?.getData(`text`)??``;if(!s||!/[\r\n]/.test(n))return;t.preventDefault();let r=t.currentTarget,i=r.selectionStart??e.length,a=r.selectionEnd??e.length;s(e.slice(0,i)+n+e.slice(a))},...Nt}),H(`div`,{class:`secret ${i?`secret-multiline`:``}`,children:[g,H(`div`,{class:`secret-actions`,children:[H(`button`,{type:`button`,class:`icon-button`,title:u?`Hide`:`Reveal`,"aria-label":`${u?`Hide`:`Reveal`} ${n}`,onClick:()=>d(!u),children:H(U,{name:u?`eyeOff`:`eye`})}),H(`button`,{type:`button`,class:`icon-button`,title:`Copy`,"aria-label":`Copy ${n}`,disabled:!e,onClick:()=>l(e,n),children:H(U,{name:`copy`})})]})]})},It=`abandon ability able about above absent absorb abstract + absurd abuse access accident account accuse achieve acid + acoustic acquire across act action actor actress actual + adapt add addict address adjust admit adult advance + advice aerobic affair afford afraid again age agent + agree ahead aim air airport aisle alarm album + alcohol alert alien all alley allow almost alone + alpha already also alter always amateur amazing among + amount amused analyst anchor ancient anger angle angry + animal ankle announce annual another answer antenna antique + anxiety any apart apology appear apple approve april + arch arctic area arena argue arm armed armor + army around arrange arrest arrive arrow art artefact + artist artwork ask aspect assault asset assist assume + asthma athlete atom attack attend attitude attract auction + audit august aunt author auto autumn average avocado + avoid awake aware away awesome awful awkward axis + baby bachelor bacon badge bag balance balcony ball + bamboo banana banner bar barely bargain barrel base + basic basket battle beach bean beauty because become + beef before begin behave behind believe below belt + bench benefit best betray better between beyond bicycle + bid bike bind biology bird birth bitter black + blade blame blanket blast bleak bless blind blood + blossom blouse blue blur blush board boat body + boil bomb bone bonus book boost border boring + borrow boss bottom bounce box boy bracket brain + brand brass brave bread breeze brick bridge brief + bright bring brisk broccoli broken bronze broom brother + brown brush bubble buddy budget buffalo build bulb + bulk bullet bundle bunker burden burger burst bus + business busy butter buyer buzz cabbage cabin cable + cactus cage cake call calm camera camp can + canal cancel candy cannon canoe canvas canyon capable + capital captain car carbon card cargo carpet carry + cart case cash casino castle casual cat catalog + catch category cattle caught cause caution cave ceiling + celery cement census century cereal certain chair chalk + champion change chaos chapter charge chase chat cheap + check cheese chef cherry chest chicken chief child + chimney choice choose chronic chuckle chunk churn cigar + cinnamon circle citizen city civil claim clap clarify + claw clay clean clerk clever click client cliff + climb clinic clip clock clog close cloth cloud + clown club clump cluster clutch coach coast coconut + code coffee coil coin collect color column combine + come comfort comic common company concert conduct confirm + congress connect consider control convince cook cool copper + copy coral core corn correct cost cotton couch + country couple course cousin cover coyote crack cradle + craft cram crane crash crater crawl crazy cream + credit creek crew cricket crime crisp critic crop + cross crouch crowd crucial cruel cruise crumble crunch + crush cry crystal cube culture cup cupboard curious + current curtain curve cushion custom cute cycle dad + damage damp dance danger daring dash daughter dawn + day deal debate debris decade december decide decline + decorate decrease deer defense define defy degree delay + deliver demand demise denial dentist deny depart depend + deposit depth deputy derive describe desert design desk + despair destroy detail detect develop device devote diagram + dial diamond diary dice diesel diet differ digital + dignity dilemma dinner dinosaur direct dirt disagree discover + disease dish dismiss disorder display distance divert divide + divorce dizzy doctor document dog doll dolphin domain + donate donkey donor door dose double dove draft + dragon drama drastic draw dream dress drift drill + drink drip drive drop drum dry duck dumb + dune during dust dutch duty dwarf dynamic eager + eagle early earn earth easily east easy echo + ecology economy edge edit educate effort egg eight + either elbow elder electric elegant element elephant elevator + elite else embark embody embrace emerge emotion employ + empower empty enable enact end endless endorse enemy + energy enforce engage engine enhance enjoy enlist enough + enrich enroll ensure enter entire entry envelope episode + equal equip era erase erode erosion error erupt + escape essay essence estate eternal ethics evidence evil + evoke evolve exact example excess exchange excite exclude + excuse execute exercise exhaust exhibit exile exist exit + exotic expand expect expire explain expose express extend + extra eye eyebrow fabric face faculty fade faint + faith fall false fame family famous fan fancy + fantasy farm fashion fat fatal father fatigue fault + favorite feature february federal fee feed feel female + fence festival fetch fever few fiber fiction field + figure file film filter final find fine finger + finish fire firm first fiscal fish fit fitness + fix flag flame flash flat flavor flee flight + flip float flock floor flower fluid flush fly + foam focus fog foil fold follow food foot + force forest forget fork fortune forum forward fossil + foster found fox fragile frame frequent fresh friend + fringe frog front frost frown frozen fruit fuel + fun funny furnace fury future gadget gain galaxy + gallery game gap garage garbage garden garlic garment + gas gasp gate gather gauge gaze general genius + genre gentle genuine gesture ghost giant gift giggle + ginger giraffe girl give glad glance glare glass + glide glimpse globe gloom glory glove glow glue + goat goddess gold good goose gorilla gospel gossip + govern gown grab grace grain grant grape grass + gravity great green grid grief grit grocery group + grow grunt guard guess guide guilt guitar gun + gym habit hair half hammer hamster hand happy + harbor hard harsh harvest hat have hawk hazard + head health heart heavy hedgehog height hello helmet + help hen hero hidden high hill hint hip + hire history hobby hockey hold hole holiday hollow + home honey hood hope horn horror horse hospital + host hotel hour hover hub huge human humble + humor hundred hungry hunt hurdle hurry hurt husband + hybrid ice icon idea identify idle ignore ill + illegal illness image imitate immense immune impact impose + improve impulse inch include income increase index indicate + indoor industry infant inflict inform inhale inherit initial + inject injury inmate inner innocent input inquiry insane + insect inside inspire install intact interest into invest + invite involve iron island isolate issue item ivory + jacket jaguar jar jazz jealous jeans jelly jewel + job join joke journey joy judge juice jump + jungle junior junk just kangaroo keen keep ketchup + key kick kid kidney kind kingdom kiss kit + kitchen kite kitten kiwi knee knife knock know + lab label labor ladder lady lake lamp language + laptop large later latin laugh laundry lava law + lawn lawsuit layer lazy leader leaf learn leave + lecture left leg legal legend leisure lemon lend + length lens leopard lesson letter level liar liberty + library license life lift light like limb limit + link lion liquid list little live lizard load + loan lobster local lock logic lonely long loop + lottery loud lounge love loyal lucky luggage lumber + lunar lunch luxury lyrics machine mad magic magnet + maid mail main major make mammal man manage + mandate mango mansion manual maple marble march margin + marine market marriage mask mass master match material + math matrix matter maximum maze meadow mean measure + meat mechanic medal media melody melt member memory + mention menu mercy merge merit merry mesh message + metal method middle midnight milk million mimic mind + minimum minor minute miracle mirror misery miss mistake + mix mixed mixture mobile model modify mom moment + monitor monkey monster month moon moral more morning + mosquito mother motion motor mountain mouse move movie + much muffin mule multiply muscle museum mushroom music + must mutual myself mystery myth naive name napkin + narrow nasty nation nature near neck need negative + neglect neither nephew nerve nest net network neutral + never news next nice night noble noise nominee + noodle normal north nose notable note nothing notice + novel now nuclear number nurse nut oak obey + object oblige obscure observe obtain obvious occur ocean + october odor off offer office often oil okay + old olive olympic omit once one onion online + only open opera opinion oppose option orange orbit + orchard order ordinary organ orient original orphan ostrich + other outdoor outer output outside oval oven over + own owner oxygen oyster ozone pact paddle page + pair palace palm panda panel panic panther paper + parade parent park parrot party pass patch path + patient patrol pattern pause pave payment peace peanut + pear peasant pelican pen penalty pencil people pepper + perfect permit person pet phone photo phrase physical + piano picnic picture piece pig pigeon pill pilot + pink pioneer pipe pistol pitch pizza place planet + plastic plate play please pledge pluck plug plunge + poem poet point polar pole police pond pony + pool popular portion position possible post potato pottery + poverty powder power practice praise predict prefer prepare + present pretty prevent price pride primary print priority + prison private prize problem process produce profit program + project promote proof property prosper protect proud provide + public pudding pull pulp pulse pumpkin punch pupil + puppy purchase purity purpose purse push put puzzle + pyramid quality quantum quarter question quick quit quiz + quote rabbit raccoon race rack radar radio rail + rain raise rally ramp ranch random range rapid + rare rate rather raven raw razor ready real + reason rebel rebuild recall receive recipe record recycle + reduce reflect reform refuse region regret regular reject + relax release relief rely remain remember remind remove + render renew rent reopen repair repeat replace report + require rescue resemble resist resource response result retire + retreat return reunion reveal review reward rhythm rib + ribbon rice rich ride ridge rifle right rigid + ring riot ripple risk ritual rival river road + roast robot robust rocket romance roof rookie room + rose rotate rough round route royal rubber rude + rug rule run runway rural sad saddle sadness + safe sail salad salmon salon salt salute same + sample sand satisfy satoshi sauce sausage save say + scale scan scare scatter scene scheme school science + scissors scorpion scout scrap screen script scrub sea + search season seat second secret section security seed + seek segment select sell seminar senior sense sentence + series service session settle setup seven shadow shaft + shallow share shed shell sheriff shield shift shine + ship shiver shock shoe shoot shop short shoulder + shove shrimp shrug shuffle shy sibling sick side + siege sight sign silent silk silly silver similar + simple since sing siren sister situate six size + skate sketch ski skill skin skirt skull slab + slam sleep slender slice slide slight slim slogan + slot slow slush small smart smile smoke smooth + snack snake snap sniff snow soap soccer social + sock soda soft solar soldier solid solution solve + someone song soon sorry sort soul sound soup + source south space spare spatial spawn speak special + speed spell spend sphere spice spider spike spin + spirit split spoil sponsor spoon sport spot spray + spread spring spy square squeeze squirrel stable stadium + staff stage stairs stamp stand start state stay + steak steel stem step stereo stick still sting + stock stomach stone stool story stove strategy street + strike strong struggle student stuff stumble style subject + submit subway success such sudden suffer sugar suggest + suit summer sun sunny sunset super supply supreme + sure surface surge surprise surround survey suspect sustain + swallow swamp swap swarm swear sweet swift swim + swing switch sword symbol symptom syrup system table + tackle tag tail talent talk tank tape target + task taste tattoo taxi teach team tell ten + tenant tennis tent term test text thank that + theme then theory there they thing this thought + three thrive throw thumb thunder ticket tide tiger + tilt timber time tiny tip tired tissue title + toast tobacco today toddler toe together toilet token + tomato tomorrow tone tongue tonight tool tooth top + topic topple torch tornado tortoise toss total tourist + toward tower town toy track trade traffic tragic + train transfer trap trash travel tray treat tree + trend trial tribe trick trigger trim trip trophy + trouble truck true truly trumpet trust truth try + tube tuition tumble tuna tunnel turkey turn turtle + twelve twenty twice twin twist two type typical + ugly umbrella unable unaware uncle uncover under undo + unfair unfold unhappy uniform unique unit universe unknown + unlock until unusual unveil update upgrade uphold upon + upper upset urban urge usage use used useful + useless usual utility vacant vacuum vague valid valley + valve van vanish vapor various vast vault vehicle + velvet vendor venture venue verb verify version very + vessel veteran viable vibrant vicious victory video view + village vintage violin virtual virus visa visit visual + vital vivid vocal voice void volcano volume vote + voyage wage wagon wait walk wall walnut want + warfare warm warrior wash wasp waste water wave + way wealth weapon wear weasel weather web wedding + weekend weird welcome west wet whale what wheat + wheel when where whip whisper wide width wife + wild will win window wine wing wink winner + winter wire wisdom wise wish witness wolf woman + wonder wood wool word work world worry worth + wrap wreck wrestle wrist write wrong yard year + yellow you young youth zebra zero zone zoo`.split(/\s+/),Lt=`Copyright (c) 2014-2024, The Monero Project +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be + used to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.`,Rt=`abbey abducts ability ablaze abnormal abort abrasive absorb + abyss academy aces aching acidic acoustic acquire across + actress acumen adapt addicted adept adhesive adjust adopt + adrenalin adult adventure aerial afar affair afield afloat + afoot afraid after against agenda aggravate agile aglow + agnostic agony agreed ahead aided ailments aimless airport + aisle ajar akin alarms album alchemy alerts algebra + alkaline alley almost aloof alpine already also altitude + alumni always amaze ambush amended amidst ammo amnesty + among amply amused anchor android anecdote angled ankle + annoyed answers antics anvil anxiety anybody apart apex + aphid aplomb apology apply apricot aptitude aquarium arbitrary + archer ardent arena argue arises army around arrow + arsenic artistic ascend ashtray aside asked asleep aspire + assorted asylum athlete atlas atom atrium attire auburn + auctions audio august aunt austere autumn avatar avidly + avoid awakened awesome awful awkward awning awoken axes + axis axle aztec azure baby bacon badge baffles + bagpipe bailed bakery balding bamboo banjo baptism basin + batch bawled bays because beer befit begun behind + being below bemused benches berries bested betting bevel + beware beyond bias bicycle bids bifocals biggest bikini + bimonthly binocular biology biplane birth biscuit bite biweekly + blender blip bluntly boat bobsled bodies bogeys boil + boldly bomb border boss both bounced bovine bowling + boxes boyfriend broken brunt bubble buckets budget buffet + bugs building bulb bumper bunch business butter buying + buzzer bygones byline bypass cabin cactus cadets cafe + cage cajun cake calamity camp candy casket catch + cause cavernous cease cedar ceiling cell cement cent + certain chlorine chrome cider cigar cinema circle cistern + citadel civilian claim click clue coal cobra cocoa + code coexist coffee cogs cohesive coils colony comb + cool copy corrode costume cottage cousin cowl criminal + cube cucumber cuddled cuffs cuisine cunning cupcake custom + cycling cylinder cynical dabbing dads daft dagger daily + damp dangerous dapper darted dash dating dauntless dawn + daytime dazed debut decay dedicated deepest deftly degrees + dehydrate deity dejected delayed demonstrate dented deodorant depth + desk devoid dewdrop dexterity dialect dice diet different + digit dilute dime dinner diode diplomat directed distance + ditch divers dizzy doctor dodge does dogs doing + dolphin domestic donuts doorway dormant dosage dotted double + dove down dozen dreams drinks drowning drunk drying + dual dubbed duckling dude duets duke dullness dummy + dunes duplex duration dusted duties dwarf dwelt dwindling + dying dynamite dyslexic each eagle earth easy eating + eavesdrop eccentric echo eclipse economics ecstatic eden edgy + edited educated eels efficient eggs egotistic eight either + eject elapse elbow eldest eleven elite elope else + eluded emails ember emerge emit emotion empty emulate + energy enforce enhanced enigma enjoy enlist enmity enough + enraged ensign entrance envy epoxy equip erase erected + erosion error eskimos espionage essential estate etched eternal + ethics etiquette evaluate evenings evicted evolved examine excess + exhale exit exotic exquisite extra exult fabrics factual + fading fainted faked fall family fancy farming fatal + faulty fawns faxed fazed feast february federal feel + feline females fences ferry festival fetches fever fewest + fiat fibula fictional fidget fierce fifteen fight films + firm fishing fitting five fixate fizzle fleet flippant + flying foamy focus foes foggy foiled folding fonts + foolish fossil fountain fowls foxes foyer framed friendly + frown fruit frying fudge fuel fugitive fully fuming + fungal furnished fuselage future fuzzy gables gadget gags + gained galaxy gambit gang gasp gather gauze gave + gawk gaze gearbox gecko geek gels gemstone general + geometry germs gesture getting geyser ghetto ghost giant + giddy gifts gigantic gills gimmick ginger girth giving + glass gleeful glide gnaw gnome goat goblet godfather + goes goggles going goldfish gone goodbye gopher gorilla + gossip gotten gourmet governing gown greater grunt guarded + guest guide gulp gumball guru gusts gutter guys + gymnast gypsy gyrate habitat hacksaw haggled hairy hamburger + happens hashing hatchet haunted having hawk haystack hazard + hectare hedgehog heels hefty height hemlock hence heron + hesitate hexagon hickory hiding highway hijack hiker hills + himself hinder hippo hire history hitched hive hoax + hobby hockey hoisting hold honked hookup hope hornet + hospital hotel hounded hover howls hubcaps huddle huge + hull humid hunter hurried husband huts hybrid hydrogen + hyper iceberg icing icon identity idiom idled idols + igloo ignore iguana illness imagine imbalance imitate impel + inactive inbound incur industrial inexact inflamed ingested initiate + injury inkling inline inmate innocent inorganic input inquest + inroads insult intended inundate invoke inwardly ionic irate + iris irony irritate island isolated issued italics itches + items itinerary itself ivory jabbed jackets jaded jagged + jailed jamming january jargon jaunt javelin jaws jazz + jeans jeers jellyfish jeopardy jerseys jester jetting jewels + jigsaw jingle jittery jive jobs jockey jogger joining + joking jolted jostle journal joyous jubilee judge juggled + juicy jukebox july jump junk jury justice juvenile + kangaroo karate keep kennel kept kernels kettle keyboard + kickoff kidneys king kiosk kisses kitchens kiwi knapsack + knee knife knowledge knuckle koala laboratory ladder lagoon + lair lakes lamb language laptop large last later + launching lava lawsuit layout lazy lectures ledge leech + left legion leisure lemon lending leopard lesson lettuce + lexicon liar library licks lids lied lifestyle light + likewise lilac limits linen lion lipstick liquid listen + lively loaded lobster locker lodge lofty logic loincloth + long looking lopped lordship losing lottery loudly love + lower loyal lucky luggage lukewarm lullaby lumber lunar + lurk lush luxury lymph lynx lyrics macro madness + magically mailed major makeup malady mammal maps masterful + match maul maverick maximum mayor maze meant mechanic + medicate meeting megabyte melting memoir menu merger mesh + metro mews mice midst mighty mime mirror misery + mittens mixture moat mobile mocked mohawk moisture molten + moment money moon mops morsel mostly motherly mouth + movement mowing much muddy muffin mugged mullet mumble + mundane muppet mural musical muzzle myriad mystery myth + nabbing nagged nail names nanny napkin narrate nasty + natural nautical navy nearby necklace needed negative neither + neon nephew nerves nestle network neutral never newt + nexus nibs niche niece nifty nightly nimbly nineteen + nirvana nitrogen nobody nocturnal nodes noises nomad noodles + northern nostril noted nouns novelty nowhere nozzle nuance + nucleus nudged nugget nuisance null number nuns nurse + nutshell nylon oaks oars oasis oatmeal obedient object + obliged obnoxious observant obtains obvious occur ocean october + odds odometer offend often oilfield ointment okay older + olive olympics omega omission omnibus onboard oncoming oneself + ongoing onion online onslaught onto onward oozed opacity + opened opposite optical opus orange orbit orchid orders + organs origin ornament orphans oscar ostrich otherwise otter + ouch ought ounce ourselves oust outbreak oval oven + owed owls owner oxidant oxygen oyster ozone pact + paddles pager pairing palace pamphlet pancakes paper paradise + pastry patio pause pavements pawnshop payment peaches pebbles + peculiar pedantic peeled pegs pelican pencil people pepper + perfect pests petals phase pheasants phone phrases physics + piano picked pierce pigment piloted pimple pinched pioneer + pipeline pirate pistons pitched pivot pixels pizza playful + pledge pliers plotting plus plywood poaching pockets podcast + poetry point poker polar ponies pool popular portents + possible potato pouch poverty powder pram present pride + problems pruned prying psychic public puck puddle puffin + pulp pumpkins punch puppy purged push putty puzzled + pylons pyramid python queen quick quote rabbits racetrack + radar rafts rage railway raking rally ramped randomly + rapid rarest rash rated ravine rays razor react + rebel recipe reduce reef refer regular reheat reinvest + rejoices rekindle relic remedy renting reorder repent request + reruns rest return reunion revamp rewind rhino rhythm + ribbon richly ridges rift rigid rims ringing riots + ripped rising ritual river roared robot rockets rodent + rogue roles romance roomy roped roster rotate rounded + rover rowboat royal ruby rudely ruffled rugged ruined + ruling rumble runway rural rustled ruthless sabotage sack + sadness safety saga sailor sake salads sample sanity + sapling sarcasm sash satin saucepan saved sawmill saxophone + sayings scamper scenic school science scoop scrub scuba + seasons second sedan seeded segments seismic selfish semifinal + sensible september sequence serving session setup seventh sewage + shackles shelter shipped shocking shrugged shuffled shyness siblings + sickness sidekick sieve sifting sighting silk simplest sincerely + sipped siren situated sixteen sizes skater skew skirting + skulls skydive slackens sleepless slid slower slug smash + smelting smidgen smog smuggled snake sneeze sniff snout + snug soapy sober soccer soda software soggy soil + solved somewhere sonic soothe soprano sorry southern sovereign + sowed soya space speedy sphere spiders splendid spout + sprig spud spying square stacking stellar stick stockpile + strained stunning stylishly subtly succeed suddenly suede suffice + sugar suitcase sulking summon sunken superior surfer sushi + suture swagger swept swiftly sword swung syllabus symptoms + syndrome syringe system taboo tacit tadpoles tagged tail + taken talent tamper tanks tapestry tarnished tasked tattoo + taunts tavern tawny taxi teardrop technical tedious teeming + tell template tender tepid tequila terminal testing tether + textbook thaw theatrics thirsty thorn threaten thumbs thwart + ticket tidy tiers tiger tilt timber tinted tipsy + tirade tissue titans toaster tobacco today toenail toffee + together toilet token tolerant tomorrow tonic toolbox topic + torch tossed total touchy towel toxic toyed trash + trendy tribal trolling truth trying tsunami tubes tucks + tudor tuesday tufts tugs tuition tulips tumbling tunnel + turnip tusks tutor tuxedo twang tweezers twice twofold + tycoon typist tyrant ugly ulcers ultimate umbrella umpire + unafraid unbending uncle under uneven unfit ungainly unhappy + union unjustly unknown unlikely unmask unnoticed unopened unplugs + unquoted unrest unsafe until unusual unveil unwind unzip + upbeat upcoming update upgrade uphill upkeep upload upon + upper upright upstairs uptight upwards urban urchins urgent + usage useful usher using usual utensils utility utmost + utopia uttered vacation vague vain value vampire vane + vapidly vary vastness vats vaults vector veered vegan + vehicle vein velvet venomous verification vessel veteran vexed + vials vibrate victim video viewpoint vigilant viking village + vinegar violin vipers virtual visited vitals vivid vixen + vocal vogue voice volcano vortex voted voucher vowels + voyage vulture wade waffle wagtail waist waking wallets + wanted warped washing water waveform waxing wayside weavers + website wedge weekday weird welders went wept were + western wetsuit whale when whipped whole wickets width + wield wife wiggle wildly winter wipeout wiring wise + withdrawn wives wizard wobbly woes woken wolf womanly + wonders woozy worry wounded woven wrap wrist wrong + yacht yahoo yanks yard yawning yearbook yellow yesterday + yeti yields yodel yoga younger yoyo zapped zeal + zebra zero zesty zigzags zinger zippers zodiac zombie + zones zoom`.split(/\s+/),zt=[{id:`bip39`,label:`BIP39 (English)`,counts:[12,15,18,21,24]},{id:`electrum`,label:`Electrum`,counts:[12]},{id:`aezeed`,label:`Aezeed (LND)`,counts:[24]},{id:`slip39`,label:`SLIP-39 share (Shamir)`,counts:[20,33]},{id:`monero`,label:`Monero`,counts:[25,13,16]},{id:`other`,label:`Other`,counts:[]}],Bt=[12,13,15,16,18,20,21,24,25,33],Vt=e=>e===`bip39`||e===`electrum`||e===`aezeed`,Ht=new Map(It.map((e,t)=>[e,t])),Ut=e=>e.normalize(`NFKD`).trim().toLowerCase(),Wt=e=>e.normalize(`NFC`).trim().toLowerCase(),Gt=e=>Ht.has(Ut(e)),Kt=/[\u200B-\u200D\u2060\uFEFF]/g,qt=/[\p{L}\p{M}\p{N}]/u,Jt=e=>{let t=[...e],n=0,r=t.length;for(;nn&&!qt.test(t[r-1]);)r--;return t.slice(n,r).join(``)},Yt=e=>{let t=e.replace(Kt,` `).replace(/(?{if(/^\p{L}[.)]$/u.test(e))return[];let t=Jt(e);return t?/^\d+$/.test(t)?[{n:Number(t)}]:/\p{L}/u.test(t)?[{word:Wt(t)}]:[]:[]}),n=t.flatMap((e,t)=>`n`in e?[t]:[]),r=n.map(e=>t[e-1]);if(n.length>1&&r.every(e=>e&&`word`in e&&e.word===r[0].word))for(let e of n.reverse())t.splice(e-1,1);let i=[],a=[],o=null,s=!0;for(let e of t)`n`in e?o=e.n:(a.push(e.word),o===null?s=!1:i.push({n:o,word:e.word}),o=null);if(s&&a.length>1){let e=[...i].sort((e,t)=>e.n-t.n);if(e.every((t,n)=>t.n===e[0].n+n)&&e[0].n>=1)return{words:e.map(e=>e.word),firstNumber:e[0].n,reordered:e.some((e,t)=>e!==i[t])}}return{words:a,reordered:!1}},Xt=e=>Yt(e).words,Zt=e=>{let t=Ut(e);if(t.length<4||Ht.has(t))return Wt(e);let n=It.filter(e=>e.startsWith(t));return n.length===1?n[0]:Wt(e)},Qt=(e,t)=>{let n=Array.from({length:t.length+1},(e,t)=>t);for(let r=1;r<=e.length;r++){let i=n[0];n[0]=r;for(let a=1;a<=t.length;a++){let o=n[a];n[a]=Math.min(n[a]+1,n[a-1]+1,i+(e[r-1]===t[a-1]?0:1)),i=o}}return n[t.length]},$t=(e,t=3)=>{let n=Ut(e);if(!n||n.length>10)return[];let r=It.filter(e=>e.startsWith(n.slice(0,4)));return r.length>0&&r.length<=t?r:It.map(e=>[e,Qt(n,e)]).filter(([,e])=>e<=2).sort((e,t)=>e[1]-t[1]).slice(0,t).map(([e])=>e)},en=async e=>{let t=e.length*11,n=t/33,r=t-n,i=e.map(e=>e.toString(2).padStart(11,`0`)).join(``),a=new Uint8Array(r/8);for(let e=0;ee.toString(2).padStart(8,`0`)).join(``);return i.slice(r)===s.slice(0,n)},tn=[[`01`,`standard`],[`100`,`segwit`],[`101`,`2fa`],[`102`,`2fa-segwit`]],nn=async e=>{let t=e.map(e=>Ut(e).replace(/[̀-ͯ]/g,``)).join(` `),n=ze(await Ge(G(`Seed version`),G(t)));return tn.find(([e])=>n.startsWith(e))?.[1]??null},rn=async(e,t)=>{let n=t.map(Ut),r=n.filter(Boolean).length,i=Vt(e)?n.flatMap((e,t)=>e&&!Ht.has(e)?[t]:[]):[];if(r===0)return{status:`incomplete`,message:`No words entered yet.`,unknownWords:i};if(r0)return{status:`invalid`,message:`Not in the English BIP39 wordlist: ${i.map(e=>`#${e+1}`).join(`, `)}. For other languages or old Electrum seeds, choose Other.`,unknownWords:i};if(!Ue()&&(e===`bip39`||e===`electrum`))return{status:`unchecked`,message:`Checksum check needs a secure (https) context.`,unknownWords:i};switch(e){case`bip39`:{if(![12,15,18,21,24].includes(n.length))return{status:`invalid`,message:`BIP39 phrases have 12, 15, 18, 21 or 24 words (this has ${n.length}).`,unknownWords:i};if(await en(n.map(e=>Ht.get(e))))return{status:`valid`,message:`Valid BIP39 checksum (${n.length} words).`,unknownWords:i};let e=n.length===12?await nn(n):null,t=n.length===24&&cn(n.map(e=>Ht.get(e)))===`valid`;return{status:`invalid`,message:e?`BIP39 checksum mismatch. The words do pass Electrum's check (${e} seed): if this seed came from Electrum, choose the Electrum scheme; otherwise check every word.`:t?`Not a BIP39 phrase, but these words are a valid aezeed seed. Choose the Aezeed (LND) scheme.`:`Checksum mismatch. Check the spelling and order of every word.`,unknownWords:i}}case`electrum`:{let e=await nn(n);return e?{status:`valid`,message:`Valid Electrum seed (${e}).`,unknownWords:i}:{status:`invalid`,message:`Not a valid Electrum 2.0+ seed. Check the words, or pick another scheme.`,unknownWords:i}}case`monero`:{if(n.length!==25&&n.length!==13)break;if(n.filter(e=>dn.has(e)).lengthfn.has(un(e))?[]:[t]);return e.length>0?{status:`invalid`,message:`Not in the Monero English wordlist: ${e.map(e=>`#${e+1}`).join(`, `)}.`,unknownWords:e}:pn(n)?{status:`valid`,message:`Monero checksum word OK (English, ${n.length} words).`,unknownWords:i}:{status:`invalid`,message:`The last word does not match the Monero checksum. Check the spelling and order of every word.`,unknownWords:i}}case`aezeed`:{if(n.length!==24)return{status:`invalid`,message:`Aezeed seeds have 24 words (this has ${n.length}).`,unknownWords:i};let e=n.map(e=>Ht.get(e)),t=cn(e);return t===`valid`?{status:`valid`,message:`Valid aezeed checksum. A seed password, if it has one, is not checked.`,unknownWords:i}:{status:`invalid`,message:t===`version`&&Ue()&&await en(e)?`Not an aezeed seed, but these words pass the BIP39 checksum. Choose the BIP39 scheme.`:t===`version`?`The first word does not match a known aezeed version. Check it, or pick another scheme.`:`Checksum mismatch. Check the spelling and order of every word.`,unknownWords:i}}}return{status:`unchecked`,message:`${n.length} words. Checksums for this scheme are not checked here.`,unknownWords:i}},an=3988292384,on=2197175160,sn=(e,t=an)=>{let n=4294967295;for(let r of e){let e=(n^r)&255;for(let n=0;n<8;n++)e=e&1?e>>>1^t:e>>>1;n=n>>>8^e}return(n^4294967295)>>>0},cn=e=>{let t=new Uint8Array(33),n=0,r=0,i=0;for(let a of e){for(n=n<<11|a,r+=11;r>=8;)r-=8,t[i++]=n>>>r&255;n&=(1<[...e].slice(0,ln).join(``),dn=new Set(Rt),fn=new Set(Rt.map(un)),pn=e=>{let t=e.slice(0,-1),n=e[e.length-1];return un(t[sn(G(t.map(un).join(``)))%t.length])===un(n)},mn=({words:e,scheme:t,unknownWords:n,onChange:r})=>{let{readOnly:i,copy:a,settings:o}=Z(),[s,c]=jt(e),[l,u]=z(null),[d,f]=z(null),[p,m]=z(``),h=V([]),g=V(new WeakSet),_=Vt(t),v=!Mt();B(()=>{if(d===null||!o.autoHideSeconds)return;let e=setTimeout(()=>f(null),o.autoHideSeconds*1e3);return()=>clearTimeout(e)},[d,e,o.autoHideSeconds]);let y=(t,n)=>{let i=[...e];i[t]=n,r(i)},b=(t,n)=>{let i=Math.min(48,Math.max(e.length,t+n.length)),a=Array.from({length:i},(t,n)=>e[n]??``);n.slice(0,i-t).forEach((e,n)=>a[t+n]=e),r(a),h.current[Math.min(t+n.length,i-1)]?.focus()},x=(e,t)=>{let n=Yt(t.clipboardData?.getData(`text`)??``);if(n.words.length<2)return;t.preventDefault();let r=n.firstNumber!==void 0&&n.firstNumber-1<48?n.firstNumber-1:e;b(r,n.words),m(n.reordered?`Placed the pasted words by their numbers. Check the order.`:``)},S=(e,t)=>{let n=t.currentTarget,r=n.value;t.isComposing?y(e,r):C(e,n)},C=(e,t)=>{let n=t.value;if(!/\s/.test(n)){let r=n.toLowerCase();if(r!==n){let[e,n]=[t.selectionStart,t.selectionEnd];t.value=r,e!==null&&n!==null&&t.setSelectionRange(e,n)}y(e,r);return}let r=Xt(n);r.length>1?b(e,r):(y(e,r[0]??``),r.length===1&&h.current[e+1]?.focus())},w=(t,n)=>{n.isComposing||n.keyCode===229||(n.key===` `||n.key===`Enter`?(n.preventDefault(),h.current[t+1]?.focus()):n.key===`Backspace`&&!e[t]&&t>0?(n.preventDefault(),h.current[t-1]?.focus()):v&&(n.key.length===1||n.key===`Backspace`)&&!n.ctrlKey&&!n.metaKey&&f(t))},T=()=>{u(null),f(null)},E=(e,t)=>{y(e,t),h.current[e]?.focus()},D=_?n.map(t=>[t,Zt(e[t]??``)]).filter(([t,n])=>n!==e[t]&&Gt(n)):[],O=D.length>0&&D.length===n.length,ee=()=>{let t=[...e];for(let[e,n]of D)t[e]=n;r(t)},te=e.filter(Boolean),k=e=>s||v&&d===e,ne=l!==null&&n.includes(l)&&e[l],re=_&&ne&&k(l)?$t(e[l]):[];return H(`div`,{class:`word-grid-wrap`,children:[H(`div`,{class:`word-toolbar`,children:[H(`button`,{type:`button`,class:`button small`,onClick:()=>c(!s),children:[H(U,{name:s?`eyeOff`:`eye`}),` `,s?`Hide words`:`Reveal words`]}),H(`button`,{type:`button`,class:`button small`,disabled:te.length===0,onClick:()=>a(te.join(` `),te.length===e.length?`Seed phrase`:`Seed phrase (only ${te.length} of ${e.length} words)`),children:[H(U,{name:`copy`}),` Copy phrase`]}),H(`span`,{class:`muted small helper`,children:[`Tip: paste a whole phrase into word 1.`,Mt()?` Phrases in other scripts (Japanese, Chinese…) can only be pasted on phones.`:``]})]}),H(`ol`,{class:`word-grid`,"aria-label":`Seed words`,children:e.map((t,r)=>{let a=k(r),o=n.includes(r)&&l!==r;return H(`li`,{class:`word ${o?`word-invalid`:``}`,children:[H(`span`,{class:`word-index`,"aria-hidden":`true`,children:r+1}),H(`input`,{ref:e=>{e&&!g.current.has(e)&&(g.current.add(e),e.type===`text`&&(e.type=`password`,e.type=`text`)),h.current[r]=e},class:`input mono`,...a?{type:`text`,list:_?`bip39-words`:void 0}:{type:`password`},value:t,"aria-label":`Word ${r+1}`,"aria-invalid":o,enterkeyhint:r===e.length-1?`done`:`next`,readOnly:i,onInput:e=>S(r,e),onPaste:e=>x(r,e),onKeyDown:e=>w(r,e),onFocus:()=>u(r),onBlur:T,oncompositionend:e=>C(r,e.currentTarget),...Nt})]},r)})}),re.length>0&&H(`p`,{class:`hint`,role:`status`,children:[`Not in the wordlist. Did you mean:`,` `,re.map(e=>H(`button`,{type:`button`,class:`link-button`,onMouseDown:e=>e.preventDefault(),onClick:()=>E(l,e),children:e},e)),`?`]}),O&&!i&&H(`p`,{class:`hint`,children:[H(`button`,{type:`button`,class:`button small`,onClick:ee,children:`Expand abbreviated words`}),` `,H(`span`,{class:`muted small`,children:`Only for English BIP39 phrases.`})]}),p&&H(`p`,{class:`hint`,role:`status`,children:p})]})},hn=Object.fromEntries(Object.entries(J).map(([e,t])=>[e,t.label])),gn={mnemonic:`Seed phrases`,privateKey:`Wallet keys`,sshKey:`SSH keys`,pgpKey:`PGP keys`,apiKey:`API keys and tokens`,genericKey:`Other keys`,recoveryCodes:`Recovery codes`,other:`Other secrets`},_n={mnemonic:`seed`,privateKey:`wallet`,sshKey:`terminal`,pgpKey:`mail`,apiKey:`code`,genericKey:`key`,recoveryCodes:`list`,other:`lock`},vn=[[`none`,`No grouping`],[`kind`,`Type`],[`chain`,`Chain or service`],[`wallet`,`Wallet or account`],[`tag`,`First tag`]],yn=e=>`Untitled ${/^[A-Z][A-Z]/.test(e)?e:e.toLowerCase()}`,bn=e=>{let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleDateString(void 0,{year:`numeric`,month:`long`,day:`numeric`})},xn=new Map([...`123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`].map((e,t)=>[e,BigInt(t)])),Sn=e=>{let t=0n;for(let n of e){let e=xn.get(n);if(e===void 0)return null;t=t*58n+e}let n=[];for(;t>0n;)n.unshift(Number(t%256n)),t/=256n;let r=0;for(;r{let t=Sn(e);if(!t||t.length<5)return null;let n=t.slice(0,-4);return Ke((await We(await We(n))).slice(0,4),t.slice(-4))?n:null},wn=`qpzry9x8gf2tvdw0s3jn54khce6mua7l`,Tn=1,En=734539939,Dn=e=>{let t=[996825010,642813549,513874426,1027748829,705979059],n=1;for(let r of e){let e=n>>>25;n=(n&33554431)<<5^r;for(let r=0;r<5;r++)e>>>r&1&&(n^=t[r])}return n>>>0},On=e=>[...[...e].map(e=>e.charCodeAt(0)>>5),0,...[...e].map(e=>e.charCodeAt(0)&31)],kn=/^(nsec|npub|bc|tb|ltc|age|age-secret-key-)$|_x?[sv]k$|xprv|xpub|^addr|^stake/,An=e=>{if(e!==e.toLowerCase()&&e!==e.toUpperCase())return null;let t=e.toLowerCase(),n=t.lastIndexOf(`1`);if(n<1||n+7>t.length)return null;let r=t.slice(0,n),i=[];for(let e of t.slice(n+1)){let t=wn.indexOf(e);if(t===-1)return null;i.push(t)}let a=Dn([...On(r),...i]),o=a===Tn?`bech32`:a===En?`bech32m`:null;return o?{hrp:r,variant:o,words:i.slice(0,-6)}:null},jn=e=>{let t=0,n=0,r=[];for(let i of e)for(t=t<<5|i,n+=5;n>=8;)n-=8,r.push(t>>n&255);return n>=5||t&(1<Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``),Fn=e=>{let t;try{t=JSON.parse(e)}catch{return null}if(Array.isArray(t)&&t.length===0)return{level:`info`,label:`Empty list`};if(Array.isArray(t)&&t.every(e=>Number.isInteger(e)&&e>=0&&e<=255))return t.length===64?{level:`ok`,label:`Byte array, 64 bytes`,detail:`Solana CLI keypair file format.`}:{level:`info`,label:`Byte array, ${t.length} bytes`};if(t&&typeof t==`object`){let e=t;if(e.crypto&&Number(e.version)===4&&typeof e.pubkey==`string`)return{level:`ok`,label:`Encrypted keystore (EIP-2335, Ethereum validator)`,detail:`Store its password in the keystore password field.`};if((e.crypto||e.Crypto)&&Number(e.version)===3)return{level:`ok`,label:`Encrypted keystore (Web3 Secret Storage v3)`,detail:`Store its password in the keystore password field.`};if(e.type===`service_account`&&typeof e.private_key==`string`)return{level:`ok`,label:`Google Cloud service account key`,detail:`JSON key file with a private key.`};let n=Array.isArray(e.keys)?e.keys.filter(e=>e&&typeof e==`object`):[e],r=n.find(e=>`d`in e||`k`in e)??n[0];return r&&typeof r.kty==`string`?`d`in r||`k`in r?{level:`ok`,label:`JSON Web Key (${r.kty}, private)`}:{level:`warn`,label:`JSON Web Key (${r.kty}, public)`,detail:Q}:{level:`info`,label:`JSON document`}}return null},In={"ssh-ed25519":`Ed25519`,"ssh-rsa":`RSA`,"ssh-dss":`DSA`,"ecdsa-sha2-nistp256":`ECDSA P-256`,"ecdsa-sha2-nistp384":`ECDSA P-384`,"ecdsa-sha2-nistp521":`ECDSA P-521`,"sk-ssh-ed25519@openssh.com":`Ed25519 security key`,"sk-ecdsa-sha2-nistp256@openssh.com":`ECDSA security key`},Ln=e=>{let t;try{t=He(e.replace(/\s+/g,``))}catch{return null}if(Re(t.slice(0,15))!==`openssh-key-v1\0`)return null;let n=15,r=new DataView(t.buffer,t.byteOffset,t.byteLength),i=()=>{if(n+4>t.length)throw Error(`truncated`);let e=r.getUint32(n);if(n+=4,n+e>t.length)throw Error(`truncated`);let i=t.slice(n,n+e);return n+=e,i};try{let e=Re(i());i(),i(),n+=4;let t=i(),r=i(),a=new DataView(t.buffer,t.byteOffset).getUint32(0),o=Re(t.slice(4,4+a)),s=e!==`none`;if(!s){let e=new DataView(r.buffer,r.byteOffset,r.byteLength);if(r.length<8||e.getUint32(0)!==e.getUint32(4))return null}return{keyType:o,encrypted:s}}catch{return null}},Rn=e=>{let t=11994318;for(let n of e){t^=n<<16;for(let e=0;e<8;e++)t<<=1,t&16777216&&(t^=25578747)}return t&16777215},zn=e=>{let t=e.split(/\r?\n/).map(e=>e.trim()),n=t.indexOf(``),r=t.slice(n===-1?1:n+1).filter(e=>e&&!e.startsWith(`-----`)),i=r.findIndex(e=>/^=[A-Za-z0-9+/]{4}$/.test(e));if(i===-1)return null;try{let e=He(r.slice(0,i).join(``)),t=He(r[i].slice(1));return Rn(e)===(t[0]<<16|t[1]<<8|t[2])}catch{return!1}},Bn={"PUBLIC KEY":`PEM public key`,"RSA PUBLIC KEY":`PEM RSA public key`,CERTIFICATE:`Certificate`,"PGP PUBLIC KEY BLOCK":`PGP public key block`},Vn={"PGP MESSAGE":`PGP message`,"PGP SIGNATURE":`PGP signature`,"PGP SIGNED MESSAGE":`PGP signed message`},Hn=e=>{if(e.includes(`:`))return null;let t;try{t=He(e.replace(/\s+/g,``))}catch{return!1}if(t.length<2||t[0]!==48)return!1;let n=t[1],r=2;if(n&128){let e=n&127;if(e<1||e>4||t.length<2+e)return!1;n=0;for(let r=0;r{let r=/Proc-Type:\s*4,ENCRYPTED/i.test(t);if(Vn[e])return{level:`warn`,label:Vn[e],detail:`This is not a key.`};if(Bn[e])return{level:`warn`,label:Bn[e],detail:Q};if(/PRIVATE KEY$/.test(e)&&e!==`OPENSSH PRIVATE KEY`&&Hn(t)===!1)return{level:`error`,label:`Private key block is damaged or incomplete`,detail:`A line may be missing or changed.`};switch(e){case`OPENSSH PRIVATE KEY`:{let e=Ln(t);return e?{level:`ok`,label:`OpenSSH private key (${In[e.keyType]??e.keyType})`,detail:e.encrypted?`Protected by a passphrase.`:`Not passphrase-protected.`}:{level:`error`,label:`OpenSSH private key, but it could not be read`,detail:`Check that it was copied completely.`}}case`PGP PRIVATE KEY BLOCK`:{let e=zn(n);return e===!1?{level:`error`,label:`PGP private key, but the checksum fails`,detail:`Check for a typo or missing line.`}:{level:`ok`,label:`PGP private key block`,detail:e?`Checksum OK.`:void 0}}case`RSA PRIVATE KEY`:return{level:`ok`,label:`PEM RSA private key (PKCS#1)`,detail:r?`Protected by a passphrase.`:void 0};case`EC PRIVATE KEY`:return{level:`ok`,label:`PEM EC private key (SEC1)`,detail:r?`Protected by a passphrase.`:void 0};case`DSA PRIVATE KEY`:return{level:`ok`,label:`PEM DSA private key`,detail:r?`Protected by a passphrase.`:void 0};case`PRIVATE KEY`:return{level:`ok`,label:`PEM private key (PKCS#8)`};case`ENCRYPTED PRIVATE KEY`:return{level:`ok`,label:`PEM private key (PKCS#8)`,detail:`Protected by a passphrase.`};default:return{level:`info`,label:`PEM block (${e.toLowerCase()})`}}},Wn=e=>/PRIVATE KEY/.test(e),Gn=e=>{let t=[...e.matchAll(/-----BEGIN ([A-Z0-9 ]+)-----([\s\S]*?)-----END \1-----/g)],n=(e.match(/-----BEGIN [A-Z0-9 ]+-----/g)??[]).length,r={level:`error`,label:`Key block is incomplete`,detail:`The matching -----END ...----- line is missing.`},i=t.find(e=>Wn(e[1]));if(i)return Un(i[1],i[2],i[0]);let a=/-----BEGIN (PGP MESSAGE|PGP SIGNATURE|PGP SIGNED MESSAGE)-----/.exec(e);if(a)return{level:`warn`,label:Vn[a[1]],detail:`This is not a key.`};if(n>t.length)return r;if(!t.length)return null;let o=t.map(e=>Un(e[1],e[2],e[0]));return o.find(e=>e.level===`warn`)??o[0]},Kn=[{pattern:/^gh[pousr]_[A-Za-z0-9]{36,}$/,label:`GitHub token`},{pattern:/^github_pat_\w{50,}$/,label:`GitHub fine-grained token`},{pattern:/^glpat-[\w-]{20,}$/,label:`GitLab access token`},{pattern:/^npm_[A-Za-z0-9]{36}$/,label:`npm access token`},{pattern:/^(sk|rk)_(live|test)_[A-Za-z0-9]{16,}$/,label:`Stripe secret key`},{pattern:/^pk_(live|test)_[A-Za-z0-9]{16,}$/,label:`Stripe publishable key`,level:`warn`,detail:Q},{pattern:/^xox[abposr]-[A-Za-z0-9-]{10,}$/,label:`Slack token`},{pattern:/^AIza[\w-]{35}$/,label:`Google API key`},{pattern:/^(AKIA|ASIA)[0-9A-Z]{16}$/,label:`AWS access key ID`,level:`info`,detail:`The 40-character secret access key is a separate value; store it as well.`},{pattern:/^SG\.[\w-]{22}\.[\w-]{43}$/,label:`SendGrid API key`},{pattern:/^dop_v1_[a-f0-9]{64}$/,label:`DigitalOcean token`},{pattern:/^sk-[\w-]{20,}$/,label:`API secret key (sk-…)`},{pattern:/^eyJ[\w-]+\.eyJ[\w-]+\.[\w-]*$/,label:`JSON Web Token`,level:`info`,detail:`Tokens like this usually expire.`}],qn=async e=>{let t=e.trim();if(!t)return null;if(/^\[[\w .-]+\][ \t]*\r?$/.test(t.split(` +`)[0])&&/^[ \t]*[\w.-]+[ \t]*=/m.test(t))return/aws_secret_access_key\s*=/i.test(t)?{level:`ok`,label:`AWS credentials file`,detail:`Contains a secret access key.`}:{level:`info`,label:`Settings file (INI)`};let n=/^\[([0-9a-fA-F]{8}(?:\/\d+['hH]?)*)\]\s*(?=\S)/.exec(t);if(n){let e=await qn(t.slice(n[0].length));if(e)return{...e,detail:[e.detail,`Key origin [${n[1]}].`].filter(Boolean).join(` `)}}if(t.startsWith(`{`)||t.startsWith(`[`))return Fn(t)??{level:`warn`,label:`Looks like JSON, but it does not parse.`};let r=/^AGE-SECRET-KEY-1[0-9A-Z]+$/m.exec(t);if(r&&t.includes(` +`))return qn(r[0]);if(/^---- BEGIN SSH2 PUBLIC KEY ----/m.test(t))return{level:`warn`,label:`SSH public key (SSH2 format)`,detail:Q};let i=Gn(t);if(i)return i;let a=/^PuTTY-User-Key-File-\d+:\s*(\S+)/.exec(t);if(a){let e=/^Private-Lines:\s*(\d+)\s*$/m.exec(t);if(e&&(t.slice(e.index+e[0].length).split(` +`).map(e=>e.trim()).filter(e=>e&&!/^Private-MAC:/.test(e)).filter(e=>/^[A-Za-z0-9+/=]+$/.test(e)).lengthe.pattern.test(t));if(s)return{level:s.level??`ok`,label:s.label,detail:s.detail};let c=Xt(t);if(c.length>=12&&c.length<=48&&c.every(Gt))return{level:`warn`,label:`Looks like a ${c.length}-word seed phrase`,detail:`Use a "Seed phrase" entry to get word-by-word checks.`};if(/^(0x)?[0-9a-fA-F]+$/i.test(t)&&t.replace(/^0x/i,``).length%2==0){let e=Be(t.replace(/^0X/,`0x`)),n=/^0x/i.test(t);return e.length===32?{level:`ok`,label:`Hex, 32 bytes${n?` (0x-prefixed)`:``}`,detail:`Raw 256-bit private key (Ethereum/EVM, Bitcoin, Cosmos and others).`}:e.length===20?{level:`warn`,label:`Hex, 20 bytes`,detail:Q+` (EVM address length)`}:e.length===33||e.length===65?{level:`warn`,label:`Hex, ${e.length} bytes`,detail:Q+` (public key length)`}:{level:`info`,label:`Hex, ${e.length} bytes`}}let l=An(t);if(l){let e=l.variant===`bech32`?jn(l.words):null;switch(l.hrp){case`age-secret-key-`:return e?.length===32?{level:`ok`,label:`age secret key`,detail:`Checksum OK.`}:{level:`error`,label:`age secret key with unexpected length`,detail:`Check that it was copied completely.`};case`age`:return{level:`warn`,label:`age recipient (public key)`,detail:Q};case`nsec`:return e?.length===32?{level:`ok`,label:`Nostr private key (nsec)`,detail:`Checksum OK.`}:{level:`error`,label:`nsec with unexpected length`};case`npub`:return{level:`warn`,label:`Nostr public key (npub)`,detail:Q};case`bc`:case`tb`:case`ltc`:return{level:`warn`,label:`Address (bech32)`,detail:Q};default:return/_x?sk$/.test(l.hrp)||l.hrp.includes(`xprv`)?{level:`ok`,label:`Bech32 secret key (${l.hrp})`,detail:`Checksum OK.`}:/_x?vk$/.test(l.hrp)||l.hrp.includes(`xpub`)||l.hrp.startsWith(`addr`)||l.hrp.startsWith(`stake`)?{level:`warn`,label:`Bech32 (${l.hrp})`,detail:Q}:{level:`info`,label:`Bech32 data (${l.hrp})`,detail:`Checksum OK.`}}}{let e=t.toLowerCase(),n=/^([a-z0-9_-]+)1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]{6,}$/.exec(e);if(n&&(t===e||t===t.toUpperCase())&&kn.test(n[1]))return{level:`error`,label:`Bech32 checksum fails`,detail:`Check for a typo.`}}if(/^[A-Za-z0-9+/]+={0,2}$/.test(t)&&t.length%4==0&&/[+/=]/.test(t))try{let e=He(t);return e.length===32?{level:`ok`,label:`Base64, 32 bytes`,detail:`The format of WireGuard keys and many other 256-bit keys.`}:{level:`info`,label:`Base64, ${e.length} bytes`}}catch{}if(t.length<=200&&/^[1-9A-HJ-NP-Za-km-z]+$/.test(t)){if(Ue()){let e=await Cn(t);if(e){if(e.length===78){let t=Mn[Pn(e.slice(0,4))];return t?t.private?{level:`ok`,label:`Extended private key (${t.name})`,detail:`${t.note}. Checksum OK.`}:{level:`warn`,label:`Extended public key (${t.name})`,detail:Q}:{level:`info`,label:`Extended key (unknown version)`,detail:`Checksum OK.`}}let t=Nn[e[0]];return t&&(e.length===33||e.length===34&&e[33]===1)?{level:`ok`,label:`WIF private key (${t}, ${e.length===34?`compressed`:`uncompressed`})`,detail:`Checksum OK.`}:e.length===21?{level:`warn`,label:`Address (Base58Check)`,detail:Q}:{level:`info`,label:`Base58Check, ${e.length} bytes`,detail:`Checksum OK.`}}let n=Sn(t);if(n&&(n.length===37||n.length===38)&&Nn[n[0]])return{level:`error`,label:`Looks like WIF, but the checksum fails`,detail:`Check for a typo.`};if(/^(?:[xyztuvYZUV](?:prv|pub)|[LM]t(?:pv|ub)|dg(?:pv|ub))/.test(t)){if(t.length===111)return{level:`error`,label:`Looks like an extended key, but the checksum fails`,detail:`Check for a typo.`};if(t.length===110||t.length===112)return{level:`error`,label:`Looks like an extended key, but a character may be missing or extra`,detail:`Extended keys are 111 characters.`}}}let e=Sn(t);if(e?.length===64)return{level:`ok`,label:`Base58, 64 bytes`,detail:`Solana-style keypair (Phantom/Solflare export).`};if(e?.length===32)return{level:`info`,label:`Base58, 32 bytes`,detail:`Could be an ed25519 secret seed, or a Solana address.`};if(e)return{level:`info`,label:`Base58, ${e.length} bytes`}}return{level:`info`,label:`Unrecognized format`,detail:`Stored as typed.`}},Jn=async e=>{let t=e.trim();if(!t)return null;if(/-----BEGIN [A-Z0-9 ]*PRIVATE KEY[A-Z0-9 ]*-----/.test(t))return`a private key block`;let n=t.split(/[\s,;()[\]]+/).map(e=>e.split(`/`)[0]).filter(e=>e.length>=40);for(let e of[t,...n]){let t=await qn(e);if(t?.level===`ok`&&!/^(Hex|Base64)/.test(t.label))return t.label}return null},Yn=`Bitcoin.Ethereum.Solana.Cardano.Monero.Litecoin.Dogecoin.Polkadot.Cosmos.Avalanche.Polygon.BNB Chain.Arbitrum.Base.Optimism.Tron.XRP Ledger.Tezos.Algorand.Stellar.Near.Sui.Aptos.Lightning (LND).Nostr.Multi-chain`.split(`.`),Xn=[`Ledger`,`Trezor`,`Coldcard`,`BitBox02`,`Keystone`,`Blockstream Jade`,`Foundation Passport`,`Sparrow`,`Electrum`,`Nunchuk`,`BlueWallet`,`Phoenix`,`MetaMask`,`Rabby`,`Rainbow`,`Phantom`,`Solflare`,`Exodus`,`Trust Wallet`,`Coinbase Wallet`,`Cake Wallet`,`Feather`,`Monero GUI`],Zn=[`GitHub`,`GitLab`,`Bitbucket`,`AWS`,`Google Cloud`,`Azure`,`Cloudflare`,`DigitalOcean`,`Vercel`,`Stripe`,`Slack`,`npm`,`Docker Hub`,`Apple ID`,`Google account`,`Microsoft account`,`Proton`,`Standard Notes`,`Coinbase`,`Kraken`,`Binance`,`Gemini`,`Bitstamp`],Qn=[[`m/44'/0'/0'`,`BTC legacy (BIP44)`],[`m/49'/0'/0'`,`BTC nested SegWit (BIP49)`],[`m/84'/0'/0'`,`BTC native SegWit (BIP84)`],[`m/86'/0'/0'`,`BTC Taproot (BIP86)`],[`m/48'/0'/0'/2'`,`BTC multisig (BIP48)`],[`m/44'/60'/0'/0/0`,`Ethereum / EVM`],[`m/44'/501'/0'/0'`,`Solana`],[`m/1852'/1815'/0'`,`Cardano`],[`m/44'/118'/0'/0/0`,`Cosmos`]],$n=()=>H(C,{children:[H(`datalist`,{id:`chains`,children:Yn.map(e=>H(`option`,{value:e}))}),H(`datalist`,{id:`wallets`,children:Xn.map(e=>H(`option`,{value:e}))}),H(`datalist`,{id:`services`,children:Zn.map(e=>H(`option`,{value:e}))}),H(`datalist`,{id:`paths`,children:Qn.map(([e,t])=>H(`option`,{value:e,label:t}))})]}),er=(e,t,n=`${t}s`)=>`${e} ${e===1?t:n}`,$=({label:e,hint:t,children:n,wide:r,safety:i})=>H(`div`,{class:`field ${r?`field-wide`:``}`,children:[H(`label`,{class:`field-control`,children:[H(`span`,{class:`field-label`,children:e}),n]}),t&&H(`span`,{class:`hint ${i?`hint-safety`:``}`,children:t})]}),tr=({id:e,title:t,icon:n,summary:r,defaultOpen:i,action:a,children:o})=>{let[s]=z(i),[c,l]=Ot(e,s),u=`section-${e.replace(/[^a-z0-9]/gi,`-`)}`;return H(`section`,{class:`section ${c?`open`:`closed`}`,children:[H(`header`,{class:`section-header`,children:[H(`h3`,{class:`section-heading`,children:H(`button`,{type:`button`,class:`section-toggle`,"aria-expanded":c,"aria-controls":u,onClick:()=>l(!c),children:[H(U,{name:`chevron`,size:14,class:`chevron`}),n&&H(U,{name:n}),H(`span`,{children:t}),!c&&r&&H(`span`,{class:`section-summary`,children:r})]})}),a&&H(`button`,{type:`button`,class:`button small`,onClick:()=>{a.onClick(),l(!0)},children:[H(U,{name:`plus`}),` `,a.label]})]}),c&&H(`div`,{class:`section-body`,id:u,children:o})]})},nr={valid:`ok`,invalid:`error`,incomplete:`info`,unchecked:`info`},rr=({entry:e,update:t,showLabel:n,focusLabel:r})=>{let{readOnly:i}=Z(),a=V(null);B(()=>{r&&a.current?.focus()},[]);let o=J[e.kind],s=Xe(e.kind),c=Tt(e),l=[e.description&&`description`,e.createdOn&&`created ${e.createdOn}`,e.expiresOn&&o.expires&&`expires ${e.expiresOn}`].filter(Boolean).join(` · `);return H(tr,{id:`${e.id}:details`,title:`Details`,summary:l||`empty`,defaultOpen:!e.label,children:[n&&H($,{label:`Label`,wide:!0,children:H(`input`,{ref:a,class:`input`,value:e.label,placeholder:yn(hn[e.kind]),readOnly:i,onInput:e=>t({label:e.currentTarget.value})})}),H($,{label:`Description`,wide:!0,children:H(`textarea`,{class:`input`,rows:2,value:e.description,placeholder:`What is this wallet or key for?`,readOnly:i,onInput:e=>t({description:e.currentTarget.value}),...Nt,"data-secret":void 0})}),sr(e,e.description)&&H(`p`,{class:`status status-error`,role:`status`,children:[H(U,{name:`alert`}),` This text repeats the entry's secret, and it is not hidden.`]}),H(`div`,{class:`row`,children:[s?H(C,{children:[H($,{label:o.serviceLabel,children:H(`input`,{class:`input`,list:`chains`,value:e.chain,readOnly:i,onInput:e=>t({chain:e.currentTarget.value})})}),H($,{label:o.accountLabel,children:H(`input`,{class:`input`,list:`wallets`,value:e.wallet,readOnly:i,onInput:e=>t({wallet:e.currentTarget.value})})})]}):H(C,{children:[H($,{label:o.serviceLabel,children:H(`input`,{class:`input`,list:`services`,value:e.service,readOnly:i,onInput:e=>t({service:e.currentTarget.value})})}),H($,{label:o.accountLabel,children:H(`input`,{class:`input`,value:e.account,readOnly:i,onInput:e=>t({account:e.currentTarget.value}),...Pt})})]}),H($,{label:`Date created`,children:H(`input`,{class:`input`,type:`date`,value:e.createdOn,readOnly:i,onInput:e=>t({createdOn:e.currentTarget.value})})}),o.expires&&H($,{label:`Expires on`,hint:c===null?`Optional. You are warned 30 days ahead.`:void 0,children:H(`input`,{class:`input`,type:`date`,value:e.expiresOn,readOnly:i,onInput:e=>t({expiresOn:e.currentTarget.value})})})]}),c!==null&&c<=30&&H(`p`,{class:`status ${c<0?`status-error`:`status-warn`}`,children:[H(U,{name:`clock`}),` `,c<0?`Expired on ${e.expiresOn}.`:c===0?`Expires today.`:`Expires in ${c} day${c===1?``:`s`}.`]}),H($,{label:`Tags`,hint:`Comma separated.`,wide:!0,children:H(xr,{tags:e.tags,onChange:e=>t({tags:e})})})]})},ir=({entry:e,update:t})=>{let{readOnly:n,confirm:r,toast:i}=Z(),a=V(e);a.current=e;let o=At(()=>rn(e.scheme,e.words),[e.scheme,e.words.join(` `)]),s=zt.find(t=>t.id===e.scheme),c=[...new Set([...s.counts,...Bt])].sort((e,t)=>e-t),l=e.words.filter(Boolean).length,[u,d]=z(!1),f=async n=>{if(!Number.isInteger(n)||n<1||n>48||n===e.words.length)return!1;let o=e.words,s=o.slice(n).filter(Boolean).length;if(s>0){if(!await r({title:`Remove words?`,message:`Shrinking to ${n} words removes ${s} word${s===1?``:`s`} you entered.`,confirmLabel:`Remove`,danger:!0}))return!1;if(a.current.words.join(` +`)!==o.join(` +`))return i(`The words changed while this was open. Nothing was removed.`,`error`),!1}return t({words:Array.from({length:n},(e,t)=>o[t]??``)}),!0},p=n=>{let r=zt.find(e=>e.id===n);l===0&&r.counts.length&&!r.counts.includes(e.words.length)?t({scheme:n,words:Array(r.counts[0]).fill(``)}):t({scheme:n})},m=`${s.label} · ${l===e.words.length?er(l,`word`):`${l} of ${e.words.length} words`}${e.passphrase?` + passphrase`:``}`;return H(tr,{id:`${e.id}:seed`,title:`Seed phrase`,icon:`seed`,summary:m,defaultOpen:!0,children:[H(`div`,{class:`row`,children:[H($,{label:`Scheme`,children:H(`select`,{class:`input`,value:e.scheme,disabled:n,onChange:e=>p(e.currentTarget.value),children:zt.map(e=>H(`option`,{value:e.id,children:e.label}))})}),H($,{label:`Words`,children:H(`select`,{class:`input`,value:u||!c.includes(e.words.length)?`custom`:String(e.words.length),disabled:n,onChange:async t=>{let n=t.currentTarget,r=n.value;r===`custom`?d(!0):(d(!1),await f(Number(r))||(n.value=c.includes(e.words.length)?String(e.words.length):`custom`))},children:[c.map(e=>H(`option`,{value:String(e),children:[e,s.counts.includes(e)?``:` (non-standard)`]})),H(`option`,{value:`custom`,children:`Custom…`})]})}),(u||!c.includes(e.words.length))&&H($,{label:`Custom count`,children:H(`input`,{class:`input`,type:`number`,min:1,max:48,value:e.words.length,readOnly:n,onChange:e=>f(Number(e.currentTarget.value))})})]}),H(mn,{words:e.words,scheme:e.scheme,unknownWords:o?.unknownWords??[],onChange:e=>t({words:e})}),o&&H(`p`,{class:`status status-${nr[o.status]}`,role:`status`,children:[H(U,{name:o.status===`valid`?`check`:o.status===`invalid`?`alert`:`shield`}),` `,o.message]}),H(cr,{entry:e,update:t})]})},ar=e=>setTimeout(()=>document.querySelector(`[data-row="${e}"] input`)?.focus()),or=e=>e.passphrase.length>=4&&e.passphraseHint.toLowerCase().includes(e.passphrase.toLowerCase()),sr=(e,t)=>{let n=t.toLowerCase();if(!n)return!1;if(e.secret.trim().length>=12&&n.includes(e.secret.trim().toLowerCase()))return!0;let r=e.words.filter(Boolean).map(e=>e.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g,`\\$&`));for(let e=0;e+4<=r.length;e++)if(RegExp(`\\b${r.slice(e,e+4).join(`\\s+`)}\\b`).test(n))return!0;return!1},cr=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=J[e.kind];return r.passphraseLabel?H(`div`,{class:`row`,children:[H($,{label:r.passphraseLabel,hint:r.passphraseHint,safety:!0,children:H(Ft,{label:r.passphraseLabel,value:e.passphrase,onInput:e=>t({passphrase:e}),placeholder:`None`})}),H($,{label:`Passphrase hint`,hint:`Not hidden. Never write the passphrase itself here.`,safety:!0,children:H(`input`,{class:`input`,value:e.passphraseHint,readOnly:n,onInput:e=>t({passphraseHint:e.currentTarget.value}),...Pt})}),or(e)&&H(`p`,{class:`status status-error field-wide`,role:`status`,children:[H(U,{name:`alert`}),` The hint contains the passphrase. Anyone who opens this note can read it.`]})]}):null},lr={ok:`ok`,info:`info`,warn:`warn`,error:`error`},ur=({entry:e,update:t})=>{let n=J[e.kind],r=At(()=>qn(e.secret),[e.secret]);return H(tr,{id:`${e.id}:key`,title:n.secretLabel,icon:`key`,summary:e.secret?r?.label??`set`:`empty`,defaultOpen:!0,children:[H($,{label:n.secretLabel,wide:!0,children:H(Ft,{label:n.secretLabel,value:e.secret,onInput:e=>t({secret:e}),placeholder:n.secretPlaceholder,multiline:n.secret===`key`&&(e.kind!==`privateKey`||e.secret.includes(` +`)),onMultilinePaste:e=>t({secret:e}),mono:!0})}),H(`p`,{class:`status ${r?`status-${lr[r.level]}`:``}`,role:`status`,children:r&&H(C,{children:[H(U,{name:r.level===`ok`?`check`:r.level===`info`?`shield`:`alert`}),` `,r.label,r.detail&&H(`span`,{class:`muted`,children:[` · `,r.detail]})]})}),H(cr,{entry:e,update:t})]})},dr=({entry:e,update:t})=>{let n=e.secret.split(/\n/).filter(e=>e.trim()).length;return H(tr,{id:`${e.id}:codes`,title:`Recovery codes`,icon:`list`,summary:n?`${n} code${n===1?``:`s`}`:`empty`,defaultOpen:!0,children:H($,{label:`Codes`,hint:`One per line. Delete or mark a code once used.`,wide:!0,children:H(Ft,{label:`Recovery codes`,value:e.secret,onInput:e=>t({secret:e}),placeholder:`One code per line`,multiline:!0,mono:!0})})})},fr=({text:e})=>{let t=At(()=>Jn(e),[e]);return t?H(`p`,{class:`status status-error`,role:`status`,children:[H(U,{name:`alert`}),` This looks like private key material (`,t,`). This field is not hidden: move it to the secret field.`]}):null},pr=(e,t)=>{let n=e.trim();return t&&(n=n.replace(/^\[([0-9a-fA-F]{8})[^\]]*\].*$/,`$1`).replace(/^0x/i,``).replace(/\s+/g,``)),n},mr=e=>e.trim().replace(/[’‘′`]/g,`'`).replace(/^M\//,`m/`),hr=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=J[e.kind].publicKey;if(!r)return null;let i=At(()=>Jn(e.fingerprint),[e.fingerprint]),a=[e.publicInfo&&`public key`,e.fingerprint&&(i?`fingerprint`:e.fingerprint)].filter(Boolean).join(` · `),o=e.kind===`pgpKey`&&e.fingerprint&&!/^([0-9a-fA-F]{40}|[0-9a-fA-F]{64})$/.test(e.fingerprint.replace(/\s/g,``));return H(tr,{id:`${e.id}:public`,title:`Public info`,icon:`eye`,summary:a||`empty`,defaultOpen:!1,children:[H(`p`,{class:`muted small helper`,children:`Not secret. Lets you match this entry to a server, keyring or recipient.`}),H($,{label:r.label,wide:!0,children:H(`textarea`,{class:`input mono`,rows:e.publicInfo?3:2,value:e.publicInfo,placeholder:r.placeholder,readOnly:n,onInput:e=>t({publicInfo:e.currentTarget.value}),...Pt})}),H(fr,{text:e.publicInfo}),H($,{label:r.fingerprintLabel,wide:!0,children:H(`input`,{class:`input mono`,value:e.fingerprint,placeholder:r.fingerprintPlaceholder,readOnly:n,onInput:e=>t({fingerprint:e.currentTarget.value}),onBlur:n=>{let r=pr(n.currentTarget.value,!1);r!==e.fingerprint&&t({fingerprint:r})},...Pt})}),H(fr,{text:e.fingerprint}),o&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` PGP fingerprints are 40 hex characters (64 for newer v6 keys).`]})]})},gr=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=!!(e.derivationPath||e.fingerprint||e.publicInfo),i=At(()=>Jn(e.fingerprint),[e.fingerprint]),a=[e.derivationPath,e.fingerprint&&(i?`fingerprint`:e.fingerprint),e.publicInfo&&`addresses`].filter(Boolean).join(` · `),o=e.derivationPath.trim();return H(tr,{id:`${e.id}:public`,title:`Public info`,icon:`eye`,summary:a||`empty`,defaultOpen:!1,children:[H(`p`,{class:`muted small helper`,children:`Not secret. Helps you recognize the wallet without revealing the secret.`}),H(`div`,{class:`row`,children:[H($,{label:`Derivation path`,children:H(`input`,{class:`input mono`,list:`paths`,value:e.derivationPath,placeholder:`m/84'/0'/0'`,readOnly:n,onInput:e=>t({derivationPath:e.currentTarget.value}),onBlur:n=>{let r=mr(n.currentTarget.value);r!==e.derivationPath&&t({derivationPath:r})},...Pt})}),H($,{label:`Master fingerprint`,children:H(`input`,{class:`input mono`,value:e.fingerprint,placeholder:`e.g. 73c5da0a`,readOnly:n,onInput:e=>t({fingerprint:e.currentTarget.value}),onBlur:n=>{let r=pr(n.currentTarget.value,!0);r!==e.fingerprint&&t({fingerprint:r})},...Pt})})]}),o&&!/^m(\/\d+['hH]?)*$/.test(o)&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` `,/[’‘′`]/.test(o)?`Use straight apostrophes (') in derivation paths; curly ones are fixed when you leave the field.`:`Derivation paths look like m/84'/0'/0'.`]}),e.fingerprint&&!i&&!/^[0-9a-fA-F]{8}$/.test(e.fingerprint.trim())&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` A master fingerprint is 8 hex characters.`]}),H($,{label:`Addresses / xpub`,wide:!0,children:H(`textarea`,{class:`input mono`,rows:r?3:2,value:e.publicInfo,placeholder:`First receive address, xpub/zpub…`,readOnly:n,onInput:e=>t({publicInfo:e.currentTarget.value}),...Pt})}),H(fr,{text:e.publicInfo}),H(fr,{text:e.fingerprint})]})},_r=({entry:e,update:t,reminderMonths:n})=>{let{readOnly:r}=Z(),i=(n,r)=>t({backups:e.backups.map(e=>e.id===n?{...e,...r}:e)}),a=wt(e,n),o=Ct(e),s=H(`span`,{class:a?`status-warn`:void 0,children:[e.backups.length?er(e.backups.length,`location`):`none recorded`,o?` · checked ${o}`:``,a?` · check due`:``]});return H(tr,{id:`${e.id}:backups`,title:`Backups`,icon:`shield`,summary:s,defaultOpen:!1,action:r?void 0:{label:`Add location`,onClick:()=>{let n=qe();t({backups:[...e.backups,{id:n,location:``,verifiedOn:``}]}),ar(n)}},children:[H(`p`,{class:`status ${a?`status-warn`:`status-info`}`,children:[H(U,{name:a?`alert`:`check`}),` `,o?`Last checked ${o}.`:`No backup check recorded.`,a&&n>0&&` Check your backups at least every ${n} months.`]}),e.backups.length===0&&H(`p`,{class:`muted small helper`,children:`Record where copies are kept, like "steel plate in home safe". Do not record the secret itself here.`}),e.backups.map(n=>H(`div`,{class:`row backup-row`,"data-row":n.id,children:[H(`input`,{class:`input grow`,value:n.location,placeholder:`Location, e.g. steel plate in safe`,"aria-label":`Backup location`,readOnly:r,onInput:e=>i(n.id,{location:e.currentTarget.value}),...Pt}),H(`input`,{class:`input`,type:`date`,value:n.verifiedOn,"aria-label":`Last checked`,readOnly:r,onInput:e=>i(n.id,{verifiedOn:e.currentTarget.value})}),!r&&H(C,{children:[H(`button`,{type:`button`,class:`button small`,onClick:()=>i(n.id,{verifiedOn:nt()}),children:`Checked today`}),H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Remove backup location`,title:`Remove`,onClick:()=>t({backups:e.backups.filter(e=>e.id!==n.id)}),children:H(U,{name:`x`})})]})]},n.id))]})},vr=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=(n,r)=>t({customFields:e.customFields.map(e=>e.id===n?{...e,...r}:e)}),i=J[e.kind].secret===`fields`;return H(tr,{id:`${e.id}:fields`,title:i?`Fields`:`Extra fields`,icon:`plus`,summary:e.customFields.length?er(e.customFields.length,`field`):`none`,defaultOpen:i,action:n?void 0:{label:`Add field`,onClick:()=>{let n=qe();t({customFields:[...e.customFields,{id:n,label:``,value:``,hidden:!0}]}),ar(n)}},children:[e.customFields.length===0&&H(`p`,{class:`muted small helper`,children:`For PINs, keystore passwords, 2FA backup codes, multisig details or anything else.`}),e.customFields.map(i=>H(`div`,{class:`custom-field`,"data-row":i.id,children:[H(`input`,{class:`input custom-label`,value:i.label,placeholder:`Label`,"aria-label":`Field label`,readOnly:n,onInput:e=>r(i.id,{label:e.currentTarget.value})}),H(`div`,{class:`custom-value`,children:i.hidden?H(Ft,{label:i.label||`Field`,value:i.value,multiline:i.multiline,onInput:e=>r(i.id,{value:e}),onMultilinePaste:e=>r(i.id,{value:e,multiline:!0})}):i.multiline?H(`textarea`,{class:`input`,rows:3,value:i.value,"aria-label":i.label||`Field value`,readOnly:n,onInput:e=>r(i.id,{value:e.currentTarget.value}),...Pt}):H(`input`,{class:`input`,value:i.value,"aria-label":i.label||`Field value`,readOnly:n,onInput:e=>r(i.id,{value:e.currentTarget.value}),...Pt,onPaste:e=>{let t=e.clipboardData?.getData(`text`)??``;if(!/[\r\n]/.test(t))return;e.preventDefault();let n=e.currentTarget,a=n.selectionStart??i.value.length,o=n.selectionEnd??i.value.length;r(i.id,{value:i.value.slice(0,a)+t+i.value.slice(o),multiline:!0})}})}),!n&&H(`div`,{class:`custom-actions`,children:[H(`label`,{class:`check small`,children:[H(`input`,{type:`checkbox`,checked:i.hidden,"aria-label":`Hide ${i.label||`field`} value`,onChange:e=>r(i.id,{hidden:e.currentTarget.checked})}),` `,`Hidden`]}),H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Remove field`,title:`Remove`,onClick:()=>t({customFields:e.customFields.filter(e=>e.id!==i.id)}),children:H(U,{name:`x`})})]})]},i.id))]})},yr=({entry:e,update:t})=>{let{readOnly:n}=Z();return H(tr,{id:`${e.id}:notes`,title:`Notes`,summary:e.notes?er(e.notes.length,`character`):`empty`,defaultOpen:!!e.notes&&e.kind===`other`,children:[H(`textarea`,{class:`input`,rows:4,value:e.notes,placeholder:`Recovery instructions, inheritance notes, history…`,"aria-label":`Notes`,readOnly:n,onInput:e=>t({notes:e.currentTarget.value}),...Nt}),sr(e,e.notes)&&H(`p`,{class:`status status-error`,role:`status`,children:[H(U,{name:`alert`}),` This text repeats the entry's secret, and it is not hidden.`]})]})},br=e=>{let t=new Set;return e.split(`,`).map(e=>e.trim()).filter(e=>e&&!t.has(e.toLowerCase())&&t.add(e.toLowerCase()))},xr=({tags:e,onChange:t})=>{let{readOnly:n}=Z(),[r,i]=z(e.join(`, `));B(()=>{br(r).join(`,`)!==e.join(`,`)&&i(e.join(`, `))},[e.join(`,`)]);let a=n=>{i(n);let r=br(n);r.join(`,`)!==e.join(`,`)&&t(r)},o=()=>i(br(r).join(`, `));return H(`input`,{class:`input`,value:r,placeholder:`cold storage, inheritance`,readOnly:n,onInput:e=>a(e.currentTarget.value),onBlur:o,onKeyDown:e=>e.key===`Enter`&&o()})},Sr=({lock:e,onEditing:t,children:n})=>{let r=Z(),i=r.readOnly||e===`locked`,a=Ce(()=>i===r.readOnly?r:{...r,readOnly:i},[r,i]),o=e===`locked`;return H(Dt.Provider,{value:a,children:[e!==`off`&&!r.readOnly&&H(`div`,{class:`lock-bar ${e}`,children:[H(U,{name:o?`lock`:`edit`}),H(`span`,{children:o?`Locked against accidental changes.`:`Editing.`}),H(`button`,{type:`button`,class:`button small`,onClick:()=>t(o),children:[H(U,{name:o?`edit`:`check`}),` `,o?`Edit`:`Done`]})]}),n]})},Cr=({entry:e,onUpdate:t,onDelete:n,onDuplicate:r})=>{let{readOnly:i}=Z();return i?null:H(`div`,{class:`entry-actions`,children:[H(`button`,{type:`button`,class:`icon-button ${e.favorite?`active`:``}`,"aria-pressed":e.favorite,"aria-label":`Favorite`,title:`Favorite`,disabled:i,onClick:()=>t({favorite:!e.favorite}),children:H(U,{name:`star`,fill:e.favorite?`currentColor`:`none`})}),!i&&H(C,{children:[H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Duplicate`,title:`Duplicate`,onClick:r,children:H(U,{name:`duplicate`})}),H(`button`,{type:`button`,class:`icon-button ${e.archived?`active`:``}`,"aria-label":e.archived?`Unarchive`:`Archive`,title:e.archived?`Unarchive`:`Archive (e.g. an emptied or retired wallet)`,onClick:()=>t({archived:!e.archived}),children:H(U,{name:`archive`})}),H(`button`,{type:`button`,class:`icon-button danger`,"aria-label":`Delete`,title:`Delete`,onClick:n,children:H(U,{name:`trash`})})]})]})},wr=e=>{let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString()},Tr=({entry:e,reminderMonths:t,onUpdate:n,showLabel:r,focusLabel:i=!1})=>{let{readOnly:a}=Z(),o=e=>!a&&n(e),s=J[e.kind].secret;return H(`div`,{class:`entry-body`,children:[H(rr,{entry:e,update:o,showLabel:r,focusLabel:i}),s===`words`&&H(ir,{entry:e,update:o}),(s===`key`||s===`token`)&&H(ur,{entry:e,update:o}),s===`codes`&&H(dr,{entry:e,update:o}),s===`fields`&&H(vr,{entry:e,update:o}),Xe(e.kind)?H(gr,{entry:e,update:o}):H(hr,{entry:e,update:o}),s!==`fields`&&H(vr,{entry:e,update:o}),H(_r,{entry:e,update:o,reminderMonths:t}),H(yr,{entry:e,update:o}),H(`footer`,{class:`editor-footer muted small`,children:[`Added `,wr(e.addedAt),` · Updated `,wr(e.updatedAt)]})]})},Er=({entry:e,lock:t,reminderMonths:n,onUpdate:r,onDelete:i,onDuplicate:a,onEditing:o,onBack:s,focusLabel:c})=>{let l=Z().readOnly||t===`locked`,u=V(null);return B(()=>{c&&u.current?.focus()},[]),H(`article`,{class:`editor`,"aria-label":e.label||`Untitled entry`,children:[H(`header`,{class:`editor-header`,children:[H(`button`,{type:`button`,class:`icon-button back-button`,"aria-label":`Back to list`,title:`Back`,onClick:s,children:H(U,{name:`back`})}),H(`input`,{ref:u,class:`input title-input`,value:e.label,placeholder:yn(hn[e.kind]),"aria-label":`Label`,readOnly:l,onInput:e=>!l&&r({label:e.currentTarget.value})}),H(`span`,{class:`badge badge-${e.kind}`,children:hn[e.kind]}),H(Cr,{entry:e,onUpdate:r,onDelete:i,onDuplicate:a,onEditing:o})]}),H(`div`,{class:`editor-body`,children:H(Sr,{lock:t,onEditing:o,children:H(Tr,{entry:e,reminderMonths:n,onUpdate:r,showLabel:!1})})})]})},Dr=[[`all`,`All`],[`crypto`,`Crypto`],...Je.map(e=>[e,gn[e]]),[`favorites`,`Favorites`],[`attention`,`Backup check due`],[`expiring`,`Expiring or expired`],[`archived`,`Archived`]],Or=new Intl.Collator(void 0,{numeric:!0,sensitivity:`base`}),kr=(e,t)=>{if(!t)return!0;let n=[e.label,e.description,e.chain,e.wallet,e.service,e.account,e.notes,e.derivationPath,e.fingerprint,e.publicInfo,...e.tags,...e.customFields.flatMap(e=>e.hidden?[e.label]:[e.label,e.value]),...e.backups.map(e=>e.location)].join(` `).toLowerCase();return t.toLowerCase().split(/\s+/).every(e=>n.includes(e))},Ar=(e,t,n,r,i)=>e.filter(e=>t===`archived`?e.archived:!e.archived).filter(e=>{switch(t){case`all`:case`archived`:return!0;case`crypto`:return Xe(e.kind);case`favorites`:return e.favorite;case`attention`:return wt(e,i);case`expiring`:return Et(e);default:return e.kind===t}}).filter(e=>kr(e,r.trim())).sort((e,t)=>e.favorite===t.favorite?n===`label`?!e.label==!t.label?Or.compare(e.label,t.label):e.label?-1:1:n===`created`?(t.createdOn||``).localeCompare(e.createdOn||``):t.updatedAt.localeCompare(e.updatedAt):e.favorite?-1:1),jr=Je,Mr={none:``,kind:``,chain:`No chain or service`,wallet:`No wallet or account`,tag:`Untagged`},Nr=(e,t)=>{if(t===`none`)return[{key:`all`,label:``,entries:e}];let n=e=>t===`kind`?e.kind:t===`chain`?(e.chain||e.service).trim():t===`wallet`?(e.wallet||e.account).trim():(e.tags[0]??``).trim(),r=new Map;for(let i of e){let e=n(i),a=`${t}:${e.toLowerCase()}`,o=r.get(a);o||(o={key:a,label:t===`kind`?gn[e]:e||Mr[t],entries:[]},r.set(a,o)),o.entries.push(i)}let i=[...r.values()];if(t===`kind`)return i.sort((e,t)=>jr.indexOf(e.entries[0].kind)-jr.indexOf(t.entries[0].kind));let a=e=>e.key.endsWith(`:`);return i.sort((e,t)=>Number(a(e))-Number(a(t))||Or.compare(e.label,t.label))},Pr=e=>({order:e.flatMap(e=>e.entries.map(e=>e.id)),groupOf:new Map(e.flatMap(e=>e.entries.map(t=>[t.id,e.key]))),labelOf:new Map(e.map(e=>[e.key,e.label]))}),Fr=(e,t)=>{let n=new Map(t.order.map((e,t)=>[e,t])),r=new Map(e.flatMap(e=>e.entries.map(t=>[t.id,e.key]))),i=new Map(e.map(e=>[e.key,e.label])),a=e.flatMap(e=>e.entries).sort((e,t)=>(n.get(e.id)??-1)-(n.get(t.id)??-1)),o=new Map;for(let e of a){let n=t.groupOf.get(e.id)??r.get(e.id),a=o.get(n);a||(a={key:n,label:t.labelOf.get(n)??i.get(n)??``,entries:[]},o.set(n,a)),a.entries.push(e)}return[...new Set([...t.labelOf.keys(),...e.map(e=>e.key)])].flatMap(e=>o.get(e)??[])},Ir=({entry:e})=>{let t=At(()=>rn(e.scheme,e.words),[e.scheme,e.words.join(` `)]);return!t||t.status===`incomplete`||t.status===`unchecked`?null:t.status===`valid`?H(`span`,{class:`pill pill-ok`,title:t.message,children:[H(U,{name:`check`,size:12}),` checksum`]}):H(`span`,{class:`pill pill-error`,title:t.message,children:[H(U,{name:`alert`,size:12}),` check words`]})},Lr=({entry:e})=>{let t=Tt(e);return t===null||!Et(e)?null:t<0?H(`span`,{class:`pill pill-error`,title:`Expired ${e.expiresOn}`,children:`expired`}):H(`span`,{class:`pill pill-warn`,title:`Expires ${e.expiresOn}`,children:t===0?`expires today`:`expires in ${t} day${t===1?``:`s`}`})},Rr=({entry:e,reminderMonths:t,idPrefix:n})=>{let r=(Xe(e.kind)?[e.chain,e.wallet,e.kind===`mnemonic`?`${e.words.length} words`:``]:[hn[e.kind],e.service,e.account]).filter(Boolean).join(` · `);return H(C,{children:[H(`span`,{class:`entry-icon badge-${e.kind}`,title:hn[e.kind],children:H(U,{name:_n[e.kind]})}),H(`span`,{class:`entry-main`,children:[H(`span`,{class:`entry-title`,id:n&&`${n}-title`,children:[e.favorite&&H(U,{name:`star`,size:12,fill:`currentColor`,class:`star`}),e.label||H(`em`,{class:`muted`,children:yn(hn[e.kind])})]}),r&&H(`span`,{class:`entry-meta`,id:n&&`${n}-meta`,children:r}),H(`span`,{class:`entry-pills`,id:n&&`${n}-pills`,children:[e.kind===`mnemonic`&&H(Ir,{entry:e}),e.passphrase&&H(`span`,{class:`pill`,children:`+ passphrase`}),e.archived&&H(`span`,{class:`pill`,children:`archived`}),H(Lr,{entry:e}),wt(e,t)&&H(`span`,{class:`pill pill-warn`,children:e.backups.length?`backup check due`:`no backup recorded`}),e.tags.map(e=>H(`span`,{class:`pill`,children:e},e))]})]}),e.createdOn&&H(`span`,{class:`entry-date`,children:e.createdOn})]})},zr=({group:e,bare:t,collapsed:n,onToggle:r,children:i})=>{let a=`group-${e.key.replace(/[^a-z0-9]/gi,`-`)}`;return!e.label||t?H(`section`,{class:`group bare`,children:H(`div`,{id:a,children:i})}):H(`section`,{class:`group ${n?`collapsed`:``}`,children:[H(`h2`,{class:`group-heading`,children:H(`button`,{type:`button`,class:`group-toggle`,"aria-expanded":!n,"aria-controls":a,onClick:r,children:[H(U,{name:`chevron`,size:14,class:`chevron`}),H(`span`,{children:e.label}),H(`span`,{class:`count`,children:e.entries.length})]})}),!n&&H(`div`,{id:a,children:i})]})},Br=({groups:e,collapsedGroups:t,selectedId:n,reminderMonths:r,onSelect:i,onToggleGroup:a})=>H(`div`,{class:`entry-list`,children:e.map(o=>H(zr,{group:o,bare:e.length===1,collapsed:t.has(o.key)&&e.length>1,onToggle:()=>a(o.key),children:H(`ul`,{class:`entry-rows`,"aria-label":o.label||`Entries`,children:o.entries.map(e=>H(`li`,{children:H(`button`,{type:`button`,class:`entry-item ${e.id===n?`selected`:``}`,"aria-current":e.id===n,onClick:()=>i(e.id),children:H(Rr,{entry:e,reminderMonths:r})})},e.id))})},o.key))}),Vr=(e,t)=>{let n=Object.keys(e);return n.length===Object.keys(t).length&&n.every(n=>Object.is(e[n],t[n]))},Hr=(e=>class extends w{shouldComponentUpdate(e){return!Vr(this.props,e)}render(t){return x(e,t)}})(({entry:e,lock:t,open:n,reminderMonths:r,isNew:i,onToggle:a,...o})=>{let s=V(null);B(()=>{i&&s.current?.scrollIntoView({block:`nearest`})},[i]);let c=`entry-${e.id}`;return H(`li`,{ref:s,class:`card-entry ${n?`open`:``}`,children:[H(`div`,{class:`card-header`,children:[H(`button`,{type:`button`,class:`card-toggle`,"aria-expanded":n,"aria-controls":c,"aria-labelledby":`${c}-title`,"aria-describedby":`${c}-meta ${c}-pills`,onClick:()=>a(e.id),children:[H(U,{name:`chevron`,size:14,class:`chevron`}),H(Rr,{entry:e,reminderMonths:r,idPrefix:c})]}),n&&H(Cr,{entry:e,...o})]}),n&&H(`div`,{class:`card-body`,id:c,children:H(Sr,{lock:t,onEditing:o.onEditing,children:H(Tr,{entry:e,reminderMonths:r,onUpdate:o.onUpdate,showLabel:!0,focusLabel:i})})})]})}),Ur=({groups:e,expanded:t,collapsedGroups:n,reminderMonths:r,newId:i,lockFor:a,onToggle:o,onToggleGroup:s,handlersFor:c})=>H(`div`,{class:`stack`,children:e.map(l=>H(zr,{group:l,bare:e.length===1,collapsed:n.has(l.key)&&e.length>1,onToggle:()=>s(l.key),children:H(`ul`,{class:`cards`,"aria-label":l.label||`Entries`,children:l.entries.map(e=>H(Hr,{entry:e,lock:a(e.id),open:t.has(e.id),reminderMonths:r,isNew:e.id===i,onToggle:o,...c(e.id)},e.id))})},l.key))}),Wr=({label:e,icon:t,kind:n,buttonClass:r=`button small`,children:i})=>{let[a,o]=z(!1),s=V(null),c=V(null);return B(()=>{if(!a)return;let e=e=>{s.current?.contains(e.target)||o(!1)};return document.addEventListener(`pointerdown`,e),()=>document.removeEventListener(`pointerdown`,e)},[a]),H(`div`,{class:`popover-wrap`,ref:s,onKeyDown:e=>{e.key===`Escape`&&a&&(e.stopPropagation(),o(!1),c.current?.focus())},onFocusOut:e=>{let t=e.relatedTarget;t&&!s.current?.contains(t)&&o(!1)},children:[H(`button`,{type:`button`,ref:c,class:r,"aria-expanded":a,"aria-label":e,title:e,onClick:()=>o(!a),children:[H(U,{name:t}),` `,H(`span`,{class:`button-text`,children:e})]}),a&&H(`div`,{class:`popover popover-${n}`,children:i(()=>o(!1))})]})},Gr=[`crypto`,`keys`,`secrets`],Kr=({icon:e,label:t,onClick:n,disabled:r})=>H(`button`,{type:`button`,class:`button small`,"aria-label":t,title:t,onClick:n,disabled:r,children:[H(U,{name:e}),` `,H(`span`,{class:`button-text`,children:t})]}),qr=e=>{let t=e.view.layout===`stacked`;return H(`div`,{class:`toolbar`,children:[H(`div`,{class:`toolbar-row`,children:[H(`div`,{class:`search`,children:[H(U,{name:`search`}),H(`input`,{class:`input`,type:`search`,placeholder:`Search labels, tags, notes`,"aria-label":`Search`,value:e.query,onInput:t=>e.onQuery(t.currentTarget.value),spellcheck:!1})]}),H(`select`,{class:`input filter`,"aria-label":`Filter`,value:e.filter,onChange:t=>e.onFilter(t.currentTarget.value),children:Dr.map(([t,n])=>H(`option`,{value:t,children:[n,t===`attention`&&e.dueCount?` (${e.dueCount})`:``]}))}),!e.readOnly&&H(Wr,{label:`Add`,icon:`plus`,kind:`menu`,buttonClass:`button small primary add-button`,children:t=>Gr.map(n=>H(`div`,{role:`group`,"aria-label":Ye[n],class:`menu-group`,children:[H(`div`,{class:`menu-heading`,"aria-hidden":`true`,children:Ye[n]}),Je.filter(e=>J[e].group===n).map(n=>H(`button`,{type:`button`,class:`menu-item`,onClick:()=>{t(),e.onAdd(n)},children:[H(U,{name:_n[n]}),` `,hn[n]]}))]}))})]}),H(`div`,{class:`toolbar-row`,children:[H(`span`,{class:`muted small count`,role:`status`,children:e.shown===e.total?`${e.total} ${e.total===1?`entry`:`entries`}`:`${e.shown} of ${e.total} entries`}),H(`span`,{class:`spacer`}),t&&H(C,{children:[H(Kr,{icon:`expand`,label:`Expand all`,onClick:e.onExpandAll,disabled:e.view.singleExpand||e.shown===0}),H(Kr,{icon:`collapse`,label:`Collapse all`,onClick:e.onCollapseAll,disabled:e.shown===0})]}),H(Wr,{label:`View`,icon:`sliders`,kind:`dialog`,children:()=>H(`div`,{class:`view-options`,children:[H(`fieldset`,{children:[H(`legend`,{children:`Layout`}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`layout`,checked:t,onChange:()=>e.onView({layout:`stacked`})}),` Expandable cards`]}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`layout`,checked:!t,onChange:()=>e.onView({layout:`split`})}),` List + editor side by side`]})]}),H(`fieldset`,{children:[H(`legend`,{children:`Density`}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`density`,checked:e.view.density===`comfortable`,onChange:()=>e.onView({density:`comfortable`})}),` `,`Comfortable`]}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`density`,checked:e.view.density===`compact`,onChange:()=>e.onView({density:`compact`})}),` Compact`]})]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Group by`}),H(`select`,{class:`input`,value:e.view.groupBy,onChange:t=>e.onView({groupBy:t.currentTarget.value}),children:vn.map(([e,t])=>H(`option`,{value:e,children:t}))})]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Sort`}),H(`select`,{class:`input`,value:e.view.sort,onChange:t=>e.onView({sort:t.currentTarget.value}),children:[H(`option`,{value:`updated`,children:`Recently updated`}),H(`option`,{value:`label`,children:`Label`}),H(`option`,{value:`created`,children:`Date created`})]})]}),t&&H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:e.view.singleExpand,onChange:t=>e.onView({singleExpand:t.currentTarget.checked})}),` Open one entry at a time`]})]})}),H(Kr,{icon:`settings`,label:`Settings`,onClick:e.onSettings}),e.hasPassword&&H(Kr,{icon:`lock`,label:`Lock`,onClick:e.onLock}),H(Kr,{icon:`eyeOff`,label:`Hide all`,onClick:e.onHideAll})]})]})},Jr=6e5,Yr=16,Xr=12,Zr=Ue,Qr=1,$r=e=>G(`${Ze}|${Qr}|PBKDF2-SHA256|${e}|AES-256-GCM`),ei=async(e,t=q(Yr),n=Jr)=>{let r=await crypto.subtle.importKey(`raw`,K(G(e.normalize(`NFC`))),`PBKDF2`,!1,[`deriveKey`]);return{key:await crypto.subtle.deriveKey({name:`PBKDF2`,hash:`SHA-256`,salt:K(t),iterations:n},r,{name:`AES-GCM`,length:256},!1,[`encrypt`,`decrypt`]),salt:t,iterations:n}},ti=async(e,t)=>{let n=q(Xr),r=await crypto.subtle.encrypt({name:`AES-GCM`,iv:K(n),additionalData:K($r(t.iterations))},t.key,K(G(JSON.stringify(e))));return{kdf:`PBKDF2-SHA256`,iterations:t.iterations,salt:Ve(t.salt),cipher:`AES-256-GCM`,iv:Ve(n),ciphertext:Ve(new Uint8Array(r))}},ni=class extends Error{constructor(){super(`Wrong password, or the vault data is damaged.`)}},ri=class extends Error{constructor(){super(`The vault data in this note is damaged. Restore an earlier version from note history.`)}},ii=e=>{try{return He(e)}catch{throw new ri}},ai=class extends Error{constructor(){super(`This browser cannot decrypt vaults here: encryption needs a secure (https) page. Open the note in the Standard Notes app or at app.standardnotes.com.`)}},oi=async(e,t)=>{let n=ii(e.iv),r=ii(e.ciphertext),i;try{i=await crypto.subtle.decrypt({name:`AES-GCM`,iv:K(n),additionalData:K($r(e.iterations))},t.key,K(r))}catch{throw new ni}try{return _t(JSON.parse(Re(new Uint8Array(i))))}catch{throw new ri}},si=async(e,t)=>{if(!Zr())throw new ai;let n=await ei(t,ii(e.salt),e.iterations);return{vault:await oi(e,n),vaultKey:n}},ci=(e,t)=>e.salt===Ve(t.salt)&&e.iterations===t.iterations,li=`keyfold-viewer.html`,ui=`Encrypted backup of a Keyfold vault (https://github.com/nickstruglia/standard-notes-keyfold). To read it without Standard Notes, open ${li} (keep a copy next to this file; it is also at https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/${li}) in a browser and choose this file; it works offline. To restore it, create a new Standard Notes note, change the note type to Keyfold, choose "Restore a backup file" and pick this file, then enter the backup password. `+et(`the password chosen when the backup was made`),di=(e=nt())=>`keyfold-backup-${e}.json`,fi=async(e,t,n=Jr)=>{let r=new Date().toISOString(),i=await ti({...e,settings:{...e.settings,lastExportedAt:r}},await ei(t,void 0,n));return{text:JSON.stringify({app:Ze,version:1,readme:ui,exportedAt:r,encryption:i},null,1)+` +`,fileName:di(),exportedAt:r,entries:e.entries.length}},pi=e=>{let t=e.settings.lastExportedAt;return t?e.entries.filter(e=>e.updatedAt>t||e.addedAt>t).length:e.entries.length},mi=e=>e===0?`Never`:e<60?`${e} seconds`:`${e/60} minute${e===60?``:`s`}`,hi=({value:e,options:t,format:n,onChange:r,disabled:i})=>H(`select`,{class:`input`,value:String(e),disabled:i,onChange:e=>r(Number(e.currentTarget.value)),children:[...new Set([...t,e])].sort((e,t)=>e-t).map(e=>H(`option`,{value:String(e),children:n(e)}))}),gi=new Set([`1234567890`,`12345678910`,`0123456789`,`1111111111`,`qwertyuiop`,`asdfghjkl;`,`password12`,`password123`,`password1!`,`password123!`,`iloveyou12`,`letmein123`,`welcome123`,`abcdefghij`,`qwerty1234`,`1q2w3e4r5t`,`q1w2e3r4t5`,`zaq12wsxcde`,`passw0rd123`,`administrator`,`trustno1234`,`football123`,`baseball12`]),_i=e=>{if(gi.has(e.toLowerCase()))return{bits:0,label:`Very common`,tone:`error`};let t=(/[a-z]/.test(e)?26:0)+(/[A-Z]/.test(e)?26:0)+(/[0-9]/.test(e)?10:0)+(/[^a-zA-Z0-9]/.test(e)?33:0),n=new Set(e).size,r=Math.round(Math.min(e.length,n*2)*Math.log2(Math.max(t,1)));return r<50?{bits:r,label:`Weak`,tone:`error`}:r<75?{bits:r,label:`Fair`,tone:`warn`}:{bits:r,label:`Strong`,tone:`ok`}},vi=10,yi={set:`Set password`,change:`Change password`,remove:`Remove password`,export:`Encrypt backup`},bi=({mode:e,onSubmit:t,onCancel:n})=>{let r=e===`change`||e===`remove`,i=e===`export`,a=kt(r),o=kt(!r),[s,c]=z(``),[l,u]=z(``),[d,f]=z(``),[p,m]=z(!1),[h,g]=z(!1),_={strength:Ee(),mismatch:Ee()},[v,y]=z(!1),[b,x]=z(``),S=_i(l),w=S.tone===`error`,T=e!==`remove`,E=d!==``&&d!==l,D=(!r||s.length>0)&&(!T||l.length>=vi&&l===d&&p&&(!w||h));return H(`form`,{class:`password-form`,onSubmit:async e=>{if(e.preventDefault(),D&&!v){y(!0),x(``);try{await t(s,l)}catch(e){x(e instanceof Error?e.message:String(e)),y(!1)}}},children:[r&&H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Current vault password`}),H(`input`,{class:`input`,type:`password`,autocomplete:`current-password`,value:s,onInput:e=>c(e.currentTarget.value),ref:a})]}),T&&H(C,{children:[H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:i?`Backup password`:`New vault password`}),H(`input`,{class:`input`,type:`password`,autocomplete:`new-password`,value:l,onInput:e=>u(e.currentTarget.value),ref:o,"aria-describedby":l?_.strength:void 0}),l&&H(`span`,{id:_.strength,class:`hint status-${S.tone}`,children:[S.label,` (~`,S.bits,` bits).`,` `,l.lengthf(e.currentTarget.value),"aria-invalid":E,"aria-describedby":E?_.mismatch:void 0}),E&&H(`span`,{id:_.mismatch,class:`hint status-error`,role:`alert`,children:`Passwords do not match.`})]}),w&&l.length>=vi&&H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:h,onChange:e=>g(e.currentTarget.checked)}),H(`span`,{children:i?`Use this weak password anyway. Anyone who finds the backup file could guess it quickly.`:`Use this weak password anyway. Someone with access to your Standard Notes account could guess it quickly.`})]}),e===`change`&&H(`p`,{class:`small status-warn`,children:[H(U,{name:`alert`}),` Older versions of this note in Standard Notes' note history still open with the old password. If it leaked, delete those revisions too.`]}),H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:p,onChange:e=>m(e.currentTarget.checked)}),H(`span`,{children:i?`I understand that if I forget this password, no one (not Standard Notes, not the developer) can open this backup.`:`I understand that if I forget this password, no one (not Standard Notes, not the developer) can recover the secrets in this note.`})]})]}),b&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` `,b]}),H(`div`,{class:`row`,children:[H(`button`,{type:`submit`,class:`button ${e===`remove`?`danger`:`primary`}`,disabled:!D||v,children:v?i?`Encrypting…`:`Working…`:yi[e]}),H(`button`,{type:`button`,class:`button`,onClick:n,disabled:v,children:`Cancel`})]})]})},xi=e=>`${(e/1024).toFixed(+(e<10240))} KB`,Si=({vault:e,mobileApp:t,onExport:n,onExported:r,onCopy:i})=>{let{toast:a}=Z(),[o,s]=z(!1),[c,l]=z(null),u=Ce(()=>{if(!c)return null;let e=new Blob([c.text],{type:`application/json`});return{url:URL.createObjectURL(e),size:e.size}},[c]);B(()=>{if(u)return()=>{setTimeout(()=>URL.revokeObjectURL(u.url),6e4)}},[u]);let d=V(null),f=V(null);B(()=>(t?f:d).current?.focus(),[u]);let p=e.settings.lastExportedAt,m=p?pi(e):0,h=Zr()?mt(e)?`This vault was saved by a newer version of Keyfold. Update Keyfold first, so the backup leaves nothing out.`:e.entries.length===0?`There is nothing to back up yet.`:``:`Your browser does not provide WebCrypto here, so a backup cannot be encrypted.`,g=async()=>{c&&(await i(c.text)?(r(c),a(`Backup copied. Paste it into a text file or another app; only its password opens it.`,`success`)):a(`Could not copy the backup: clipboard access was blocked.`,`error`))},_=c&&u&&H(`a`,{ref:d,class:`button ${t?``:`primary`}`,href:u.url,download:c.fileName,onClick:()=>r(c),children:[H(U,{name:`download`}),` Save file`]}),v=H(`button`,{ref:f,type:`button`,class:`button ${t?`primary`:``}`,onClick:g,children:[H(U,{name:`copy`}),` Copy as text`]});return H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`download`}),` Backup file`]}),H(`p`,{class:`small`,children:`Save an encrypted copy of this vault outside Standard Notes, for example on a flash drive, so you can still read it if Standard Notes is ever unavailable. The Keyfold offline viewer opens it in any browser, with no account and no internet connection.`}),H(`p`,{class:`muted small`,children:[p?`Last backup file: ${bn(p)}.`:`No backup file made yet.`,m>0&&` ${m} ${m===1?`entry was`:`entries were`} added or changed since.`]}),c&&u?H(`div`,{class:`backup-ready`,children:[H(`p`,{class:`status status-ok`,role:`status`,children:[H(U,{name:`check`}),` Encrypted `,c.entries,` `,c.entries===1?`entry`:`entries`,` into `,c.fileName,` (`,xi(u.size),`).`]}),H(`div`,{class:`row`,children:[t?v:_,t?_:v,H(`button`,{type:`button`,class:`button`,onClick:()=>l(null),children:`Done`})]}),(t||Mt())&&H(`p`,{class:`small`,children:[t?`The Standard Notes phone app may not save files from plugins. `:``,`If Save file does nothing, copy the text and paste it into a file or another app, or make the backup on a computer.`]}),H(`p`,{class:`muted small`,children:`Keep it somewhere other than Standard Notes, with the offline viewer next to it, and make a new one after adding or changing keys.`})]}):o?H(C,{children:[H(`p`,{class:`small`,children:`Choose a password for this backup. It can be your vault password or a different one, as long as you will still remember it in years.`}),H(bi,{mode:`export`,onSubmit:async(e,t)=>{l(await n(t)),s(!1)},onCancel:()=>s(!1)})]}):H(C,{children:[h&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` `,h]}),H(`div`,{class:`row`,children:[H(`button`,{type:`button`,class:`button primary`,disabled:!!h,onClick:()=>s(!0),children:[H(U,{name:`download`}),` Make a backup file`]}),H(`a`,{class:`button`,href:`https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/${li}`,target:`_blank`,rel:`noopener noreferrer`,children:`Get the offline viewer`})]})]})]})},Ci=({vault:e,settings:t,hasPassword:n,onChange:r,onSetPassword:i,onChangePassword:a,onRemovePassword:o,onExport:s,onExported:c,onCopyBackup:l,mobileApp:u,onLock:d,onClose:f})=>{let{readOnly:p}=Z(),[m,h]=z(null);return H(`article`,{class:`editor settings`,children:[H(`header`,{class:`editor-header`,children:[H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Close settings`,title:`Back`,onClick:f,children:H(U,{name:`back`})}),H(`h2`,{children:`Vault settings`})]}),H(`div`,{class:`editor-body`,children:[H(`p`,{class:`muted small`,children:`Settings are saved in this note, so every device uses the same ones.`}),H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`eye`}),` Privacy`]}),H(`div`,{class:`row`,children:[H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Hide revealed secrets after`}),H(hi,{value:t.autoHideSeconds,options:[0,10,30,60,120,300],format:mi,disabled:p,onChange:e=>r({autoHideSeconds:e})})]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Clear clipboard after`}),H(hi,{value:t.clipboardClearSeconds,options:[0,10,20,30,60,120],format:mi,disabled:p,onChange:e=>r({clipboardClearSeconds:e})})]})]}),H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:t.hideOnBlur,disabled:p,onChange:e=>r({hideOnBlur:e.currentTarget.checked})}),H(`span`,{children:`Hide revealed secrets when the editor loses focus`})]}),H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:t.privacyScreen,disabled:p,onChange:e=>r({privacyScreen:e.currentTarget.checked})}),H(`span`,{children:`Privacy screen: blur the whole vault while the editor is not focused`})]}),H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:t.lockSavedEntries,disabled:p,onChange:e=>r({lockSavedEntries:e.currentTarget.checked})}),H(`span`,{children:`Open saved entries locked, so nothing changes by accident while scrolling. Use Edit on an entry to change it.`})]})]}),H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`shield`}),` Backup reminders`]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Flag entries whose backups were not checked within`}),H(hi,{value:t.backupReminderMonths,options:[0,3,6,12,24],format:e=>e===0?`Off`:`${e} months`,disabled:p,onChange:e=>r({backupReminderMonths:e})})]})]}),H(Si,{vault:e,mobileApp:u,onExport:s,onExported:c,onCopy:l}),H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`lock`}),` Vault password`]}),H(`p`,{class:`small`,children:`Standard Notes already end-to-end encrypts this note. A vault password adds a second layer: the note stays unreadable even to someone using your unlocked Standard Notes account, until the password is entered.`}),H(`p`,{class:`muted small`,children:[`AES-256-GCM, key derived with PBKDF2-SHA256 (`,Jr.toLocaleString(),` iterations). The key is kept only in memory while the vault is unlocked.`]}),!n&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` Older versions of this note in Standard Notes' note history are not re-encrypted. To keep no unprotected copy, set the password on a new, empty vault note before adding secrets, or delete the old revisions.`]}),Zr()?m?H(bi,{mode:m,onSubmit:async(e,t)=>{m===`set`&&await i(t),m===`change`&&await a(e,t),m===`remove`&&await o(e),h(null)},onCancel:()=>h(null)}):n?H(C,{children:[H(`p`,{class:`status status-ok`,children:[H(U,{name:`check`}),` This vault is password protected.`]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Lock automatically after inactivity`}),H(hi,{value:t.autoLockMinutes,options:[0,1,2,5,10,15,30,60],format:e=>e===0?`Never`:`${e} minute${e===1?``:`s`}`,disabled:p,onChange:e=>r({autoLockMinutes:e})})]}),H(`div`,{class:`row`,children:[H(`button`,{type:`button`,class:`button primary`,onClick:d,children:[H(U,{name:`lock`}),` Lock now`]}),H(`button`,{type:`button`,class:`button`,disabled:p,onClick:()=>h(`change`),children:`Change password`}),H(`button`,{type:`button`,class:`button danger`,disabled:p,onClick:()=>h(`remove`),children:`Remove password`})]})]}):H(`button`,{type:`button`,class:`button primary`,disabled:p,onClick:()=>h(`set`),children:[H(U,{name:`lock`}),` Set a vault password`]}):H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` Your browser does not provide WebCrypto here, so a vault password is not available.`]})]}),H(`section`,{class:`section`,children:[H(`h3`,{children:`About`}),H(`p`,{class:`small`,children:[`Keyfold `,`1.0.31 (77e7bd8)`,`, from `,`https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/`,`. Open source (MIT):`,` `,H(`a`,{href:`https://github.com/nickstruglia/standard-notes-keyfold`,target:`_blank`,rel:`noopener noreferrer`,children:`github.com/nickstruglia/standard-notes-keyfold`}),`. Its Content Security Policy blocks all outgoing connections, images and fonts from other sites; only your Standard Notes theme's stylesheets load.`]}),H(`details`,{class:`notices`,children:[H(`summary`,{class:`small`,children:`Third-party notices`}),H(`p`,{class:`small`,children:`Monero seeds are checked against the Monero English wordlist, used under this licence:`}),H(`pre`,{class:`small`,children:Lt})]})]})]})]})},wi=e=>new Promise((t,n)=>{let r=new FileReader;r.onload=()=>t(String(r.result??``)),r.onerror=()=>n(r.error),r.readAsText(e)}),Ti=({offlineViewer:e,onOpen:t})=>{let[n,r]=z(``),[i,a]=z(``),[o,s]=z(!1),c=V(null),l=kt(),u=(e,n)=>{let r=yt(e).kind;if(r===`empty`)return a(n===`file`?`This file is empty.`:`Paste the text first.`);if(r===`foreign`)return a(n===`file`?`This file is not a Keyfold backup or note.`:`This is not the text of a Keyfold note. Copy all of it, from the first { to the last }, without editing.`);t(e)},d=async e=>{if(e){if(a(``),e.size>20971520)return a(`This file is too large to be a Keyfold backup.`);try{u(await wi(e),`file`)}catch{a(`Could not read this file.`)}}};return H(`div`,{class:`app`,children:H(`div`,{class:`screen ${o?`dragging`:``}`,onDragOver:e=>{e.preventDefault(),s(!0)},onDragLeave:e=>{e.currentTarget===e.target&&s(!1)},onDrop:e=>{e.preventDefault(),s(!1),d(e.dataTransfer?.files[0])},children:H(`form`,{class:`card open-note`,onSubmit:e=>{e.preventDefault(),a(``),u(n,`paste`)},children:[H(U,{name:`lock`,size:32}),H(`h2`,{children:e?`Keyfold offline viewer`:`Open a Keyfold backup or note`}),H(`p`,{class:`small`,children:[`Open a Keyfold backup file, or paste the text of a Keyfold note. It opens read-only. Nothing is saved, and this page cannot send anything anywhere`,e?`, so it works offline`:``,`.`]}),H(`input`,{ref:c,type:`file`,hidden:!0,"aria-label":`Backup file`,onChange:e=>{let t=e.currentTarget;d(t.files?.[0]).finally(()=>{t.value=``})}}),H(`button`,{ref:l,type:`button`,class:`button primary`,onClick:()=>c.current?.click(),children:[H(U,{name:`file`}),` Choose backup file`]}),!Mt()&&H(`p`,{class:`muted small`,children:`or drop it on this page`}),i&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` `,i]}),H(`details`,{class:`paste-note`,children:[H(`summary`,{children:`Paste a note's text instead`}),H(`p`,{class:`small`,children:`In Standard Notes, change the note type to Plain text, then select all and copy, without editing.`}),H(`textarea`,{class:`input mono`,rows:8,value:n,"aria-label":`Note text`,placeholder:`{ "app": "keyfold", ... }`,onInput:e=>r(e.currentTarget.value),autocomplete:`off`,spellcheck:!1}),H(`button`,{type:`submit`,class:`button`,disabled:!n.trim(),children:`Open read-only`})]}),location.protocol!==`file:`&&H(`a`,{class:`small`,href:`./keyfold-viewer.html`,download:`keyfold-viewer.html`,children:`Save this viewer as a single file, to keep next to your backups`}),!e&&H(`a`,{class:`small`,href:`./`,children:`Back to the demo`})]})})})},Ei=({mobileApp:e,vaultHasPassword:t,onRestore:n,onCancel:r})=>{let[i,a]=z(``),[o,s]=z(null),[c,l]=z(``),[u,d]=z(!1),[f,p]=z(``),[m,h]=z(!1),g=V(null),_=V(null),v=kt(!e);B(()=>{o&&_.current?.focus()},[o]);let y=async(e,t)=>{d(!0),p(``);try{await n(e,t)}catch(e){p(e instanceof Error?e.message:String(e)),d(!1)}},b=(e,t)=>{p(``);let n=yt(e);switch(n.kind){case`empty`:return p(t===`file`?`This file is empty.`:`Paste the text first.`);case`foreign`:return p(t===`file`?`This file is not a Keyfold backup.`:`This is not the text of a Keyfold backup or note. Copy all of it, from the first { to the last }, without editing.`);case`newer`:return p(`This was made by a newer version of Keyfold. Update the plugin in Standard Notes (Preferences → Plugins), then try again.`);case`unsupported`:return p(`Its encryption uses settings this copy of Keyfold cannot read, or the file is damaged.`);case`plain`:y(e,``);return;case`encrypted`:return s({text:e,exportedAt:n.exportedAt})}},x=async e=>{if(e){if(p(``),e.size>20971520)return p(`This file is too large to be a Keyfold backup.`);try{b(await wi(e),`file`)}catch{p(`Could not read this file.`)}}},S=f&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` `,f]});if(o){let e=o.exportedAt?`Backup password`:`Vault password`;return H(`div`,{class:`screen`,children:H(`form`,{class:`card restore-backup`,onSubmit:e=>{e.preventDefault(),c&&!u&&y(o.text,c)},children:[H(U,{name:`lock`,size:32}),H(`h2`,{children:o.exportedAt?`Encrypted backup`:`Encrypted vault`}),H(`p`,{class:`small`,children:[o.exportedAt?`Made ${bn(o.exportedAt)}. Enter the password chosen when the backup was made.`:`Enter the vault password of the note this text came from.`,` `,t?`This vault keeps its own password.`:`The restored vault keeps this password. You can change it in Settings.`]}),!Zr()&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` Encryption needs a secure (https) connection. Open the note in the Standard Notes app or at app.standardnotes.com.`]}),H(`input`,{ref:_,class:`input`,type:`password`,autocomplete:`current-password`,placeholder:e,"aria-label":e,value:c,onInput:e=>l(e.currentTarget.value)}),S,H(`div`,{class:`row`,children:[H(`button`,{type:`submit`,class:`button primary`,disabled:!c||u,children:u?`Restoring…`:`Restore`}),H(`button`,{type:`button`,class:`button`,disabled:u,onClick:()=>{s(null),l(``),p(``)},children:`Back`})]})]})})}return H(`div`,{class:`screen ${m?`dragging`:``}`,onDragOver:e=>{e.preventDefault(),h(!0)},onDragLeave:e=>{e.currentTarget===e.target&&h(!1)},onDrop:e=>{e.preventDefault(),h(!1),x(e.dataTransfer?.files[0])},children:H(`form`,{class:`card restore-backup`,onSubmit:e=>{e.preventDefault(),u||b(i,`paste`)},children:[H(U,{name:`file`,size:32}),H(`h2`,{children:`Restore a backup`}),H(`p`,{class:`small`,children:`Choose a Keyfold backup file, or paste its text. Its entries are restored into this note, which is empty.`}),H(`input`,{ref:g,type:`file`,hidden:!0,"aria-label":`Backup file`,onChange:e=>{let t=e.currentTarget;x(t.files?.[0]).finally(()=>{t.value=``})}}),H(`button`,{ref:v,type:`button`,class:`button primary`,disabled:u,onClick:()=>g.current?.click(),children:[H(U,{name:`file`}),` Choose backup file`]}),!Mt()&&H(`p`,{class:`muted small`,children:`or drop it here`}),e&&H(`p`,{class:`small`,children:`The Standard Notes phone app may not let plugins open files. If nothing happens, paste the text instead.`}),S,H(`details`,{class:`paste-note`,open:e,children:[H(`summary`,{children:`Paste the text instead`}),H(`textarea`,{class:`input mono`,rows:6,value:i,"aria-label":`Backup text`,placeholder:`{ "app": "keyfold", ... }`,onInput:e=>a(e.currentTarget.value),autocomplete:`off`,spellcheck:!1}),H(`button`,{type:`submit`,class:`button`,disabled:!i.trim()||u,children:`Continue`})]}),H(`button`,{type:`button`,class:`button`,disabled:u,onClick:r,children:`Cancel`})]})})},Di=({onUnlock:e,autoFocus:t,exportedAt:n})=>{let r=n?`Backup password`:`Vault password`,i=Zr(),a=kt(t&&i),[o,s]=z(``),[c,l]=z(!1),[u,d]=z(``);return H(`div`,{class:`screen`,children:H(`form`,{class:`card lock-card`,onSubmit:async t=>{if(t.preventDefault(),o&&!c){l(!0),d(``);try{await e(o)}catch(e){d(e instanceof Error?e.message:String(e)),l(!1)}}},children:[H(U,{name:`lock`,size:32}),H(`h2`,{children:n?`Encrypted backup`:`Vault locked`}),H(`p`,{class:`muted small`,children:n?`Made ${bn(n)}. Enter the password chosen when the backup was made.`:`This note has an extra vault password. Standard Notes cannot recover it for you.`}),!i&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` This page cannot decrypt vaults: encryption needs a secure (https) connection. Open the note in the Standard Notes app or at app.standardnotes.com.`]}),H(`input`,{class:`input`,type:`password`,autocomplete:`current-password`,placeholder:r,"aria-label":r,value:o,disabled:!i,onInput:e=>s(e.currentTarget.value),ref:a}),u&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` `,u]}),H(`button`,{type:`submit`,class:`button primary`,disabled:!o||c,children:c?`Unlocking…`:`Unlock`})]})})},Oi=({length:e,readOnly:t,onConvert:n})=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(U,{name:`alert`,size:32}),H(`h2`,{children:`This note already has other content`}),H(`p`,{class:`small`,children:[`It holds `,e.toLocaleString(),` characters that are not a Keyfold vault. Nothing has been changed.`]}),H(`p`,{class:`small`,children:`To keep the note as it is, switch it back to another editor in Standard Notes. Or convert it: the existing text is kept, line breaks included, in a hidden field of a new "Imported note" entry.`}),H(`button`,{type:`button`,class:`button primary`,disabled:t,onClick:n,children:`Convert to a vault`})]})}),ki=({version:e})=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(U,{name:`alert`,size:32}),H(`h2`,{children:`Saved by a newer version`}),H(`p`,{class:`small`,children:[`This vault uses format version `,e,`, which this copy of Keyfold does not understand yet. Nothing has been changed. Update the plugin in Standard Notes (Preferences → Plugins) to open it.`]})]})}),Ai=()=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(U,{name:`alert`,size:32}),H(`h2`,{children:`Vault encryption not recognized`}),H(`p`,{class:`small`,children:`This is a Keyfold vault, but its password protection uses settings this copy of Keyfold cannot read, or the data is damaged. Nothing has been changed. Update the plugin in Standard Notes (Preferences → Plugins), or restore an earlier version from note history.`})]})}),ji=({slow:e})=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(`p`,{class:`muted`,children:`Connecting to Standard Notes…`}),e&&H(`p`,{class:`small muted`,children:`Still waiting. If Standard Notes asks to activate Keyfold, choose Continue; otherwise, close and reopen the note.`})]})}),Mi=({dialog:e,onClose:t})=>{let[n]=z(()=>document.activeElement),r=kt();return B(()=>()=>{n?.isConnected&&n.focus()},[]),B(()=>{let e=e=>e.key===`Escape`&&t(!1);return document.addEventListener(`keydown`,e),()=>document.removeEventListener(`keydown`,e)},[t]),H(`div`,{class:`overlay`,role:`presentation`,onClick:e=>e.target===e.currentTarget&&t(!1),onKeyDown:e=>{if(e.key!==`Tab`)return;let t=Array.from(e.currentTarget.querySelectorAll(`button`)),n=t[0],r=t[t.length-1];e.shiftKey&&document.activeElement===n?(e.preventDefault(),r.focus()):!e.shiftKey&&document.activeElement===r&&(e.preventDefault(),n.focus())},children:H(`div`,{class:`card dialog`,role:`alertdialog`,"aria-modal":`true`,"aria-labelledby":`dialog-title`,"aria-describedby":`dialog-message`,children:[H(`h2`,{id:`dialog-title`,children:e.title}),H(`p`,{id:`dialog-message`,class:`small`,children:e.message}),H(`div`,{class:`row end`,children:[H(`button`,{type:`button`,class:`button`,onClick:()=>t(!1),ref:r,children:`Cancel`}),H(`button`,{type:`button`,class:`button ${e.danger?`danger`:`primary`}`,onClick:()=>t(!0),children:e.confirmLabel??`OK`})]})]})})},Ni=({toasts:e,onDismiss:t})=>H(`div`,{class:`toasts`,role:`status`,"aria-live":`polite`,children:e.map(e=>H(`div`,{class:`toast toast-${e.tone}`,children:[H(`span`,{children:e.message}),e.action&&H(`button`,{type:`button`,class:`button small`,onClick:()=>{e.action.run(),t(e.id)},children:e.action.label}),H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Dismiss`,onClick:()=>t(e.id),children:H(U,{name:`x`,size:14})})]},e.id))}),Pi=e=>{let t=document.activeElement,n=t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement?t:null,r=n?[n.selectionStart,n.selectionEnd]:null,i=document.createElement(`textarea`);i.value=e,i.setAttribute(`readonly`,``),i.style.position=`fixed`,i.style.opacity=`0`,document.body.appendChild(i),i.select(),i.setSelectionRange(0,e.length);let a=!1;try{a=document.execCommand(`copy`)}catch{a=!1}if(i.remove(),t?.focus?.({preventScroll:!0}),n&&r&&r[0]!==null&&r[1]!==null)try{n.setSelectionRange(r[0],r[1])}catch{}return a},Fi=async e=>{if(Pi(e))return!0;try{if(navigator.clipboard?.writeText)return await navigator.clipboard.writeText(e),!0}catch{}return!1},Ii=()=>Pi(` `),Li=async()=>{if(Ii())return!0;try{if(navigator.clipboard?.writeText)return await navigator.clipboard.writeText(``),!0}catch{}return!1},Ri=2e3,zi=class{host;onError;delayMs;maxWaitMs;version=0;ready=null;timer;inflight=Promise.resolve();unsentSince=null;readyVersion=0;pending=[];lastText=``;constructor(e,t,n=300,r=1e3){this.host=e,this.onError=t,this.delayMs=n,this.maxWaitMs=r}schedule(e){let t=++this.version;this.unsentSince??=Date.now();let n=async()=>{if(t===this.version)try{let n=await e();if(t!==this.version)return;this.ready=n,this.readyVersion=t,clearTimeout(this.timer);let r=this.unsentSince??Date.now(),i=Math.max(0,Math.min(this.delayMs,r+this.maxWaitMs-Date.now()));this.timer=setTimeout(()=>this.flush(),i)}catch(e){t===this.version&&this.onError(e)}};this.inflight=this.inflight.then(n)}flush(){clearTimeout(this.timer),this.timer=void 0;let e=this.ready;e&&(this.ready=null,this.readyVersion===this.version&&(this.unsentSince=null),this.remember(e.text),this.host.save(e.text,e.preview))}hasUnsent(){return this.unsentSince!==null}async settle(){await this.inflight,this.flush()}cancel(){this.version++,clearTimeout(this.timer),this.timer=void 0,this.ready=null,this.unsentSince=null}isEcho(e){let t=Date.now();this.pending=this.pending.filter(e=>t-e.att.text===e);return n===-1?e!==``&&e===this.lastText:(this.pending.splice(0,n),!0)}forget(){this.cancel(),this.pending=[]}noteSeen(e){this.lastText=e}remember(e){this.lastText=e,this.pending.push({text:e,at:Date.now()}),this.pending.length>20&&this.pending.shift()}},Bi=e=>e instanceof Error?e.message:String(e),Vi=H(`datalist`,{id:`bip39-words`,children:It.map(e=>H(`option`,{value:e}))}),Hi=H($n,{}),Ui=`The note changed while this was running. Please try again.`,Wi=({host:e})=>{let[t,n]=z({name:`connecting`}),[r,i]=z(rt),[a,o]=z(!1),[s,c]=z(!1),[l,u]=z(0),[d,f]=z(()=>document.hasFocus()),[p,m]=z(!1),[h,g]=z({type:`list`}),[_,v]=z(``),[y,b]=z(`all`),[x,S]=z(()=>new Set),[w,T]=z(()=>new Set),[E,D]=z({}),[O,ee]=z({}),[te,k]=z(null),[ne,re]=z([]),[ie,ae]=z(null),[oe,se]=z(!1),[ce,le]=z(()=>new Set),A=V(r),j=V(null),ue=V(!1),M=V(0),de=V(0),fe=V(0),N=V(null),pe=we(e=>re(t=>t.filter(t=>t.id!==e)),[]),P=we((e,t=`info`,n,r=4e3)=>{let i=++fe.current;return re(r=>{let a=[...r,{id:i,message:e,tone:t,action:n}];for(;a.length>4;){let e=a.findIndex(e=>!e.action&&e.id!==i);a.splice(e===-1?0:e,1)}return a}),setTimeout(()=>pe(i),r),i},[]),F=Ce(()=>new zi(e,e=>P(`Could not save: ${Bi(e)}`,`error`,void 0,8e3)),[e]),I=async e=>{let t=j.current;return t?{text:xt(await ti(e,t)),preview:St(null)}:{text:bt(e),preview:St(e)}},me=e=>{A.current=e,i(e)},he=mt(r),L=a||he||t.name!==`ready`,ge=V(L);ge.current=L;let _e=V(a);_e.current=a;let ve=()=>{let e=M.current;return()=>{if(e!==M.current)throw Error(Ui);if(ge.current)throw Error(`This note is read-only right now.`)}},ye=()=>{j.current=null,F.cancel(),me(rt()),u(e=>e+1),g({type:`list`}),S(new Set),le(new Set),D({}),k(null),re([]),ae(e=>(e?.resolve(!1),null))},be=we(e=>{if(ge.current)return!1;let t=e(A.current);return me(t),F.schedule(()=>I(t)),!0},[F]);B(()=>{e.subscribe(async e=>{if(o(e.locked),e.metadataOnly||F.isEcho(e.text))return;let t=F.hasUnsent();F.cancel(),F.noteSeen(e.text);let r=++M.current,i=r===1,a=yt(e.text),s=()=>t&&P(`A newer version arrived from another device or note history and replaced your last few keystrokes.`,`error`,void 0,8e3);switch(a.kind){case`empty`:case`plain`:{let e=ue.current;j.current&&ye(),ue.current=!1,c(!1),me(a.kind===`plain`?a.vault:rt()),n({name:`ready`}),e&&!i?P(`This vault is no longer password protected: the note was changed on another device or restored from history. Set a password again in Settings if this was not you.`,`error`,void 0,6e4):s();return}case`encrypted`:{c(!0),ue.current=!0;let e=j.current;if(e&&ci(a.blob,e))try{let t=await oi(a.blob,e);if(r!==M.current)return;F.cancel(),me(t),n({name:`ready`}),s();return}catch{}if(r!==M.current)return;j.current&&ye(),me(rt()),n({name:`locked`,blob:a.blob,autoFocus:i||document.hasFocus(),exportedAt:a.exportedAt});return}case`foreign`:case`newer`:case`unsupported`:j.current&&ye(),ue.current=!1,c(!1),n(a.kind===`foreign`?{name:`foreign`,text:a.text}:a.kind===`newer`?{name:`newer`,version:a.version}:{name:`unsupported`});return}})},[e,F]),B(()=>{let e=setTimeout(()=>m(!0),5e3);return()=>clearTimeout(e)},[]);let R=r.settings,xe=V(R);xe.current=R,B(()=>{let e=()=>F.flush(),t=()=>{F.flush(),f(!1),xe.current.hideOnBlur&&u(e=>e+1)},n=()=>f(!0),r=()=>document.visibilityState===`hidden`&&F.flush();return window.addEventListener(`blur`,t),window.addEventListener(`focus`,n),window.addEventListener(`pagehide`,e),window.addEventListener(`beforeunload`,e),document.addEventListener(`visibilitychange`,r),()=>{window.removeEventListener(`blur`,t),window.removeEventListener(`focus`,n),window.removeEventListener(`pagehide`,e),window.removeEventListener(`beforeunload`,e),document.removeEventListener(`visibilitychange`,r)}},[F]);let Se=we(async(e=!1)=>{e&&N.current&&Ii()&&(N.current.blockedToast&&pe(N.current.blockedToast),N.current=null,de.current++),document.activeElement instanceof HTMLElement&&document.activeElement.blur(),await F.settle();let t=yt(F.lastText);t.kind===`encrypted`?(ye(),n({name:`locked`,blob:t.blob,autoFocus:e||document.hasFocus(),exportedAt:t.exportedAt})):(c(!1),e&&P(`This note is not password protected, so it cannot be locked.`,`error`))},[F]);B(()=>{if(!s||t.name!==`ready`||!R.autoLockMinutes)return;let e=Date.now(),n=()=>e=Date.now(),r=[`pointerdown`,`keydown`,`input`,`wheel`,`touchstart`];r.forEach(e=>window.addEventListener(e,n,{passive:!0}));let i=()=>{Date.now()-e>=R.autoLockMinutes*6e4&&Se()},a=setInterval(i,5e3);return document.addEventListener(`visibilitychange`,i),window.addEventListener(`pageshow`,i),window.addEventListener(`focus`,i),()=>{r.forEach(e=>window.removeEventListener(e,n)),clearInterval(a),document.removeEventListener(`visibilitychange`,i),window.removeEventListener(`pageshow`,i),window.removeEventListener(`focus`,i)}},[s,t.name,R.autoLockMinutes,Se]);let Te=async e=>{if(t.name!==`locked`)return;let r=M.current,{vault:i,vaultKey:a}=await si(t.blob,e);if(r!==M.current){let e=yt(F.lastText);if(e.kind!==`encrypted`||!ci(e.blob,a))throw Error(Ui);let t=M.current;if(i=await oi(e.blob,a),t!==M.current)throw Error(Ui)}if(j.current=a,me(i),n({name:`ready`}),a.iterations<6e5){let t=ve(),n=await ei(e);try{t()}catch{return}j.current=n,F.schedule(()=>I(A.current))}},Ee=async e=>{await F.settle();let t=yt(F.lastText);if(t.kind!==`encrypted`)throw Error(`The vault is not password protected.`);await si(t.blob,e)},De=async e=>{let t=ve(),n=await ei(e);t(),j.current=n,ue.current=!0,c(!0),F.schedule(()=>I(A.current)),P(`Vault password set. The note is now encrypted with it.`,`success`)},Oe=async(e,t)=>{let n=ve();await Ee(e);let r=await ei(t);n(),j.current=r,F.schedule(()=>I(A.current)),P(`Vault password changed.`,`success`)},ke=async e=>{let t=ve();await Ee(e),t(),j.current=null,ue.current=!1,c(!1),F.schedule(()=>I(A.current)),P(`Vault password removed. Standard Notes encryption still protects the note.`,`success`)};B(()=>{r.entries.length>0&&se(!1)},[r.entries.length]);let Ae=async(e,t)=>{let n=ve(),r=yt(e),i=j.current,a,o=i;if(r.kind===`plain`)a=r.vault;else if(r.kind===`encrypted`){let e=await si(r.blob,t);a=e.vault,o??=e.vaultKey.iterations<6e5?await ei(t):e.vaultKey}else throw Error(`This is not a Keyfold backup.`);if(mt(a))throw Error(`This was made by a newer version of Keyfold. Update the plugin in Standard Notes (Preferences → Plugins), then try again.`);if(n(),A.current.entries.length>0)throw Error(`Entries were added to this note meanwhile. Restore into a new, empty note.`);j.current=o,ue.current=o!==null,c(o!==null),me(a),se(!1),F.schedule(()=>I(a));let s=`${a.entries.length} ${a.entries.length===1?`entry`:`entries`}`;P(i?`Restored ${s}. The vault keeps its own password.`:o?`Restored ${s}. The vault keeps the password you entered; you can change it in Settings.`:`Restored ${s}. This vault has no password of its own; you can set one in Settings.`,`success`,void 0,8e3)},je=e=>{if(mt(A.current))throw Error(`Update Keyfold before making a backup of this vault.`);return fi(A.current,e)},Me=async e=>await Fi(e)?(de.current++,N.current?.blockedToast&&pe(N.current.blockedToast),N.current=null,!0):!1,Ne=we(e=>{let t=xe.current.clipboardClearSeconds,n=++de.current;N.current?.blockedToast&&pe(N.current.blockedToast),N.current=t?{id:n}:null;let r=Mt(),i=t?`${e} copied. The clipboard is cleared after ${t}s, on your next click or tap here if the browser requires one. It stays copied if you leave this note first.`:`${e} copied.`;if(P(r?`${i} Your keyboard's clipboard history may keep its own copy.`:i,`success`,void 0,r?8e3:6e3),!t)return;let a=()=>{N.current?.blockedToast&&pe(N.current.blockedToast),N.current?.id===n&&(N.current=null),r?P(`Clipboard cleared. Delete it from your keyboard's clipboard history too.`,`info`,void 0,6e3):P(`Clipboard cleared.`,`info`,void 0,3e3)};setTimeout(async()=>{if(n!==de.current)return;if(await Li()){a();return}let e=[`click`,`touchend`,`pointerup`],t=!1,r=()=>e.forEach(e=>window.removeEventListener(e,i,!0)),i=()=>{if(!t){if(n!==de.current)return r();Ii()&&(t=!0,r(),a())}};e.forEach(e=>window.addEventListener(e,i,!0));let o=P(`Waiting for a click or tap to clear the clipboard.`,`info`,{label:`Clear now`,run:i},2e4);N.current?.id===n&&(N.current.blockedToast=o)},t*1e3)},[P]),Pe=we(async(e,t)=>{e&&(await Fi(e)?Ne(t):P(`Could not copy ${t.toLowerCase()}: clipboard access was blocked.`,`error`))},[Ne]);B(()=>{let e=e=>{e.target?.closest?.(`[data-secret]`)&&Ne(`Selection`)};return document.addEventListener(`copy`,e,!0),document.addEventListener(`cut`,e,!0),()=>{document.removeEventListener(`copy`,e,!0),document.removeEventListener(`cut`,e,!0)}},[Ne]);let Fe=we(e=>new Promise(t=>ae({...e,resolve:t})),[]),Ie=Ce(()=>({settings:R,readOnly:L,hideEpoch:l,copy:Pe,toast:P,confirm:Fe,sectionOpen:(e,t)=>E[e]??t,setSectionOpen:(e,t)=>D(n=>({...n,[e]:t}))}),[R,L,l,Pe,P,Fe,E]),W={layout:R.layout,density:R.density,singleExpand:R.singleExpand,groupBy:R.groupBy,sort:R.sort,...O},Le=e=>{ee(t=>({...t,...e})),be(t=>({...t,settings:{...t.settings,...e}}))},G=W.singleExpand,Re=we(e=>{k(null),S(t=>{if(t.has(e)){let n=new Set(t);return n.delete(e),n}return G?new Set([e]):new Set(t).add(e)})},[G]),ze=we(e=>T(t=>{let n=new Set(t);return n.delete(e)||n.add(e),n}),[]),Be=e=>{b(`all`),v(``),T(new Set),k(e),S(t=>W.singleExpand?new Set([e]):new Set(t).add(e)),g({type:`entry`,id:e}),le(t=>new Set(t).add(e))},Ve=(e,t)=>le(n=>{let r=new Set(n);return t?r.add(e):r.delete(e),r}),He=e=>{let t=it(e);be(e=>({...e,entries:[t,...e.entries]})),Be(t.id)},Ue=(e,t)=>{be(n=>({...n,entries:n.entries.map(n=>n.id===e?{...n,...t,updatedAt:new Date().toISOString()}:n)}))&&t.archived===!0&&P(`Archived. It is under the "Archived" filter.`,`info`,{label:`Undo`,run:()=>Ue(e,{archived:!1})},6e3)},K=e=>{let t=A.current.entries.find(t=>t.id===e);if(!t)return;let n=new Date().toISOString(),r={...JSON.parse(JSON.stringify(t)),id:qe(),label:t.label?`${t.label} (copy)`:``,archived:!1,addedAt:n,updatedAt:n};be(e=>({...e,entries:[r,...e.entries]})),Be(r.id)},We=async e=>{let t=A.current.entries.findIndex(t=>t.id===e),n=A.current.entries[t];n&&await Fe({title:`Delete this entry?`,message:`"${n.label||`Untitled`}" will be removed from this note. You can undo right after, and Standard Notes keeps note history.`,confirmLabel:`Delete`,danger:!0})&&A.current.entries.some(t=>t.id===e)&&(be(t=>({...t,entries:t.entries.filter(t=>t.id!==e)}))?(g({type:`list`}),S(t=>{let n=new Set(t);return n.delete(e),n}),P(`Deleted "${n.label||`Untitled`}".`,`info`,{label:`Undo`,run:()=>{A.current.entries.some(e=>e.id===n.id)||be(e=>{let r=[...e.entries];return r.splice(Math.min(t,r.length),0,n),{...e,entries:r}})}},1e4)):P(`Nothing was deleted: the note is read-only right now.`,`error`))},Ge=e=>be(t=>({...t,settings:{...t.settings,...e}})),Ke=async e=>{let t=M.current;if(!await Fe({title:`Convert this note?`,message:`The existing text is moved into a hidden field of a new "Imported note" entry, and the note becomes a vault.`,confirmLabel:`Convert`})||t!==M.current||_e.current)return;let r=rt();r.entries.push(it(`other`,{label:`Imported note`,customFields:[{id:qe(),label:`Imported text`,value:e,hidden:!0,multiline:!0}]})),me(r),n({name:`ready`}),c(j.current!==null),F.schedule(()=>I(r))},q=h.type===`entry`?r.entries.find(e=>e.id===h.id)??null:null,J=r.entries.filter(e=>wt(e,R.backupReminderMonths)).length,Ye=W.layout===`stacked`?x.size>0:q!==null,Xe=[W.layout,W.sort,W.groupBy,y,_,W.layout===`stacked`?``:q?.id].join(`|`),Ze=V(null),Qe=Ye&&Ze.current?.key===Xe?Ze.current.snapshot:null,$e=Ar(r.entries,y,W.sort,_,R.backupReminderMonths);if(Qe){let e=new Set($e.map(e=>e.id));$e=[...$e,...r.entries.filter(t=>!e.has(t.id)&&Qe.groupOf.has(t.id))]}let et=Nr($e,W.groupBy);Qe&&(et=Fr(et,Qe)),Ze.current={key:Xe,snapshot:Pr(et)};let tt=V({updateEntry:Ue,deleteEntry:We,duplicateEntry:K,setEntryEditing:Ve});tt.current={updateEntry:Ue,deleteEntry:We,duplicateEntry:K,setEntryEditing:Ve};let Y=V(new Map),nt=e=>{let t=Y.current.get(e);return t||(t={onUpdate:t=>tt.current.updateEntry(e,t),onDelete:()=>tt.current.deleteEntry(e),onDuplicate:()=>tt.current.duplicateEntry(e),onEditing:t=>tt.current.setEntryEditing(e,t)},Y.current.set(e,t)),t},X=e=>R.lockSavedEntries?ce.has(e)?`editing`:`locked`:`off`,at=W.layout===`stacked`;B(()=>{le(e=>{let t=e=>at?x.has(e):h.type===`entry`&&h.id===e,n=new Set([...e].filter(t));return n.size===e.size?e:n})},[x,h,at]);let ot=H(`div`,{class:`empty`,children:[H(U,{name:`shield`,size:28}),H(`p`,{children:H(`strong`,{children:`No keys yet.`})}),H(`p`,{class:`small muted`,children:`Keep crypto seed phrases and wallet keys here, and also SSH, PGP and API keys, recovery codes and any other secret. Each one folds into a single line until you open it, and secrets stay hidden until you reveal them.`}),!L&&H(C,{children:[H(`p`,{class:`small`,children:`What do you want to add first?`}),H(`div`,{class:`kind-choices`,role:`group`,"aria-label":`Add your first entry`,children:Je.map(e=>H(`button`,{type:`button`,class:`button small`,onClick:()=>He(e),children:[H(U,{name:_n[e]}),` `,hn[e]]}))}),H(`p`,{class:`small muted`,children:`Add more of any type later with the Add (+) button.`}),H(`p`,{class:`small`,children:H(`button`,{type:`button`,class:`link-button`,onClick:()=>se(!0),children:`Restore a backup file`})})]})]}),st=r.entries.length>0&&r.entries.every(e=>e.archived)&&y!==`archived`?H(`p`,{class:`empty small muted`,children:[`Every entry is archived.`,` `,H(`button`,{type:`button`,class:`link-button`,onClick:()=>b(`archived`),children:`Show archived entries`})]}):H(`p`,{class:`empty small muted`,children:`No entries match.`}),ct;switch(t.name){case`connecting`:ct=H(ji,{slow:p});break;case`locked`:ct=H(Di,{onUnlock:Te,autoFocus:t.autoFocus,exportedAt:t.exportedAt});break;case`foreign`:ct=H(Oi,{length:t.text.length,readOnly:a,onConvert:()=>Ke(t.text)});break;case`newer`:ct=H(ki,{version:t.version});break;case`unsupported`:ct=H(Ai,{});break;case`ready`:{let t=H(qr,{query:_,onQuery:v,filter:y,onFilter:b,dueCount:J,shown:$e.length,total:r.entries.filter(e=>y===`archived`?e.archived:!e.archived).length,readOnly:L,onAdd:He,view:W,onView:Le,onExpandAll:()=>{T(new Set),S(new Set($e.map(e=>e.id)))},onCollapseAll:()=>{k(null),S(new Set)},onSettings:()=>g({type:`settings`}),hasPassword:s,onLock:()=>Se(!0),onHideAll:()=>{u(e=>e+1),le(new Set)}});ct=h.type===`settings`?H(`main`,{class:`detail full`,children:H(Ci,{vault:r,settings:R,hasPassword:s,onChange:Ge,onSetPassword:De,onChangePassword:Oe,onRemovePassword:ke,onExport:je,onExported:e=>Ge({lastExportedAt:e.exportedAt}),onCopyBackup:Me,mobileApp:e.inMobileApp(),onLock:()=>Se(!0),onClose:()=>g({type:`list`})})}):W.layout===`stacked`?H(C,{children:[t,H(`main`,{class:`detail full`,children:r.entries.length===0?ot:$e.length===0?st:H(Ur,{groups:et,expanded:x,collapsedGroups:w,reminderMonths:R.backupReminderMonths,newId:te,lockFor:X,onToggle:Re,onToggleGroup:ze,handlersFor:nt})})]}):H(C,{children:[t,H(`div`,{class:`layout ${q?`has-detail`:``}`,children:[H(`aside`,{class:`sidebar`,children:r.entries.length===0?ot:$e.length===0?st:H(Br,{groups:et,collapsedGroups:w,selectedId:q?.id??null,reminderMonths:R.backupReminderMonths,onSelect:e=>{k(null),g({type:`entry`,id:e})},onToggleGroup:ze})}),H(`main`,{class:`detail`,children:q?H(Er,{entry:q,lock:X(q.id),reminderMonths:R.backupReminderMonths,focusLabel:q.id===te,onBack:()=>{k(null),g({type:`list`})},...nt(q.id)},q.id):H(`div`,{class:`placeholder muted`,children:[H(U,{name:`shield`,size:36}),H(`p`,{children:`Select an entry, or add a new one.`})]})})]})]}),oe&&r.entries.length===0&&!L&&(ct=H(Ei,{mobileApp:e.inMobileApp(),vaultHasPassword:s,onRestore:Ae,onCancel:()=>se(!1)}))}}return H(Dt.Provider,{value:Ie,children:[H(`div`,{class:`app ${W.density} ${R.privacyScreen&&!d&&t.name===`ready`?`privacy`:``}`,children:[e.mode===`demo`&&H(`div`,{class:`banner banner-warn`,role:`note`,children:[H(U,{name:`alert`}),` Demo mode: not connected to Standard Notes, nothing is saved. Do not type real secrets here. To install, add `,H(`code`,{children:new URL(`ext.json`,location.href).href}),` in Standard Notes → Preferences → Plugins.`,` `,`Lost access to Keyfold? `,H(`a`,{href:`#open`,onClick:()=>setTimeout(()=>location.reload()),children:`Open a backup or note read-only`}),`.`]}),e.mode===`viewer`&&H(`div`,{class:`banner`,role:`note`,children:[H(U,{name:`lock`}),` Read-only viewer: nothing you open here is saved or sent anywhere.`,H(`button`,{type:`button`,class:`link-button`,onClick:()=>location.reload(),children:`Close`})]}),he&&t.name===`ready`&&H(`div`,{class:`banner`,role:`note`,children:[H(U,{name:`alert`}),` This vault was saved by a newer version of Keyfold, so it is read-only here. Update the plugin in Standard Notes (Preferences → Plugins) to edit it.`]}),a&&e.mode!==`viewer`&&t.name===`ready`&&H(`div`,{class:`banner`,role:`note`,children:[H(U,{name:`lock`}),` "Prevent editing" is on for this note. You can still reveal and copy secrets.`]}),ct,R.privacyScreen&&!d&&t.name===`ready`&&H(`button`,{type:`button`,class:`privacy-cover`,onClick:()=>{window.focus(),f(!0)},children:[H(U,{name:`eyeOff`,size:28}),H(`span`,{children:Mt()?`Tap to show the vault`:`Click to show the vault`})]})]}),Hi,Vi,ie&&H(Mi,{dialog:ie,onClose:e=>{ie.resolve(e),ae(null)}}),H(Ni,{toasts:ne,onDismiss:e=>re(t=>t.filter(t=>t.id!==e))})]})},Gi=()=>typeof crypto.randomUUID==`function`?crypto.randomUUID():Array.from(crypto.getRandomValues(new Uint8Array(16)),e=>e.toString(16).padStart(2,`0`)).join(``),Ki=e=>e&&/^https?:\/\//.test(e)?e:`*`,qi=`https://app.standardnotes.com/components/assets/`,Ji=e=>{if(/^https?:\/\//i.test(e)||/^data:text\/css[;,]/i.test(e))return e;let t=/\/components\/assets\/([a-z0-9][a-z0-9.-]*)\/([\w.-]+(?:\/[\w.-]+)*\.css)$/i.exec(e);if(t&&!t[0].includes(`..`))return`${qi}${t[1]}/${t[2]}`},Yi=2e3,Xi=[`Shift`,`Alt`,`Control`,`Meta`,`AltGraph`],Zi=class{win;sessionKey;origin;environment;queue=[];callbacks=new Map;themeLoads=new WeakMap;themeGeneration=0;constructor(e=window){this.win=e,e.addEventListener(`message`,this.onMessage),e.addEventListener(`click`,this.onClick),e.addEventListener(`keydown`,this.onKey),e.addEventListener(`keyup`,this.onKey),setTimeout(this.reveal,Yi)}get inMobileApp(){return this.environment===`native-mobile-web`||this.environment===`mobile`}streamContextItem(e){this.send(`stream-context-item`,{},t=>t?.item&&e(t.item),!0)}saveItem(e,t){this.send(`save-items`,{items:[e]},()=>t?.())}send(e,t,n,r=!1){if(!this.sessionKey){this.queue.push({action:e,data:t,callback:n,keep:r});return}let i={action:e,data:t,messageId:Gi(),sessionKey:this.sessionKey,api:`component`};n&&this.callbacks.set(i.messageId,{callback:n,keep:r});let a=this.environment===`mobile`?JSON.stringify(i):i;this.win.parent.postMessage(a,Ki(this.origin))}onMessage=e=>{if(e.source!==this.win.parent||this.win.parent===this.win)return;let t;try{t=typeof e.data==`string`?JSON.parse(e.data):e.data}catch{return}if(t&&typeof t==`object`)switch(t.action){case`component-registered`:if(this.sessionKey||!t.sessionKey)return;this.sessionKey=t.sessionKey,this.origin=e.origin,this.environment=t.data?.environment,this.activateThemes(t.data?.activeThemeUrls),this.send(`themes-activated`,{});for(let e of this.queue.splice(0))this.send(e.action,e.data,e.callback,e.keep);return;case`themes`:this.activateThemes(t.data?.themes);return;case`reply`:{let e=t.original?.messageId,n=e?this.callbacks.get(e):void 0;if(!n)return;n.keep||this.callbacks.delete(e),n.callback(t.data);return}}};onClick=()=>{this.sessionKey&&this.send(`click`,{})};onKey=e=>{if(!this.sessionKey)return;let t=Xi.includes(e.key),n=e.type===`keyup`&&t;(!e.getModifierState?.(`AltGraph`)||t)&&(e.ctrlKey||e.metaKey||e.key===`Control`||e.key===`Meta`||n)&&(e.type===`keydown`&&(e.ctrlKey||e.metaKey)&&e.key.toLowerCase()===`s`&&e.preventDefault(),this.send(e.type===`keydown`?`key-down`:`key-up`,{key:e.key,code:e.code,ctrlKey:e.ctrlKey,metaKey:e.metaKey,shiftKey:e.shiftKey,altKey:e.altKey}))};activateThemes(e){let t=Array.isArray(e)?e.filter(e=>typeof e==`string`):[],n=[...new Set(t.map(Ji).filter(e=>!!e))],r=this.win.document,i=[...r.querySelectorAll(`link[data-sn-theme]`)],a=[];for(let e of n){let t=i.find(t=>t.getAttribute(`href`)===e);if(t){a.push(this.themeLoads.get(t)??Promise.resolve());continue}let n=r.createElement(`link`),o=new Promise(e=>{n.onload=n.onerror=e});this.themeLoads.set(n,o),a.push(o),n.rel=`stylesheet`,n.href=e,n.setAttribute(`data-sn-theme`,``),r.head.appendChild(n)}let o=++this.themeGeneration;Promise.all(a).then(()=>{if(o===this.themeGeneration){for(let e of i)n.includes(e.getAttribute(`href`)??``)||e.remove();this.updateColorScheme(),this.reveal()}})}updateColorScheme(){let e=this.win.document,t=/^rgba?\(([^)]*)\)/.exec(this.win.getComputedStyle(e.body).backgroundColor)?.[1].split(/[\s,/]+/).map(Number);if(!t||t.length<3||t[3]===0)return;let n=.2126*t[0]+.7152*t[1]+.0722*t[2];e.documentElement.style.colorScheme=n<128?`dark`:`light`}reveal=()=>{this.win.document.documentElement.classList.remove(`theme-pending`)}},Qi=e=>e.content?.appData?.[`org.standardnotes.sn`]?.locked===!0,$i=`authentication`,ea=e=>{e.content?.noteType===$i&&(e.content.noteType=`unknown`)},ta=()=>{let e=new Zi(window),t=null;return{mode:`standardnotes`,inMobileApp:()=>e.inMobileApp,subscribe(n){e.streamContextItem(e=>{t=e,n({text:e.content?.text??``,locked:Qi(e),metadataOnly:e.isMetadataUpdate===!0})})},save(n,r){let i=t;i&&(i.content.text=n,i.content.preview_plain=r,i.content.preview_html=``,ea(i),e.saveItem(i))}}},na=e=>{let t=e;return{mode:`demo`,inMobileApp:()=>!1,subscribe(e){queueMicrotask(()=>e({text:t,locked:!1,metadataOnly:!1}))},save(e){t=e}}},ra=e=>({mode:`viewer`,inMobileApp:()=>!1,subscribe(t){queueMicrotask(()=>t({text:e,locked:!0,metadataOnly:!1}))},save(){}}),ia=()=>{try{return window.parent!==window}catch{return!0}},aa=e=>e.split(` `),oa=e=>{let t=new Uint8Array(4+e.length);return new DataView(t.buffer).setUint32(0,e.length),t.set(e,4),t},sa=(...e)=>{let t=new Uint8Array(e.reduce((e,t)=>e+t.length,0)),n=0;for(let r of e)t.set(r,n),n+=r.length;return t},ca=()=>{let e=sa(oa(G(`ssh-ed25519`)),oa(q(32)));return{privateKey:`-----BEGIN OPENSSH PRIVATE KEY-----\n${Ve(sa(G(`openssh-key-v1\0`),oa(G(`aes256-ctr`)),oa(G(`bcrypt`)),oa(q(24)),new Uint8Array([0,0,0,1]),oa(e),oa(q(144)))).match(/.{1,70}/g).join(` +`)}\n-----END OPENSSH PRIVATE KEY-----`,publicKey:`ssh-ed25519 ${Ve(e)} demo@example`}},la=(e,t=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`)=>Array.from(q(e),e=>t[e%t.length]).join(``),ua=e=>{let t=new Date;return t.setDate(t.getDate()+e),t.toISOString().slice(0,10)},da=()=>{let e=ca(),t=rt();return t.entries.push(it(`mnemonic`,{label:`Example: cold storage`,description:`Public BIP39 test vector. Do not send funds to it.`,chain:`Bitcoin`,wallet:`Coldcard`,tags:[`example`,`long-term`],favorite:!0,words:aa(`legal winner thank year wave sausage worth useful legal winner thank yellow`),passphrase:`example passphrase`,passphraseHint:`Example hint only`,derivationPath:`m/84'/0'/0'`,createdOn:`2021-03-14`,backups:[{id:`b1`,location:`Steel plate in home safe`,verifiedOn:nt()}]}),it(`mnemonic`,{label:`Example: multisig key 2 of 3`,chain:`Bitcoin`,wallet:`Trezor`,tags:[`example`,`multisig`],words:aa(`letter advice cage absurd amount doctor acoustic avoid letter advice cage above`),derivationPath:`m/48'/0'/0'/2'`,createdOn:`2022-08-02`,backups:[{id:`b2`,location:`Bank deposit box`,verifiedOn:`2025-01-10`}]}),it(`mnemonic`,{label:`Example: DeFi hot wallet`,chain:`Ethereum`,wallet:`MetaMask`,tags:[`example`],words:aa(`${`abandon `.repeat(23)}art`),derivationPath:`m/44'/60'/0'/0/0`,createdOn:`2023-11-20`}),it(`privateKey`,{label:`Example: paper wallet`,description:`WIF test vector from the Bitcoin wiki.`,chain:`Bitcoin`,tags:[`example`],secret:`5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ`,createdOn:`2013-04-01`}),it(`sshKey`,{label:`Example: deploy key`,description:`Random bytes in OpenSSH format, not a working key.`,service:`github.com`,account:`git`,tags:[`example`],secret:e.privateKey,passphrase:`example passphrase`,publicInfo:e.publicKey,expiresOn:ua(365)}),it(`apiKey`,{label:`Example: CI token`,description:`Random characters in GitHub token format, not a real token.`,service:`GitHub`,account:`release workflow`,tags:[`example`],secret:`ghp_${la(36)}`,expiresOn:ua(12)}),it(`recoveryCodes`,{label:`Example: exchange 2FA backup codes`,service:`Kraken`,account:`you@example.com`,tags:[`example`],secret:Array.from({length:8},()=>`${la(4,`0123456789`)}-${la(4,`0123456789`)}`).join(` +`)})),t.entries.forEach((e,t)=>e.updatedAt=new Date(Date.now()-t*6e4).toISOString()),bt(t)},fa=document.documentElement.hasAttribute(`data-viewer`),pa=!fa&&ia();document.documentElement.classList.toggle(`standalone`,!pa),pa||document.documentElement.classList.remove(`theme-pending`);var ma=document.getElementById(`app`);pa?M(H(Wi,{host:ta()}),ma):fa||location.hash===`#open`?M(H(Ti,{offlineViewer:fa,onOpen:e=>M(H(Wi,{host:ra(e)}),ma)}),ma):M(H(Wi,{host:na(da())}),ma)})(); \ No newline at end of file diff --git a/packages/io.github.nickstruglia.keyfold/prebuilt/assets/index-BhYPNPAd.js b/packages/io.github.nickstruglia.keyfold/prebuilt/assets/index-BhYPNPAd.js deleted file mode 100644 index ef67927..0000000 --- a/packages/io.github.nickstruglia.keyfold/prebuilt/assets/index-BhYPNPAd.js +++ /dev/null @@ -1,265 +0,0 @@ -(function(){var e=document.createElement(`style`);e.textContent=`:root{--bg:var(--sn-stylekit-background-color,#fff);--fg:var(--sn-stylekit-foreground-color,#1d1d20);--muted:var(--sn-stylekit-passive-color-0,var(--sn-stylekit-neutral-color,#6c7079));--border:var(--sn-stylekit-border-color,#e0e2e6);--panel:var(--sn-stylekit-secondary-background-color,#f6f7f9);--contrast:var(--sn-stylekit-contrast-background-color,#eef0f3);--info:var(--sn-stylekit-info-color,#086dd6);--info-fg:var(--sn-stylekit-info-contrast-color,#fff);--success:var(--sn-stylekit-success-color,#1e8a34);--warning:var(--sn-stylekit-warning-color,#a96500);--danger:var(--sn-stylekit-danger-color,#cc1f36);--danger-fg:var(--sn-stylekit-danger-contrast-color,#fff);--placeholder:var(--sn-stylekit-input-placeholder-color,var(--muted));--success-text:color-mix(in srgb, var(--success) 70%, var(--fg));--warning-text:color-mix(in srgb, var(--warning) 55%, var(--fg));--danger-text:color-mix(in srgb, var(--danger) 75%, var(--fg));--keys:color-mix(in srgb, var(--info) 60%, var(--danger));--font:var(--sn-stylekit-sans-serif-font,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);--mono:var(--sn-stylekit-monospace-font,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);--radius:6px;--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark}@media (prefers-color-scheme:dark){:root{--lightningcss-light: ;--lightningcss-dark:initial}html.standalone{--bg:#17181b;--fg:#e7e8ea;--muted:#9a9ea6;--border:#2e3036;--panel:#1d1f23;--contrast:#262930;--info:#4c9df0;--success:#4fbf63;--warning:#e3a33a;--danger:#f0566a;--placeholder:#6d7179}}html.theme-pending{opacity:0}*{box-sizing:border-box}html,body{background:var(--bg);height:100%;color:var(--fg);font:14px/1.45 var(--font);margin:0}#app,.app{flex-direction:column;height:100%;min-height:0;display:flex}h2,h3{margin:0;font-weight:600}h2{font-size:1.15rem}h3{align-items:center;gap:6px;font-size:.95rem;display:flex}a{color:var(--info)}code{font-family:var(--mono);word-break:break-all;font-size:.9em}.muted{color:var(--muted)}.small{font-size:.85rem}.input{width:100%;min-width:0;font:inherit;color:var(--fg);background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);outline:none;padding:7px 9px}.input::placeholder{color:var(--placeholder)}.input:focus-visible,.button:focus-visible,.icon-button:focus-visible,.entry-item:focus-visible{outline:2px solid var(--info);outline-offset:1px}.input[readonly]{background:var(--panel)}textarea.input{resize:vertical;min-height:2.6em}select.input{width:auto;padding-right:4px}.mono{font-family:var(--mono)}.masked-placeholder{text-align:left;cursor:pointer;color:var(--muted);letter-spacing:2px}.button{font:inherit;color:var(--fg);background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);cursor:pointer;white-space:nowrap;align-items:center;gap:6px;padding:7px 12px;font-weight:500;display:inline-flex}.button.small{padding:4px 9px;font-size:.85rem}.button.primary{background:var(--info);border-color:var(--info);color:var(--info-fg)}.button.danger{color:var(--danger);border-color:var(--danger)}.button:disabled,.icon-button:disabled{opacity:.5;cursor:not-allowed}.icon-button{width:30px;height:30px;color:var(--muted);border-radius:var(--radius);cursor:pointer;background:0 0;border:1px solid #0000;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.icon-button.active{color:var(--warning)}.check{cursor:pointer;align-items:flex-start;gap:8px;margin:6px 0;display:flex}.check input{margin-top:3px}.row{flex-wrap:wrap;align-items:flex-end;gap:10px;display:flex}.row>.field{flex:180px}.row.tight{gap:6px}.row.end{justify-content:flex-end}.grow{flex:200px}.field{flex-direction:column;gap:4px;min-width:0;margin-bottom:10px;display:flex}.field-control{display:contents}.field-label{color:var(--muted);font-size:.8rem;font-weight:600}.hint{color:var(--muted);margin:0;font-size:.8rem}.status{align-items:baseline;gap:6px;margin:6px 0 10px;font-size:.85rem;display:flex}.status svg{flex:none;align-self:flex-start;margin-top:.2em}.status-ok{color:var(--success-text)}.status-error{color:var(--danger-text)}.status-warn{color:var(--warning-text)}.status-info{color:var(--muted)}.pill{white-space:nowrap;background:var(--contrast);color:var(--muted);border-radius:999px;align-items:center;gap:3px;padding:0 7px;font-size:.72rem;line-height:1.6;display:inline-flex}.pill-ok{color:var(--success-text);background:color-mix(in srgb, var(--success) 13%, transparent)}.pill-error{color:var(--danger-text);background:color-mix(in srgb, var(--danger) 13%, transparent)}.pill-warn{color:color-mix(in srgb, var(--warning) 45%, var(--fg));background:color-mix(in srgb, var(--warning) 15%, transparent)}.badge{border-radius:999px;flex:none;padding:2px 8px;font-size:.75rem;font-weight:600}.badge-mnemonic{color:var(--info);background:color-mix(in srgb, var(--info) 12%, transparent)}.badge-privateKey{color:var(--success);background:color-mix(in srgb, var(--success) 12%, transparent)}.badge-other,.badge-recoveryCodes{color:var(--muted);background:var(--contrast)}.badge-sshKey,.badge-pgpKey,.badge-apiKey,.badge-genericKey{color:var(--keys);background:color-mix(in srgb, var(--keys) 12%, transparent)}.banner{background:var(--contrast);border-bottom:1px solid var(--border);padding:8px 14px;font-size:.85rem}.banner svg{vertical-align:-3px;margin-right:4px}.banner-warn{color:var(--fg);background:color-mix(in srgb, var(--warning) 16%, var(--bg))}.layout{flex:1;grid-template-columns:minmax(260px,340px) minmax(0,1fr);min-height:0;display:grid}.sidebar{border-right:1px solid var(--border);background:var(--panel);flex-direction:column;min-height:0;display:flex}.toolbar{background:var(--panel);border-bottom:1px solid var(--border);flex-direction:column;gap:8px;padding:10px 12px;display:flex}.toolbar-row{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.spacer{flex:1}.search{color:var(--muted);flex:200px;position:relative}.search svg{position:absolute;top:50%;left:9px;transform:translateY(-50%)}.search .input{padding-left:30px}.popover-wrap{position:relative}.popover{z-index:15;background:var(--bg);border:1px solid var(--border);border-radius:8px;min-width:190px;max-height:70vh;padding:6px;position:absolute;top:calc(100% + 4px);right:0;overflow-y:auto;box-shadow:0 8px 24px #00000029}.popover-dialog{width:270px;padding:12px}.menu-heading{letter-spacing:.04em;text-transform:uppercase;color:var(--muted);padding:6px 10px 2px;font-size:.72rem;font-weight:600}.menu-group+.menu-group{border-top:1px solid var(--border);margin-top:4px;padding-top:4px}.menu-item{width:100%;font:inherit;text-align:left;color:var(--fg);border-radius:var(--radius);cursor:pointer;background:0 0;border:0;align-items:center;gap:8px;padding:7px 10px;display:flex}.menu-item:focus-visible{background:var(--contrast)}.view-options fieldset{border:0;margin:0 0 10px;padding:0}.view-options legend{color:var(--muted);margin-bottom:2px;padding:0;font-size:.8rem;font-weight:600}.view-options .check{margin:3px 0}.view-options select.input{width:100%}.group-heading{text-transform:uppercase;letter-spacing:.04em;margin:10px 0 4px;font-size:.78rem}.group:first-child .group-heading{margin-top:0}.group-toggle{width:100%;font:inherit;color:var(--muted);border-radius:var(--radius);cursor:pointer;text-transform:inherit;letter-spacing:inherit;background:0 0;border:0;align-items:center;gap:6px;padding:4px;font-weight:600;display:flex}.count{background:var(--contrast);border-radius:999px;padding:0 6px;font-size:.72rem}.toolbar .count{background:0 0;padding:0;font-size:.8rem}.chevron{flex:none;transition:transform .15s}[aria-expanded=true]>.chevron{transform:rotate(90deg)}.entry-list{flex:1;padding:8px 6px;overflow-y:auto}.entry-rows{margin:0;padding:0;list-style:none}.entry-item{width:100%;font:inherit;text-align:left;color:var(--fg);border-radius:var(--radius);cursor:pointer;background:0 0;border:1px solid #0000;align-items:flex-start;gap:10px;padding:9px 10px;display:flex}.entry-item.selected{background:color-mix(in srgb, var(--info) 10%, var(--bg));border-color:var(--border);box-shadow:inset 3px 0 0 var(--info)}.entry-icon{border-radius:var(--radius);padding:6px;display:inline-flex}.entry-main{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.entry-title{text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.entry-title .star{color:var(--warning);vertical-align:-1px;margin-right:4px}.entry-meta{color:var(--muted);text-overflow:ellipsis;white-space:nowrap;font-size:.8rem;overflow:hidden}.entry-pills{flex-wrap:wrap;gap:4px;display:flex}.entry-pills:empty{display:none}.entry-date{color:var(--muted);flex:none;font-size:.75rem}.empty{text-align:center;color:var(--muted);padding:24px 16px}.empty p{margin:6px 0}.detail{min-width:0;min-height:0;overflow-y:auto}.detail.full{flex:1}.stack{max-width:980px;margin:0 auto;padding:12px 12px 48px}.cards{flex-direction:column;gap:6px;margin:0;padding:0;list-style:none;display:flex}.card-entry{background:var(--bg);border:1px solid var(--border);border-radius:8px}.card-entry.open{box-shadow:0 2px 10px #00000012}.card-header{border-radius:8px;align-items:center;gap:4px;padding-right:6px;display:flex}.card-entry.open .card-header{z-index:3;background:var(--bg);border-bottom:1px solid var(--border);border-radius:8px 8px 0 0;position:sticky;top:0}.card-toggle{min-width:0;font:inherit;text-align:left;color:var(--fg);cursor:pointer;background:0 0;border:0;border-radius:8px;flex:auto;align-items:flex-start;gap:10px;padding:10px 12px;display:flex}.card-toggle>.chevron{color:var(--muted);margin-top:7px}.card-toggle:focus-visible,.group-toggle:focus-visible,.section-toggle:focus-visible{outline:2px solid var(--info);outline-offset:-2px}.card-body{padding:0 16px 12px 46px}.entry-actions{flex:none;display:flex}.empty .row.center{justify-content:center;margin-top:12px}.placeholder{flex-direction:column;justify-content:center;align-items:center;gap:8px;height:100%;display:flex}.editor-header{z-index:2;background:var(--bg);border-bottom:1px solid var(--border);align-items:center;gap:6px;padding:10px 16px;display:flex;position:sticky;top:0}.title-input{border-color:#0000;flex:1;font-size:1.1rem;font-weight:600}.title-input:focus{border-color:var(--border)}.editor-body{max-width:880px;padding:8px 16px 32px}.editor-footer{margin-top:16px}.back-button{display:none}.section{border-bottom:1px solid var(--border);padding:10px 0 6px}.section:last-of-type{border-bottom:none}.section.closed{padding-bottom:10px}.section-header{justify-content:space-between;align-items:center;gap:8px;margin-bottom:10px;display:flex}.section.closed .section-header{margin-bottom:0}.section-heading{flex:1;min-width:0}.section-toggle{width:100%;font:inherit;text-align:left;color:var(--fg);border-radius:var(--radius);cursor:pointer;background:0 0;border:0;align-items:center;gap:6px;padding:2px 4px;font-weight:600;display:flex}.section-toggle>.chevron{color:var(--muted)}.section-summary{min-width:0;color:var(--muted);text-overflow:ellipsis;white-space:nowrap;margin-left:4px;font-size:.82rem;font-weight:400;overflow:hidden}.section>h3{margin-bottom:10px}.section p{margin:0 0 10px}.secret{align-items:center;gap:2px;display:flex}.secret-multiline{align-items:flex-start}.secret-actions{flex:none;display:flex}.secret-multiline .secret-actions{flex-direction:column}.word-toolbar{flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:8px;display:flex}.word-grid{grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:6px;margin:0 0 6px;padding:0;list-style:none;display:grid}.word{position:relative}.word-index{min-width:18px;color:var(--muted);text-align:right;pointer-events:none;font-size:.75rem;position:absolute;top:50%;left:8px;transform:translateY(-50%)}.word .input{padding-left:30px;padding-right:6px}.word .input::-webkit-calendar-picker-indicator{display:none!important}.word .input::-webkit-list-button{display:none!important}.word-invalid .input{border-color:var(--danger);background:color-mix(in srgb, var(--danger) 6%, var(--bg))}.custom-field{grid-template-columns:minmax(110px,.6fr) minmax(0,1.4fr) auto;align-items:center;gap:8px;margin-bottom:8px;display:grid}.custom-actions{align-items:center;gap:4px;display:flex}.custom-actions .check{margin:0}.backup-row{align-items:center;margin-bottom:8px}.backup-row input[type=date]{width:auto}.screen{flex:1;justify-content:center;align-items:center;padding:24px 16px;display:flex;overflow:auto}.card{text-align:center;background:var(--bg);border:1px solid var(--border);border-radius:10px;flex-direction:column;align-items:center;gap:10px;width:100%;max-width:420px;padding:24px;display:flex}.card p{margin:0}.lock-card .input,.lock-card .button{justify-content:center;width:100%}.open-note{width:100%;max-width:640px}.open-note textarea{width:100%}.screen.dragging .open-note{border-color:var(--info);box-shadow:0 0 0 3px color-mix(in srgb, var(--info) 30%, transparent)}.paste-note{width:100%}.paste-note>summary{color:var(--info);cursor:pointer;font-size:.85rem}.paste-note>*+*{margin-top:10px}a.button{text-decoration:none}.backup-ready>.row{margin-bottom:10px}.password-form{max-width:460px}.overlay{z-index:40;background:#00000059;justify-content:center;align-items:center;padding:16px;display:flex;position:fixed;inset:0}.dialog{text-align:left;align-items:stretch;box-shadow:0 10px 30px #0003}.toasts{z-index:30;pointer-events:none;flex-direction:column;align-items:flex-end;gap:8px;display:flex;position:fixed;bottom:16px;left:16px;right:16px}.toast{background:var(--bg);border:1px solid var(--border);border-left:4px solid var(--info);border-radius:var(--radius);pointer-events:auto;align-items:center;gap:8px;max-width:420px;padding:8px 8px 8px 12px;font-size:.85rem;display:flex;box-shadow:0 4px 16px #00000026}.toast-success{border-left-color:var(--success)}.toast-error{border-left-color:var(--danger)}.app.privacy .layout,.app.privacy .toolbar,.app.privacy .detail{filter:blur(10px);pointer-events:none;-webkit-user-select:none;user-select:none}.app.privacy~.overlay,.app.privacy~.toasts{filter:blur(10px)}.privacy-cover{z-index:10;width:100%;font:inherit;cursor:pointer;color:var(--muted);background:0 0;border:0;flex-direction:column;justify-content:center;align-items:center;gap:8px;display:flex;position:fixed;inset:0}.app.compact{font-size:13px}.app.compact .input{padding:4px 7px}.app.compact .button{padding:4px 9px}.app.compact .toolbar{gap:6px;padding:6px 10px}.app.compact .stack{padding-top:8px}.app.compact .cards{gap:4px}.app.compact .card-toggle,.app.compact .entry-item{align-items:center;padding:5px 10px}.app.compact .card-toggle>.chevron{margin-top:0}.app.compact .entry-icon{padding:3px}.app.compact .entry-main{flex-direction:row;align-items:center;gap:8px}.app.compact .entry-title{text-overflow:ellipsis;white-space:nowrap;flex:none;min-width:0;max-width:60%;overflow:hidden}.app.compact .entry-meta{flex:0 10 auto;min-width:0}.app.compact .entry-pills{flex-wrap:nowrap;flex:0 auto;min-width:0;overflow:hidden}.app.compact .sidebar .entry-date,.app.compact .entry-pills .pill:not(.pill-error):not(.pill-warn){display:none}.app.compact .card-body{padding:0 12px 8px 36px}.app.compact .section{padding:6px 0 4px}.app.compact .section.closed{padding-bottom:6px}.app.compact .section-header{margin-bottom:6px}.app.compact .section.closed .section-header{margin-bottom:0}.app.compact .field{margin-bottom:6px}.app.compact .helper,.app.compact .field>.hint:not([class*=status-]):not(.hint-safety){display:none}.app.compact .word-grid{grid-template-columns:repeat(auto-fill,minmax(112px,1fr));gap:4px}.app.compact .word .input{padding-left:28px}.app.compact .search .input{padding-left:30px}.app.compact .editor-footer{margin-top:8px}@media (pointer:coarse){.input,.app.compact .input{font-size:16px}.icon-button{width:40px;height:40px}.entry-actions{gap:6px}}@media (max-width:560px){.toolbar .button-text,.app.compact .entry-meta{display:none}.toolbar .button{padding:5px 8px}}@media (max-width:760px){.card-header{flex-wrap:wrap}.card-entry.open .entry-actions{margin-left:auto}.card-body,.app.compact .card-body{padding:0 10px 10px}.entry-date{display:none}.layout{grid-template-columns:minmax(0,1fr)}.layout.has-detail .sidebar,.layout:not(.has-detail) .detail{display:none}.sidebar{border-right:none}.back-button{display:inline-flex}.editor-header{flex-wrap:wrap;padding:8px 10px}.editor-header .badge{margin-right:auto}.title-input{flex-basis:100%;order:10}.editor-body{padding:4px 12px 24px}.custom-field{grid-template-columns:minmax(0,1fr)}.word-grid{grid-template-columns:repeat(auto-fill,minmax(120px,1fr))}}@media (max-width:560px){.toolbar-row{position:relative}.popover-wrap{position:static}.popover{min-width:0;left:0;right:0}.popover-dialog{width:auto}}@media (max-width:760px),(max-height:560px){.card-entry.open .card-header{position:static}}@media (pointer:coarse){.button,.toolbar .button{min-height:40px}.toolbar .button{min-width:36px}.group-toggle,.section-toggle{min-height:40px}.menu-item{min-height:44px}.check{align-items:center;min-height:40px}.check input{width:20px;height:20px}}@media (hover:hover){.button:hover:not(:disabled){background:var(--contrast)}.button.primary:hover:not(:disabled){background:var(--info);filter:brightness(1.08)}.button.danger:hover:not(:disabled){background:var(--danger);color:var(--danger-fg)}.icon-button:hover:not(:disabled){color:var(--fg);background:var(--contrast)}.icon-button.danger:hover:not(:disabled){color:var(--danger)}.group-toggle:hover{color:var(--fg)}.entry-item:hover{background:var(--contrast)}.card-toggle:hover{background:var(--panel)}.menu-item:hover{background:var(--contrast)}.title-input:hover{border-color:var(--border)}}.input::-webkit-date-and-time-value{text-align:start}@media (forced-colors:active){.pill,.status-error,.entry-item.selected,.word-invalid .input{border:1px solid canvastext}.entry-item.selected{border-color:highlight}.word-invalid .input{border-width:2px}}@supports not (color:color-mix(in srgb, red, red)){:root{--keys:var(--info);--success-text:var(--success);--warning-text:var(--fg);--danger-text:var(--danger)}.pill-ok,.pill-error,.pill-warn,.badge,[class*=badge-],.entry-item.selected,.word-invalid .input{background:var(--contrast)}.pill-warn{color:var(--fg)}}@media print{.app{display:none}}.link-button{font:inherit;color:var(--info);cursor:pointer;background:0 0;border:0;margin:0 .25em;padding:0;text-decoration:underline} -/*$vite$:1*/`,document.head.appendChild(e);var t,n,r,i,a,o,s,c,l,u,d,f,p,m,h,g={},_=[],v=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,y=Array.isArray;function b(e,t){for(var n in t)e[n]=t[n];return e}function ee(e){e&&e.parentNode&&e.parentNode.removeChild(e)}function x(e,n,r){var i,a,o,s={};for(o in n)o==`key`?i=n[o]:o==`ref`?a=n[o]:s[o]=n[o];if(arguments.length>2&&(s.children=arguments.length>3?t.call(arguments,2):r),typeof e==`function`&&e.defaultProps!=null)for(o in e.defaultProps)s[o]===void 0&&(s[o]=e.defaultProps[o]);return S(e,s,i,a,null)}function S(e,t,i,a,o){var s={type:e,props:t,key:i,ref:a,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:o??++r,__i:-1,__u:0};return o==null&&n.vnode!=null&&n.vnode(s),s}function C(e){return e.children}function te(e,t){this.props=e,this.context=t}function w(e,t){if(t==null)return e.__?w(e.__,e.__i+1):null;for(var n;tt&&i.sort(s),e=i.shift(),t=i.length,T(e)}finally{i.length=D.__r=0}}function re(e,t,n,r,i,a,o,s,c,l,u){var d,f,p,m,h,v,y=r&&r.__k||_,b=t.length;for(c=ie(n,t,y,c,b),d=0;d0?o=e.__k[a]=S(o.type,o.props,o.key,o.ref?o.ref:null,o.__v):e.__k[a]=o,c=a+f,o.__=e,o.__b=e.__b+1,s=null,(l=o.__i=oe(o,n,c,d))!=-1&&(d--,(s=n[l])&&(s.__u|=2)),s==null||s.__v==null?(l==-1&&(i>u?f--:ic?f--:f++,o.__u|=4))):e.__k[a]=null;if(d)for(a=0;a+!!u){for(i=n-1,a=n+1;i>=0||a=0?i--:a++])!=null&&!(2&l.__u)&&s==l.key&&c==l.type)return o}return-1}function O(e,t,n){t[0]==`-`?e.setProperty(t,n??``):e[t]=n==null?``:typeof n!=`number`||v.test(t)?n:n+`px`}function k(e,t,n,r,i){var a,o;n:if(t==`style`){if(typeof n==`string`)e.style.cssText=n;else{if(typeof r==`string`&&(e.style.cssText=r=``),r)for(t in r)n&&t in n||O(e.style,t,``);if(n)for(t in n)r&&n[t]==r[t]||O(e.style,t,n[t])}}else if(t[0]==`o`&&t[1]==`n`)a=t!=(t=t.replace(d,`$1`)),o=t.toLowerCase(),t=o in e||t==`onFocusOut`||t==`onFocusIn`?o.slice(2):t.slice(2),e.l||={},e.l[t+a]=n,n?r?n[u]=r[u]:(n[u]=f,e.addEventListener(t,a?m:p,a)):e.removeEventListener(t,a?m:p,a);else{if(i==`http://www.w3.org/2000/svg`)t=t.replace(/xlink(H|:h)/,`h`).replace(/sName$/,`s`);else if(t!=`width`&&t!=`height`&&t!=`href`&&t!=`list`&&t!=`form`&&t!=`tabIndex`&&t!=`download`&&t!=`rowSpan`&&t!=`colSpan`&&t!=`role`&&t!=`popover`&&t in e)try{e[t]=n??``;break n}catch{}typeof n==`function`||(n==null||!1===n&&t[4]!=`-`?e.removeAttribute(t):e.setAttribute(t,t==`popover`&&n==1?``:n))}}function A(e){return function(t){if(this.l){var r=this.l[t.type+e];if(t[l]==null)t[l]=f++;else if(t[l]0?e:y(e)?e.map(le):e.constructor===void 0?b({},e):null}function M(e,r,i,a,o,s,c,l,u){var d,f,p,m,h,_,v,b=i.props||g,x=r.props,S=r.type;if(S==`svg`?o=`http://www.w3.org/2000/svg`:S==`math`?o=`http://www.w3.org/1998/Math/MathML`:o||=`http://www.w3.org/1999/xhtml`,s!=null){for(d=0;d=n.__.length&&n.__.push({}),n.__[e]}function R(e){return ge=1,we(Pe,e)}function we(e,t,n){var r=Ce(pe++,2);if(r.t=e,!r.__c&&(r.__=[n?n(t):Pe(void 0,t),function(e){var t=r.__N?r.__N[0]:r.__[0],n=r.t(t,e);t!==n&&(r.__N=[n,r.__[1]],r.__c.setState({}))}],r.__c=F,!F.__f)){var i=function(e,t,n){if(!r.__c.__H)return!0;var i=!1,o=r.__c.props!==e;if(r.__c.__H.__.some(function(e){if(e.__N){i=!0;var t=e.__[0];e.__=e.__N,e.__N=void 0,t!==e.__[0]&&(o=!0)}}),a){var s=a.call(this,e,t,n);return i?s||o:s}return!i||o};F.__f=!0;var a=F.shouldComponentUpdate,o=F.componentWillUpdate;F.componentWillUpdate=function(e,t,n){if(this.__e){var r=a;a=void 0,i(e,t,n),a=r}o&&o.call(this,e,t,n)},F.shouldComponentUpdate=i}return r.__N||r.__}function z(e,t){var n=Ce(pe++,3);!I.__s&&Ne(n.__H,t)&&(n.__=e,n.u=t,F.__H.__h.push(n))}function B(e){return ge=5,Te(function(){return{current:e}},[])}function Te(e,t){var n=Ce(pe++,7);return Ne(n.__H,t)&&(n.__=e(),n.__H=t,n.__h=e),n.__}function Ee(e,t){return ge=8,Te(function(){return e},t)}function De(e){var t=F.context[e.__c],n=Ce(pe++,9);return n.c=e,t?(n.__??(n.__=!0,t.sub(F)),t.props.value):e.__}function Oe(){var e=Ce(pe++,11);if(!e.__){for(var t=F.__v;t!==null&&!t.__m&&t.__!==null;)t=t.__;var n=t.__m||(t.__m=[0,0]);e.__=`P`+n[0]+`-`+n[1]++}return e.__}function ke(){for(var e;e=_e.shift();){var t=e.__H;if(e.__P&&t)try{t.__h.some(Me),t.__h.some(V),t.__h=[]}catch(n){t.__h=[],I.__e(n,e.__v)}}}I.__b=function(e){F=null,L&&L(e)},I.__=function(e,t){e&&t.__k&&t.__k.__m&&(e.__m=t.__k.__m),Se&&Se(e,t)},I.__r=function(e){ve&&ve(e),pe=0;var t=(F=e.__c).__H;t&&(me===F?(t.__h=[],F.__h=[],t.__.some(function(e){e.__N&&(e.__=e.__N),e.u=e.__N=void 0})):(t.__h.some(Me),t.__h.some(V),t.__h=[],pe=0)),me=F},I.diffed=function(e){ye&&ye(e);var t=e.__c;t&&t.__H&&(t.__H.__h.length&&(_e.push(t)!==1&&he===I.requestAnimationFrame||((he=I.requestAnimationFrame)||je)(ke)),t.__H.__.some(function(e){e.u&&=(e.__H=e.u,void 0)})),me=F=null},I.__c=function(e,t){t.some(function(e){try{e.__h.some(Me),e.__h=e.__h.filter(function(e){return!e.__||V(e)})}catch(n){t.some(function(e){e.__h&&=[]}),t=[],I.__e(n,e.__v)}}),be&&be(e,t)},I.unmount=function(e){xe&&xe(e);var t,n=e.__c;n&&n.__H&&(n.__H.__.some(function(e){try{Me(e)}catch(e){t=e}}),n.__H=void 0,t&&I.__e(t,n.__v))};var Ae=typeof requestAnimationFrame==`function`;function je(e){var t,n=function(){clearTimeout(r),Ae&&cancelAnimationFrame(t),setTimeout(e)},r=setTimeout(n,35);Ae&&(t=requestAnimationFrame(n))}function Me(e){var t=F,n=e.__c;typeof n==`function`&&(e.__c=void 0,n()),F=t}function V(e){var t=F;e.__c=e.__(),F=t}function Ne(e,t){return!e||e.length!==t.length||t.some(function(t,n){return t!==e[n]})}function Pe(e,t){return typeof t==`function`?t(e):t}var Fe=0;Array.isArray;function H(e,t,r,i,a,o){t||={};var s,c,l=t;if(`ref`in l)for(c in l={},t)c==`ref`?s=t[c]:l[c]=t[c];var u={type:e,props:l,key:r,ref:s,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--Fe,__i:-1,__u:0,__source:a,__self:o};if(typeof e==`function`&&(s=e.defaultProps))for(c in s)l[c]===void 0&&(l[c]=s[c]);return n.vnode&&n.vnode(u),u}var Ie={eye:`M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12Z M12 9a3 3 0 1 0 0 6 3 3 0 0 0 0-6Z`,eyeOff:`M3 3l18 18 M10.6 5.1A10 10 0 0 1 12 5c6.5 0 10 7 10 7a17 17 0 0 1-3.2 4.2 M6.6 6.6A17 17 0 0 0 2 12s3.5 7 10 7a9.6 9.6 0 0 0 5.4-1.6 M9.9 9.9a3 3 0 0 0 4.2 4.2`,copy:`M9 9h11v11H9z M5 15H4V4h11v1`,plus:`M12 5v14 M5 12h14`,star:`M12 3l2.8 5.7 6.2.9-4.5 4.4 1.1 6.2L12 17.3 6.4 20.2l1.1-6.2L3 9.6l6.2-.9Z`,lock:`M6 11h12v10H6z M8 11V7a4 4 0 0 1 8 0v4`,settings:`M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1.1 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1Z`,trash:`M4 7h16 M10 11v6 M14 11v6 M6 7l1 13h10l1-13 M9 7V4h6v3`,back:`M15 18l-6-6 6-6`,check:`M5 12l5 5 9-10`,alert:`M12 3l10 18H2Z M12 10v4 M12 17.5v.5`,key:`M14 10a4 4 0 1 0-3.6 4L13 17h2v2h2v2h3v-3l-6.4-6.4A4 4 0 0 0 14 10Z`,seed:`M4 6h16 M4 12h16 M4 18h10`,shield:`M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6Z`,duplicate:`M8 8h12v12H8z M4 16V4h12`,archive:`M3 4h18v4H3z M5 8v12h14V8 M10 12h4`,x:`M6 6l12 12 M18 6L6 18`,search:`M11 4a7 7 0 1 0 0 14 7 7 0 0 0 0-14Z M20 20l-4-4`,chevron:`M9 6l6 6-6 6`,wallet:`M3 7h15a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H3z M3 7V5h13v2 M16 13.5h.01`,terminal:`M4 6l6 6-6 6 M12 19h8`,mail:`M3 6h18v12H3z M3 7l9 6 9-6`,code:`M8 6l-6 6 6 6 M16 6l6 6-6 6`,list:`M9 6h11 M9 12h11 M9 18h11 M4 6h.01 M4 12h.01 M4 18h.01`,clock:`M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18Z M12 7v5l3 2`,expand:`M7 9l5-5 5 5 M7 15l5 5 5-5`,collapse:`M7 4l5 5 5-5 M7 20l5-5 5 5`,sliders:`M4 6h16 M4 12h16 M4 18h16 M9 4v4 M15 10v4 M7 16v4`,download:`M12 4v11 M7 10l5 5 5-5 M5 20h14`,file:`M6 3h8l4 4v14H6z M14 3v4h4`},U=({name:e,size:t=16,...n})=>H(`svg`,{width:t,height:t,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,"stroke-width":`2`,"stroke-linecap":`round`,"stroke-linejoin":`round`,"aria-hidden":`true`,...n,children:H(`path`,{d:Ie[e]})}),Le=new TextEncoder,Re=new TextDecoder,W=e=>Le.encode(e),ze=e=>Re.decode(e),Be=e=>Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``),Ve=e=>{let t=e.startsWith(`0x`)||e.startsWith(`0X`)?e.slice(2):e;if(t.length%2!=0||/[^0-9a-fA-F]/.test(t))throw Error(`Invalid hex`);let n=new Uint8Array(t.length/2);for(let e=0;e{let t=``;for(let n=0;n{let t=atob(e),n=new Uint8Array(t.length);for(let e=0;eglobalThis.crypto!==void 0&&globalThis.crypto.subtle!==void 0,K=e=>e,We=async e=>new Uint8Array(await crypto.subtle.digest(`SHA-256`,K(e))),Ge=async(e,t)=>{let n=await crypto.subtle.importKey(`raw`,K(e),{name:`HMAC`,hash:`SHA-512`},!1,[`sign`]);return new Uint8Array(await crypto.subtle.sign(`HMAC`,n,K(t)))},Ke=(e,t)=>{if(e.length!==t.length)return!1;for(let n=0;n{let t=new Uint8Array(e);return crypto.getRandomValues(t),t},qe=()=>typeof crypto.randomUUID==`function`?crypto.randomUUID():Be(q(16)),Je=[`mnemonic`,`privateKey`,`sshKey`,`pgpKey`,`apiKey`,`genericKey`,`recoveryCodes`,`other`],J={mnemonic:{label:`Seed phrase`,one:`seed phrase`,plural:`seed phrases`,group:`crypto`,secret:`words`,secretLabel:`Seed phrase`,passphraseLabel:`Passphrase (25th word)`,passphraseHint:`Optional BIP39 passphrase. A different passphrase opens a different wallet.`,serviceLabel:`Chain / coin`,accountLabel:`Wallet / device`,expires:!1,backupReminders:!0},privateKey:{label:`Wallet key`,one:`wallet key`,plural:`wallet keys`,group:`crypto`,secret:`key`,secretLabel:`Private key`,secretPlaceholder:`Hex, WIF, xprv, nsec, base58, keystore JSON…`,passphraseLabel:`Keystore password`,passphraseHint:`Only for encrypted keystores (e.g. Ethereum JSON keystores).`,serviceLabel:`Chain / coin`,accountLabel:`Wallet / device`,expires:!1,backupReminders:!0},sshKey:{label:`SSH key`,one:`SSH key`,plural:`SSH keys`,group:`keys`,secret:`key`,secretLabel:`Private key`,secretPlaceholder:`-----BEGIN OPENSSH PRIVATE KEY-----`,passphraseLabel:`Key passphrase`,passphraseHint:`The passphrase that unlocks the key file, if it has one.`,publicKey:{label:`Public key`,placeholder:`ssh-ed25519 AAAA… user@host`,fingerprintLabel:`Fingerprint`,fingerprintPlaceholder:`SHA256:…`},serviceLabel:`Hosts / service`,accountLabel:`User / account`,expires:!0,backupReminders:!1},pgpKey:{label:`PGP key`,one:`PGP key`,plural:`PGP keys`,group:`keys`,secret:`key`,secretLabel:`Private key`,secretPlaceholder:`-----BEGIN PGP PRIVATE KEY BLOCK-----`,passphraseLabel:`Key passphrase`,passphraseHint:`The passphrase that protects the secret key.`,publicKey:{label:`Public key`,placeholder:`-----BEGIN PGP PUBLIC KEY BLOCK-----`,fingerprintLabel:`Fingerprint`,fingerprintPlaceholder:`40 hex characters`},serviceLabel:`Used for`,accountLabel:`User ID / email`,expires:!0,backupReminders:!0},apiKey:{label:`API key or token`,one:`API key`,plural:`API keys`,group:`keys`,secret:`token`,secretLabel:`Key or token`,secretPlaceholder:`Paste the key or token`,serviceLabel:`Service`,accountLabel:`Account / project`,expires:!0,backupReminders:!1},genericKey:{label:`Other key`,one:`other key`,plural:`other keys`,group:`keys`,secret:`key`,secretLabel:`Secret key`,secretPlaceholder:`age, WireGuard, PEM, JSON Web Key, Nostr…`,passphraseLabel:`Passphrase`,passphraseHint:`If the key is encrypted.`,publicKey:{label:`Public key`,placeholder:`Public key or recipient`,fingerprintLabel:`Fingerprint / key ID`,fingerprintPlaceholder:`Optional`},serviceLabel:`Used for`,accountLabel:`Account / owner`,expires:!0,backupReminders:!1},recoveryCodes:{label:`Recovery codes`,one:`set of recovery codes`,plural:`sets of recovery codes`,group:`secrets`,secret:`codes`,secretLabel:`Recovery codes`,secretPlaceholder:`One code per line`,serviceLabel:`Service`,accountLabel:`Account`,expires:!1,backupReminders:!0},other:{label:`Other secret`,one:`other secret`,plural:`other secrets`,group:`secrets`,secret:`fields`,secretLabel:`Fields`,serviceLabel:`Service`,accountLabel:`Account`,expires:!1,backupReminders:!1}},Ye={crypto:`Crypto`,keys:`Keys`,secrets:`Secrets`},Xe=e=>J[e].group===`crypto`,Ze=`keyfold`,Qe=`Managed by the Keyfold editor for Standard Notes (https://github.com/nickstruglia/standard-notes-keyfold). Open it with Keyfold; do not edit it as plain text or convert it to Super, which can damage the data. `,$e=Qe+`The vault below lists each entry with its label, kind and secret; seed phrase words are in order, and \\n in a value is a line break.`,et=e=>`The vault below is encrypted with ${e}: PBKDF2-SHA256 (password NFC-normalized, the salt and iteration count below) gives an AES-256-GCM key; the IV is below, the ciphertext ends with the 16-byte tag, the associated data is "keyfold|1|PBKDF2-SHA256||AES-256-GCM", and the plaintext is the vault as JSON.`,tt=Qe+et(`your vault password`),Y={autoHideSeconds:30,clipboardClearSeconds:30,hideOnBlur:!0,privacyScreen:!1,autoLockMinutes:5,backupReminderMonths:12,layout:`stacked`,density:`comfortable`,singleExpand:!1,groupBy:`kind`,sort:`updated`,lastExportedAt:``},nt=()=>{let e=new Date,t=e=>String(e).padStart(2,`0`);return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())}`},rt=()=>({entries:[],settings:{...Y}}),it=(e,t={})=>{let n=new Date().toISOString();return{id:qe(),kind:e,label:``,description:``,chain:``,wallet:``,service:``,account:``,createdOn:nt(),expiresOn:``,tags:[],favorite:!1,archived:!1,scheme:`bip39`,words:e===`mnemonic`?Array(12).fill(``):[],passphrase:``,passphraseHint:``,secret:``,derivationPath:``,fingerprint:``,publicInfo:``,backups:[],customFields:[],notes:``,addedAt:n,updatedAt:n,...t}},X=(e,t=``)=>typeof e==`string`?e:t,at=(e,t=!1)=>typeof e==`boolean`?e:t,ot=(e,t)=>typeof e==`number`&&Number.isFinite(e)&&e>=0?e:t,st=e=>Array.isArray(e)?e:[],ct=(e,t,n)=>t.includes(e)?e:n,lt=e=>e&&typeof e==`object`&&!Array.isArray(e)?e:{},ut=[`bip39`,`electrum`,`aezeed`,`slip39`,`monero`,`other`],dt=e=>{let t=lt(e),n=it(`other`);return{...t,id:X(t.id)||n.id,kind:Je.includes(t.kind)?t.kind:`other`,label:X(t.label),description:X(t.description),chain:X(t.chain),wallet:X(t.wallet),service:X(t.service),account:X(t.account),createdOn:X(t.createdOn),expiresOn:X(t.expiresOn),tags:st(t.tags).filter(e=>typeof e==`string`),favorite:at(t.favorite),archived:at(t.archived),scheme:ut.includes(t.scheme)?t.scheme:`bip39`,words:st(t.words).map(e=>X(e)),passphrase:X(t.passphrase),passphraseHint:X(t.passphraseHint),secret:X(t.secret),derivationPath:X(t.derivationPath),fingerprint:X(t.fingerprint),publicInfo:X(t.publicInfo),backups:st(t.backups).map(e=>{let t=lt(e);return{...t,id:X(t.id)||qe(),location:X(t.location),verifiedOn:X(t.verifiedOn)}}),customFields:st(t.customFields).map(e=>{let t=lt(e);return{...t,id:X(t.id)||qe(),label:X(t.label),value:X(t.value),hidden:at(t.hidden,!0),multiline:t.multiline===!0||X(t.value).includes(` -`)}}),notes:X(t.notes),addedAt:X(t.addedAt)||n.addedAt,updatedAt:X(t.updatedAt)||n.updatedAt}},ft={layout:[`stacked`,`split`],density:[`comfortable`,`compact`],groupBy:[`none`,`kind`,`chain`,`wallet`,`tag`],sort:[`updated`,`label`,`created`]},pt=new WeakSet,mt=e=>pt.has(e),ht=(e,t)=>st(e.entries).some(e=>{let t=lt(e);return t.kind!==void 0&&!Je.includes(t.kind)||t.scheme!==void 0&&!ut.includes(t.scheme)})||Object.entries(ft).some(([e,n])=>t[e]!==void 0&&!n.includes(t[e])),gt=(e,t,n)=>{let r=ot(e,t);return r>n?t:r},_t=e=>{let t=lt(e),n=lt(t.settings),r={...t,entries:st(t.entries).map(dt),settings:{...n,autoHideSeconds:gt(n.autoHideSeconds,Y.autoHideSeconds,86400),clipboardClearSeconds:gt(n.clipboardClearSeconds,Y.clipboardClearSeconds,86400),hideOnBlur:at(n.hideOnBlur,Y.hideOnBlur),privacyScreen:at(n.privacyScreen,Y.privacyScreen),autoLockMinutes:gt(n.autoLockMinutes,Y.autoLockMinutes,10080),backupReminderMonths:gt(n.backupReminderMonths,Y.backupReminderMonths,1200),layout:ct(n.layout,[`stacked`,`split`],Y.layout),density:ct(n.density,[`comfortable`,`compact`],Y.density),singleExpand:at(n.singleExpand,Y.singleExpand),groupBy:ct(n.groupBy,[`none`,`kind`,`chain`,`wallet`,`tag`],Y.groupBy),sort:ct(n.sort,[`updated`,`label`,`created`],Y.sort),lastExportedAt:X(n.lastExportedAt)}};return ht(t,n)&&pt.add(r),r},vt=e=>{let t=lt(e);return t.kdf===`PBKDF2-SHA256`&&t.cipher===`AES-256-GCM`&&typeof t.iterations==`number`&&Number.isInteger(t.iterations)&&t.iterations>=1e3&&t.iterations<=1e7&&typeof t.salt==`string`&&typeof t.iv==`string`&&typeof t.ciphertext==`string`},yt=e=>{let t=e?.replace(/^\uFEFF/,``);if(!t||!t.trim())return{kind:`empty`};let n;try{n=JSON.parse(t)}catch{return{kind:`foreign`,text:t}}let r=lt(n);if(r.app!==`keyfold`)return{kind:`foreign`,text:t};let i=typeof r.version==`number`?r.version:0;return i>1?{kind:`newer`,version:i}:r.encryption===void 0?{kind:`plain`,vault:_t(r.vault)}:vt(r.encryption)?typeof r.exportedAt==`string`?{kind:`encrypted`,blob:r.encryption,exportedAt:r.exportedAt}:{kind:`encrypted`,blob:r.encryption}:{kind:`unsupported`}},bt=e=>JSON.stringify({app:Ze,version:1,readme:$e,vault:e},null,1),xt=e=>JSON.stringify({app:Ze,version:1,readme:tt,encryption:e},null,1),St=e=>{if(!e)return`Keyfold (password protected)`;let t=e.entries.filter(e=>!e.archived),n=Je.flatMap(e=>{let n=t.filter(t=>t.kind===e).length;return n?[`${n} ${n===1?J[e].one:J[e].plural}`]:[]});return`Keyfold: ${n.length?n.join(`, `):`empty`}`},Ct=e=>e.backups.map(e=>e.verifiedOn).filter(Boolean).sort().pop()??``,wt=(e,t,n=new Date)=>{if(t<=0||e.archived||!J[e.kind].backupReminders)return!1;let r=Ct(e);if(!r)return!0;let i=new Date(`${r}T00:00:00`);return i.setMonth(i.getMonth()+t),i.getTime()<=n.getTime()},Tt=(e,t=new Date)=>{if(!e.expiresOn||!J[e.kind].expires)return null;let n=new Date(`${e.expiresOn}T00:00:00`);if(Number.isNaN(n.getTime()))return null;let r=new Date(t.getFullYear(),t.getMonth(),t.getDate());return Math.round((n.getTime()-r.getTime())/864e5)},Et=(e,t=new Date)=>{let n=Tt(e,t);return n!==null&&n<=30&&!e.archived},Dt=fe({settings:Y,readOnly:!1,hideEpoch:0,copy:()=>void 0,toast:()=>void 0,confirm:async()=>!1,sectionOpen:(e,t)=>t,setSectionOpen:()=>void 0}),Z=()=>De(Dt),Ot=(e,t)=>{let{sectionOpen:n,setSectionOpen:r}=Z();return[n(e,t),t=>r(e,t)]},kt=(e=!0)=>{let t=B(null);return z(()=>{e&&t.current?.focus()},[]),t},At=(e,t)=>{let[n,r]=R(void 0),i=B(0);return z(()=>{let t=++i.current;e().then(e=>t===i.current&&r(()=>e),()=>t===i.current&&r(void 0))},t),n},jt=e=>{let{hideEpoch:t,settings:n}=Z(),[r,i]=R(!1);return z(()=>i(!1),[t]),z(()=>{if(!r||!n.autoHideSeconds)return;let e=setTimeout(()=>i(!1),n.autoHideSeconds*1e3);return()=>clearTimeout(e)},[r,n.autoHideSeconds,e]),[r,i]},Mt=()=>typeof matchMedia==`function`&&matchMedia(`(pointer: coarse)`).matches,Nt={autocomplete:`off`,autocorrect:`off`,autocapitalize:`off`,spellcheck:!1,"data-1p-ignore":`true`,"data-lpignore":`true`,"data-bwignore":`true`,"data-form-type":`other`,"data-secret":``},Pt={autocorrect:`off`,autocapitalize:`off`,spellcheck:!1},Ft=({value:e,onInput:t,label:n,placeholder:r,multiline:i,mono:a,id:o,onMultilinePaste:s})=>{let{readOnly:c,copy:l}=Z(),[u,d]=jt(e),f=`input ${a?`mono`:``}`,p=B(null),[m,h]=R(!1);z(()=>{m&&u&&(p.current?.focus(),h(!1))},[m,u]);let g;return g=i&&!u?H(`button`,{type:`button`,class:`input masked-placeholder`,"aria-label":`${n} (hidden). Reveal to view or edit`,onClick:()=>{d(!0),h(!0)},children:e?`${`•`.repeat(12)} ${e.length} characters, hidden`:r||`Empty`}):i?H(`textarea`,{ref:p,id:o,class:f,value:e,rows:e.length>120?6:3,placeholder:r,"aria-label":n,readOnly:c,onInput:e=>t(e.currentTarget.value),...Nt}):H(`input`,{id:o,class:f,type:u?`text`:`password`,value:e,placeholder:r,"aria-label":n,readOnly:c,onInput:e=>t(e.currentTarget.value),onPaste:t=>{let n=t.clipboardData?.getData(`text`)??``;if(!s||!/[\r\n]/.test(n))return;t.preventDefault();let r=t.currentTarget,i=r.selectionStart??e.length,a=r.selectionEnd??e.length;s(e.slice(0,i)+n+e.slice(a))},...Nt}),H(`div`,{class:`secret ${i?`secret-multiline`:``}`,children:[g,H(`div`,{class:`secret-actions`,children:[H(`button`,{type:`button`,class:`icon-button`,title:u?`Hide`:`Reveal`,"aria-label":`${u?`Hide`:`Reveal`} ${n}`,onClick:()=>d(!u),children:H(U,{name:u?`eyeOff`:`eye`})}),H(`button`,{type:`button`,class:`icon-button`,title:`Copy`,"aria-label":`Copy ${n}`,disabled:!e,onClick:()=>l(e,n),children:H(U,{name:`copy`})})]})]})},It=`abandon ability able about above absent absorb abstract - absurd abuse access accident account accuse achieve acid - acoustic acquire across act action actor actress actual - adapt add addict address adjust admit adult advance - advice aerobic affair afford afraid again age agent - agree ahead aim air airport aisle alarm album - alcohol alert alien all alley allow almost alone - alpha already also alter always amateur amazing among - amount amused analyst anchor ancient anger angle angry - animal ankle announce annual another answer antenna antique - anxiety any apart apology appear apple approve april - arch arctic area arena argue arm armed armor - army around arrange arrest arrive arrow art artefact - artist artwork ask aspect assault asset assist assume - asthma athlete atom attack attend attitude attract auction - audit august aunt author auto autumn average avocado - avoid awake aware away awesome awful awkward axis - baby bachelor bacon badge bag balance balcony ball - bamboo banana banner bar barely bargain barrel base - basic basket battle beach bean beauty because become - beef before begin behave behind believe below belt - bench benefit best betray better between beyond bicycle - bid bike bind biology bird birth bitter black - blade blame blanket blast bleak bless blind blood - blossom blouse blue blur blush board boat body - boil bomb bone bonus book boost border boring - borrow boss bottom bounce box boy bracket brain - brand brass brave bread breeze brick bridge brief - bright bring brisk broccoli broken bronze broom brother - brown brush bubble buddy budget buffalo build bulb - bulk bullet bundle bunker burden burger burst bus - business busy butter buyer buzz cabbage cabin cable - cactus cage cake call calm camera camp can - canal cancel candy cannon canoe canvas canyon capable - capital captain car carbon card cargo carpet carry - cart case cash casino castle casual cat catalog - catch category cattle caught cause caution cave ceiling - celery cement census century cereal certain chair chalk - champion change chaos chapter charge chase chat cheap - check cheese chef cherry chest chicken chief child - chimney choice choose chronic chuckle chunk churn cigar - cinnamon circle citizen city civil claim clap clarify - claw clay clean clerk clever click client cliff - climb clinic clip clock clog close cloth cloud - clown club clump cluster clutch coach coast coconut - code coffee coil coin collect color column combine - come comfort comic common company concert conduct confirm - congress connect consider control convince cook cool copper - copy coral core corn correct cost cotton couch - country couple course cousin cover coyote crack cradle - craft cram crane crash crater crawl crazy cream - credit creek crew cricket crime crisp critic crop - cross crouch crowd crucial cruel cruise crumble crunch - crush cry crystal cube culture cup cupboard curious - current curtain curve cushion custom cute cycle dad - damage damp dance danger daring dash daughter dawn - day deal debate debris decade december decide decline - decorate decrease deer defense define defy degree delay - deliver demand demise denial dentist deny depart depend - deposit depth deputy derive describe desert design desk - despair destroy detail detect develop device devote diagram - dial diamond diary dice diesel diet differ digital - dignity dilemma dinner dinosaur direct dirt disagree discover - disease dish dismiss disorder display distance divert divide - divorce dizzy doctor document dog doll dolphin domain - donate donkey donor door dose double dove draft - dragon drama drastic draw dream dress drift drill - drink drip drive drop drum dry duck dumb - dune during dust dutch duty dwarf dynamic eager - eagle early earn earth easily east easy echo - ecology economy edge edit educate effort egg eight - either elbow elder electric elegant element elephant elevator - elite else embark embody embrace emerge emotion employ - empower empty enable enact end endless endorse enemy - energy enforce engage engine enhance enjoy enlist enough - enrich enroll ensure enter entire entry envelope episode - equal equip era erase erode erosion error erupt - escape essay essence estate eternal ethics evidence evil - evoke evolve exact example excess exchange excite exclude - excuse execute exercise exhaust exhibit exile exist exit - exotic expand expect expire explain expose express extend - extra eye eyebrow fabric face faculty fade faint - faith fall false fame family famous fan fancy - fantasy farm fashion fat fatal father fatigue fault - favorite feature february federal fee feed feel female - fence festival fetch fever few fiber fiction field - figure file film filter final find fine finger - finish fire firm first fiscal fish fit fitness - fix flag flame flash flat flavor flee flight - flip float flock floor flower fluid flush fly - foam focus fog foil fold follow food foot - force forest forget fork fortune forum forward fossil - foster found fox fragile frame frequent fresh friend - fringe frog front frost frown frozen fruit fuel - fun funny furnace fury future gadget gain galaxy - gallery game gap garage garbage garden garlic garment - gas gasp gate gather gauge gaze general genius - genre gentle genuine gesture ghost giant gift giggle - ginger giraffe girl give glad glance glare glass - glide glimpse globe gloom glory glove glow glue - goat goddess gold good goose gorilla gospel gossip - govern gown grab grace grain grant grape grass - gravity great green grid grief grit grocery group - grow grunt guard guess guide guilt guitar gun - gym habit hair half hammer hamster hand happy - harbor hard harsh harvest hat have hawk hazard - head health heart heavy hedgehog height hello helmet - help hen hero hidden high hill hint hip - hire history hobby hockey hold hole holiday hollow - home honey hood hope horn horror horse hospital - host hotel hour hover hub huge human humble - humor hundred hungry hunt hurdle hurry hurt husband - hybrid ice icon idea identify idle ignore ill - illegal illness image imitate immense immune impact impose - improve impulse inch include income increase index indicate - indoor industry infant inflict inform inhale inherit initial - inject injury inmate inner innocent input inquiry insane - insect inside inspire install intact interest into invest - invite involve iron island isolate issue item ivory - jacket jaguar jar jazz jealous jeans jelly jewel - job join joke journey joy judge juice jump - jungle junior junk just kangaroo keen keep ketchup - key kick kid kidney kind kingdom kiss kit - kitchen kite kitten kiwi knee knife knock know - lab label labor ladder lady lake lamp language - laptop large later latin laugh laundry lava law - lawn lawsuit layer lazy leader leaf learn leave - lecture left leg legal legend leisure lemon lend - length lens leopard lesson letter level liar liberty - library license life lift light like limb limit - link lion liquid list little live lizard load - loan lobster local lock logic lonely long loop - lottery loud lounge love loyal lucky luggage lumber - lunar lunch luxury lyrics machine mad magic magnet - maid mail main major make mammal man manage - mandate mango mansion manual maple marble march margin - marine market marriage mask mass master match material - math matrix matter maximum maze meadow mean measure - meat mechanic medal media melody melt member memory - mention menu mercy merge merit merry mesh message - metal method middle midnight milk million mimic mind - minimum minor minute miracle mirror misery miss mistake - mix mixed mixture mobile model modify mom moment - monitor monkey monster month moon moral more morning - mosquito mother motion motor mountain mouse move movie - much muffin mule multiply muscle museum mushroom music - must mutual myself mystery myth naive name napkin - narrow nasty nation nature near neck need negative - neglect neither nephew nerve nest net network neutral - never news next nice night noble noise nominee - noodle normal north nose notable note nothing notice - novel now nuclear number nurse nut oak obey - object oblige obscure observe obtain obvious occur ocean - october odor off offer office often oil okay - old olive olympic omit once one onion online - only open opera opinion oppose option orange orbit - orchard order ordinary organ orient original orphan ostrich - other outdoor outer output outside oval oven over - own owner oxygen oyster ozone pact paddle page - pair palace palm panda panel panic panther paper - parade parent park parrot party pass patch path - patient patrol pattern pause pave payment peace peanut - pear peasant pelican pen penalty pencil people pepper - perfect permit person pet phone photo phrase physical - piano picnic picture piece pig pigeon pill pilot - pink pioneer pipe pistol pitch pizza place planet - plastic plate play please pledge pluck plug plunge - poem poet point polar pole police pond pony - pool popular portion position possible post potato pottery - poverty powder power practice praise predict prefer prepare - present pretty prevent price pride primary print priority - prison private prize problem process produce profit program - project promote proof property prosper protect proud provide - public pudding pull pulp pulse pumpkin punch pupil - puppy purchase purity purpose purse push put puzzle - pyramid quality quantum quarter question quick quit quiz - quote rabbit raccoon race rack radar radio rail - rain raise rally ramp ranch random range rapid - rare rate rather raven raw razor ready real - reason rebel rebuild recall receive recipe record recycle - reduce reflect reform refuse region regret regular reject - relax release relief rely remain remember remind remove - render renew rent reopen repair repeat replace report - require rescue resemble resist resource response result retire - retreat return reunion reveal review reward rhythm rib - ribbon rice rich ride ridge rifle right rigid - ring riot ripple risk ritual rival river road - roast robot robust rocket romance roof rookie room - rose rotate rough round route royal rubber rude - rug rule run runway rural sad saddle sadness - safe sail salad salmon salon salt salute same - sample sand satisfy satoshi sauce sausage save say - scale scan scare scatter scene scheme school science - scissors scorpion scout scrap screen script scrub sea - search season seat second secret section security seed - seek segment select sell seminar senior sense sentence - series service session settle setup seven shadow shaft - shallow share shed shell sheriff shield shift shine - ship shiver shock shoe shoot shop short shoulder - shove shrimp shrug shuffle shy sibling sick side - siege sight sign silent silk silly silver similar - simple since sing siren sister situate six size - skate sketch ski skill skin skirt skull slab - slam sleep slender slice slide slight slim slogan - slot slow slush small smart smile smoke smooth - snack snake snap sniff snow soap soccer social - sock soda soft solar soldier solid solution solve - someone song soon sorry sort soul sound soup - source south space spare spatial spawn speak special - speed spell spend sphere spice spider spike spin - spirit split spoil sponsor spoon sport spot spray - spread spring spy square squeeze squirrel stable stadium - staff stage stairs stamp stand start state stay - steak steel stem step stereo stick still sting - stock stomach stone stool story stove strategy street - strike strong struggle student stuff stumble style subject - submit subway success such sudden suffer sugar suggest - suit summer sun sunny sunset super supply supreme - sure surface surge surprise surround survey suspect sustain - swallow swamp swap swarm swear sweet swift swim - swing switch sword symbol symptom syrup system table - tackle tag tail talent talk tank tape target - task taste tattoo taxi teach team tell ten - tenant tennis tent term test text thank that - theme then theory there they thing this thought - three thrive throw thumb thunder ticket tide tiger - tilt timber time tiny tip tired tissue title - toast tobacco today toddler toe together toilet token - tomato tomorrow tone tongue tonight tool tooth top - topic topple torch tornado tortoise toss total tourist - toward tower town toy track trade traffic tragic - train transfer trap trash travel tray treat tree - trend trial tribe trick trigger trim trip trophy - trouble truck true truly trumpet trust truth try - tube tuition tumble tuna tunnel turkey turn turtle - twelve twenty twice twin twist two type typical - ugly umbrella unable unaware uncle uncover under undo - unfair unfold unhappy uniform unique unit universe unknown - unlock until unusual unveil update upgrade uphold upon - upper upset urban urge usage use used useful - useless usual utility vacant vacuum vague valid valley - valve van vanish vapor various vast vault vehicle - velvet vendor venture venue verb verify version very - vessel veteran viable vibrant vicious victory video view - village vintage violin virtual virus visa visit visual - vital vivid vocal voice void volcano volume vote - voyage wage wagon wait walk wall walnut want - warfare warm warrior wash wasp waste water wave - way wealth weapon wear weasel weather web wedding - weekend weird welcome west wet whale what wheat - wheel when where whip whisper wide width wife - wild will win window wine wing wink winner - winter wire wisdom wise wish witness wolf woman - wonder wood wool word work world worry worth - wrap wreck wrestle wrist write wrong yard year - yellow you young youth zebra zero zone zoo`.split(/\s+/),Lt=[{id:`bip39`,label:`BIP39 (English)`,counts:[12,15,18,21,24]},{id:`electrum`,label:`Electrum`,counts:[12]},{id:`aezeed`,label:`Aezeed (LND)`,counts:[24]},{id:`slip39`,label:`SLIP-39 share (Shamir)`,counts:[20,33]},{id:`monero`,label:`Monero`,counts:[25,13,16]},{id:`other`,label:`Other`,counts:[]}],Rt=[12,13,15,16,18,20,21,24,25,33],zt=e=>e===`bip39`||e===`electrum`||e===`aezeed`,Bt=new Map(It.map((e,t)=>[e,t])),Vt=e=>e.normalize(`NFKD`).trim().toLowerCase(),Ht=e=>Bt.has(Vt(e)),Ut=/[\u200B-\u200D\u2060\uFEFF]/g,Wt=/^[^\p{L}\p{M}\p{N}]+|[^\p{L}\p{M}\p{N}]+$/gu,Gt=e=>{let t=e.replace(Ut,` `).replace(/(?1){let e=[...n].sort((e,t)=>e.n-t.n);if(e.every((t,n)=>t.n===e[0].n+n)&&e[0].n>=1)return{words:e.map(e=>e.word),firstNumber:e[0].n,reordered:e.some((e,t)=>e!==n[t])}}return{words:r,reordered:!1}},Kt=e=>Gt(e).words,qt=e=>{let t=Vt(e);if(t.length<4||Bt.has(t))return t;let n=It.filter(e=>e.startsWith(t));return n.length===1?n[0]:t},Jt=(e,t)=>{let n=Array.from({length:t.length+1},(e,t)=>t);for(let r=1;r<=e.length;r++){let i=n[0];n[0]=r;for(let a=1;a<=t.length;a++){let o=n[a];n[a]=Math.min(n[a]+1,n[a-1]+1,i+(e[r-1]===t[a-1]?0:1)),i=o}}return n[t.length]},Yt=(e,t=3)=>{let n=Vt(e);if(!n||n.length>10)return[];let r=It.filter(e=>e.startsWith(n.slice(0,4)));return r.length>0&&r.length<=t?r:It.map(e=>[e,Jt(n,e)]).filter(([,e])=>e<=2).sort((e,t)=>e[1]-t[1]).slice(0,t).map(([e])=>e)},Xt=async e=>{let t=e.length*11,n=t/33,r=t-n,i=e.map(e=>e.toString(2).padStart(11,`0`)).join(``),a=new Uint8Array(r/8);for(let e=0;ee.toString(2).padStart(8,`0`)).join(``);return i.slice(r)===s.slice(0,n)},Zt=[[`01`,`standard`],[`100`,`segwit`],[`101`,`2fa`],[`102`,`2fa-segwit`]],Qt=async e=>{let t=e.map(e=>Vt(e).replace(/[̀-ͯ]/g,``)).join(` `),n=Be(await Ge(W(`Seed version`),W(t)));return Zt.find(([e])=>n.startsWith(e))?.[1]??null},$t=async(e,t)=>{let n=t.map(Vt),r=n.filter(Boolean).length,i=zt(e)?n.flatMap((e,t)=>e&&!Bt.has(e)?[t]:[]):[];if(r===0)return{status:`incomplete`,message:`No words entered yet.`,unknownWords:i};if(r0)return{status:`invalid`,message:`Not in the English BIP39 wordlist: ${i.map(e=>`#${e+1}`).join(`, `)}. For other languages or old Electrum seeds, choose Other.`,unknownWords:i};if(!Ue()&&(e===`bip39`||e===`electrum`))return{status:`unchecked`,message:`Checksum check needs a secure (https) context.`,unknownWords:i};switch(e){case`bip39`:{if(![12,15,18,21,24].includes(n.length))return{status:`invalid`,message:`BIP39 phrases have 12, 15, 18, 21 or 24 words (this has ${n.length}).`,unknownWords:i};if(await Xt(n.map(e=>Bt.get(e))))return{status:`valid`,message:`Valid BIP39 checksum (${n.length} words).`,unknownWords:i};let e=n.length===12?await Qt(n):null;return{status:`invalid`,message:e?`Not a BIP39 phrase, but these words are a valid Electrum seed (${e}). Choose the Electrum scheme.`:`Checksum mismatch. Check the spelling and order of every word.`,unknownWords:i}}case`electrum`:{let e=await Qt(n);return e?{status:`valid`,message:`Valid Electrum seed (${e}).`,unknownWords:i}:{status:`invalid`,message:`Not a valid Electrum 2.0+ seed. Check the words, or pick another scheme.`,unknownWords:i}}case`monero`:if(n.length!==25&&n.length!==13)break;return tn(n)?{status:`valid`,message:`Monero checksum word OK (${n.length} words).`,unknownWords:i}:{status:`invalid`,message:`The last word does not match the Monero checksum. Check the spelling and order of every word.`,unknownWords:i};case`aezeed`:return{status:`unchecked`,message:`All words are in the wordlist. The aezeed checksum is not checked here.`,unknownWords:i}}return{status:`unchecked`,message:`${n.length} words. Checksums for this scheme are not checked here.`,unknownWords:i}},en=e=>{let t=4294967295;for(let n of e){let e=(t^n)&255;for(let t=0;t<8;t++)e=e&1?e>>>1^3988292384:e>>>1;t=t>>>8^e}return(t^4294967295)>>>0},tn=e=>{let t=e.slice(0,-1).map(e=>e.normalize(`NFC`)),n=e[e.length-1].normalize(`NFC`);return[3,4,1].some(e=>{let r=t.map(t=>[...t].slice(0,e).join(``)).join(``);return t[en(W(r))%t.length]===n})},nn=({words:e,scheme:t,unknownWords:n,onChange:r})=>{let{readOnly:i,copy:a,settings:o}=Z(),[s,c]=jt(e),[l,u]=R(null),[d,f]=R(null),[p,m]=R(``),h=B([]),g=zt(t),_=!Mt();z(()=>{if(d===null||!o.autoHideSeconds)return;let e=setTimeout(()=>f(null),o.autoHideSeconds*1e3);return()=>clearTimeout(e)},[d,e,o.autoHideSeconds]);let v=(t,n)=>{let i=[...e];i[t]=n,r(i)},y=(t,n)=>{let i=Math.min(48,Math.max(e.length,t+n.length)),a=Array.from({length:i},(t,n)=>e[n]??``);n.slice(0,i-t).forEach((e,n)=>a[t+n]=e),r(a),h.current[Math.min(t+n.length,i-1)]?.focus()},b=(e,t)=>{let n=Gt(t.clipboardData?.getData(`text`)??``);if(n.words.length<2)return;t.preventDefault();let r=n.firstNumber!==void 0&&n.firstNumber-1<48?n.firstNumber-1:e;y(r,n.words),m(n.reordered?`Placed the pasted words by their numbers. Check the order.`:``)},ee=(e,t)=>{let n=t.currentTarget,r=n.value;t.isComposing?v(e,r):x(e,n)},x=(e,t)=>{let n=t.value;if(!/\s/.test(n)){let r=n.toLowerCase();if(r!==n){let[e,n]=[t.selectionStart,t.selectionEnd];t.value=r,e!==null&&n!==null&&t.setSelectionRange(e,n)}v(e,r);return}let r=Kt(n);r.length>1?y(e,r):(v(e,r[0]??``),r.length===1&&h.current[e+1]?.focus())},S=(t,n)=>{n.isComposing||n.keyCode===229||(n.key===` `||n.key===`Enter`?(n.preventDefault(),h.current[t+1]?.focus()):n.key===`Backspace`&&!e[t]&&t>0?(n.preventDefault(),h.current[t-1]?.focus()):_&&(n.key.length===1||n.key===`Backspace`)&&!n.ctrlKey&&!n.metaKey&&f(t))},C=()=>{u(null),f(null)},te=(e,t)=>{v(e,t),h.current[e]?.focus()},w=g?n.map(t=>[t,qt(e[t]??``)]).filter(([t,n])=>n!==e[t]&&Ht(n)):[],T=w.length>0&&w.length===n.length,ne=()=>{let t=[...e];for(let[e,n]of w)t[e]=n;r(t)},E=e.filter(Boolean),D=e=>s||_&&d===e,re=l!==null&&n.includes(l)&&e[l]&&D(l)?Yt(e[l]):[];return H(`div`,{class:`word-grid-wrap`,children:[H(`div`,{class:`word-toolbar`,children:[H(`button`,{type:`button`,class:`button small`,onClick:()=>c(!s),children:[H(U,{name:s?`eyeOff`:`eye`}),` `,s?`Hide words`:`Reveal words`]}),H(`button`,{type:`button`,class:`button small`,disabled:E.length===0,onClick:()=>a(E.join(` `),E.length===e.length?`Seed phrase`:`Seed phrase (only ${E.length} of ${e.length} words)`),children:[H(U,{name:`copy`}),` Copy phrase`]}),H(`span`,{class:`muted small helper`,children:[`Tip: paste a whole phrase into word 1.`,Mt()?` Phrases in other scripts (Japanese, Chinese…) can only be pasted on phones.`:``]})]}),H(`ol`,{class:`word-grid`,"aria-label":`Seed words`,children:e.map((t,r)=>{let a=D(r),o=n.includes(r)&&l!==r;return H(`li`,{class:`word ${o?`word-invalid`:``}`,children:[H(`span`,{class:`word-index`,"aria-hidden":`true`,children:r+1}),H(`input`,{ref:e=>{e&&!h.current[r]&&e.type===`text`&&(e.type=`password`,e.type=`text`),h.current[r]=e},class:`input mono`,type:a?`text`:`password`,value:t,"aria-label":`Word ${r+1}`,"aria-invalid":o,list:g&&a?`bip39-words`:void 0,enterkeyhint:r===e.length-1?`done`:`next`,readOnly:i,onInput:e=>ee(r,e),onPaste:e=>b(r,e),onKeyDown:e=>S(r,e),onFocus:()=>u(r),onBlur:C,oncompositionend:e=>x(r,e.currentTarget),...Nt})]},r)})}),re.length>0&&H(`p`,{class:`hint`,role:`status`,children:[`Not in the wordlist. Did you mean:`,` `,re.map(e=>H(`button`,{type:`button`,class:`link-button`,onMouseDown:e=>e.preventDefault(),onClick:()=>te(l,e),children:e},e)),`?`]}),T&&!i&&H(`p`,{class:`hint`,children:[H(`button`,{type:`button`,class:`button small`,onClick:ne,children:`Expand abbreviated words`}),` `,H(`span`,{class:`muted small`,children:`Only for English BIP39 phrases.`})]}),p&&H(`p`,{class:`hint`,role:`status`,children:p})]})},rn=Object.fromEntries(Object.entries(J).map(([e,t])=>[e,t.label])),an={mnemonic:`Seed phrases`,privateKey:`Wallet keys`,sshKey:`SSH keys`,pgpKey:`PGP keys`,apiKey:`API keys and tokens`,genericKey:`Other keys`,recoveryCodes:`Recovery codes`,other:`Other secrets`},on={mnemonic:`seed`,privateKey:`wallet`,sshKey:`terminal`,pgpKey:`mail`,apiKey:`code`,genericKey:`key`,recoveryCodes:`list`,other:`lock`},sn=[[`none`,`No grouping`],[`kind`,`Type`],[`chain`,`Chain or service`],[`wallet`,`Wallet or account`],[`tag`,`First tag`]],cn=e=>`Untitled ${/^[A-Z][A-Z]/.test(e)?e:e.toLowerCase()}`,ln=e=>{let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleDateString(void 0,{year:`numeric`,month:`long`,day:`numeric`})},un=new Map([...`123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`].map((e,t)=>[e,BigInt(t)])),dn=e=>{let t=0n;for(let n of e){let e=un.get(n);if(e===void 0)return null;t=t*58n+e}let n=[];for(;t>0n;)n.unshift(Number(t%256n)),t/=256n;let r=0;for(;r{let t=dn(e);if(!t||t.length<5)return null;let n=t.slice(0,-4);return Ke((await We(await We(n))).slice(0,4),t.slice(-4))?n:null},pn=`qpzry9x8gf2tvdw0s3jn54khce6mua7l`,mn=1,hn=734539939,gn=e=>{let t=[996825010,642813549,513874426,1027748829,705979059],n=1;for(let r of e){let e=n>>>25;n=(n&33554431)<<5^r;for(let r=0;r<5;r++)e>>>r&1&&(n^=t[r])}return n>>>0},_n=e=>[...[...e].map(e=>e.charCodeAt(0)>>5),0,...[...e].map(e=>e.charCodeAt(0)&31)],vn=/^(nsec|npub|bc|tb|ltc|age|age-secret-key-)$|_x?[sv]k$|xprv|xpub|^addr|^stake/,yn=e=>{if(e!==e.toLowerCase()&&e!==e.toUpperCase())return null;let t=e.toLowerCase(),n=t.lastIndexOf(`1`);if(n<1||n+7>t.length)return null;let r=t.slice(0,n),i=[];for(let e of t.slice(n+1)){let t=pn.indexOf(e);if(t===-1)return null;i.push(t)}let a=gn([..._n(r),...i]),o=a===mn?`bech32`:a===hn?`bech32m`:null;return o?{hrp:r,variant:o,words:i.slice(0,-6)}:null},bn=e=>{let t=0,n=0,r=[];for(let i of e)for(t=t<<5|i,n+=5;n>=8;)n-=8,r.push(t>>n&255);return n>=5||t&(1<Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``),wn=e=>{let t;try{t=JSON.parse(e)}catch{return null}if(Array.isArray(t)&&t.length===0)return{level:`info`,label:`Empty list`};if(Array.isArray(t)&&t.every(e=>Number.isInteger(e)&&e>=0&&e<=255))return t.length===64?{level:`ok`,label:`Byte array, 64 bytes`,detail:`Solana CLI keypair file format.`}:{level:`info`,label:`Byte array, ${t.length} bytes`};if(t&&typeof t==`object`){let e=t;if(e.crypto&&Number(e.version)===4&&typeof e.pubkey==`string`)return{level:`ok`,label:`Encrypted keystore (EIP-2335, Ethereum validator)`,detail:`Store its password in the keystore password field.`};if((e.crypto||e.Crypto)&&Number(e.version)===3)return{level:`ok`,label:`Encrypted keystore (Web3 Secret Storage v3)`,detail:`Store its password in the keystore password field.`};if(e.type===`service_account`&&typeof e.private_key==`string`)return{level:`ok`,label:`Google Cloud service account key`,detail:`JSON key file with a private key.`};let n=Array.isArray(e.keys)?e.keys.filter(e=>e&&typeof e==`object`):[e],r=n.find(e=>`d`in e||`k`in e)??n[0];return r&&typeof r.kty==`string`?`d`in r||`k`in r?{level:`ok`,label:`JSON Web Key (${r.kty}, private)`}:{level:`warn`,label:`JSON Web Key (${r.kty}, public)`,detail:Q}:{level:`info`,label:`JSON document`}}return null},Tn={"ssh-ed25519":`Ed25519`,"ssh-rsa":`RSA`,"ssh-dss":`DSA`,"ecdsa-sha2-nistp256":`ECDSA P-256`,"ecdsa-sha2-nistp384":`ECDSA P-384`,"ecdsa-sha2-nistp521":`ECDSA P-521`,"sk-ssh-ed25519@openssh.com":`Ed25519 security key`,"sk-ecdsa-sha2-nistp256@openssh.com":`ECDSA security key`},En=e=>{let t;try{t=G(e.replace(/\s+/g,``))}catch{return null}if(ze(t.slice(0,15))!==`openssh-key-v1\0`)return null;let n=15,r=new DataView(t.buffer,t.byteOffset,t.byteLength),i=()=>{if(n+4>t.length)throw Error(`truncated`);let e=r.getUint32(n);if(n+=4,n+e>t.length)throw Error(`truncated`);let i=t.slice(n,n+e);return n+=e,i};try{let e=ze(i());i(),i(),n+=4;let t=i(),r=i(),a=new DataView(t.buffer,t.byteOffset).getUint32(0),o=ze(t.slice(4,4+a)),s=e!==`none`;if(!s){let e=new DataView(r.buffer,r.byteOffset,r.byteLength);if(r.length<8||e.getUint32(0)!==e.getUint32(4))return null}return{keyType:o,encrypted:s}}catch{return null}},Dn=e=>{let t=11994318;for(let n of e){t^=n<<16;for(let e=0;e<8;e++)t<<=1,t&16777216&&(t^=25578747)}return t&16777215},On=e=>{let t=e.split(/\r?\n/).map(e=>e.trim()),n=t.indexOf(``),r=t.slice(n===-1?1:n+1).filter(e=>e&&!e.startsWith(`-----`)),i=r.findIndex(e=>/^=[A-Za-z0-9+/]{4}$/.test(e));if(i===-1)return null;try{let e=G(r.slice(0,i).join(``)),t=G(r[i].slice(1));return Dn(e)===(t[0]<<16|t[1]<<8|t[2])}catch{return!1}},kn={"PUBLIC KEY":`PEM public key`,"RSA PUBLIC KEY":`PEM RSA public key`,CERTIFICATE:`Certificate`,"PGP PUBLIC KEY BLOCK":`PGP public key block`},An={"PGP MESSAGE":`PGP message`,"PGP SIGNATURE":`PGP signature`,"PGP SIGNED MESSAGE":`PGP signed message`},jn=e=>{if(e.includes(`:`))return null;let t;try{t=G(e.replace(/\s+/g,``))}catch{return!1}if(t.length<2||t[0]!==48)return!1;let n=t[1],r=2;if(n&128){let e=n&127;if(e<1||e>4||t.length<2+e)return!1;n=0;for(let r=0;r{let r=/Proc-Type:\s*4,ENCRYPTED/i.test(t);if(An[e])return{level:`warn`,label:An[e],detail:`This is not a key.`};if(kn[e])return{level:`warn`,label:kn[e],detail:Q};if(/PRIVATE KEY$/.test(e)&&e!==`OPENSSH PRIVATE KEY`&&jn(t)===!1)return{level:`error`,label:`Private key block is damaged or incomplete`,detail:`A line may be missing or changed.`};switch(e){case`OPENSSH PRIVATE KEY`:{let e=En(t);return e?{level:`ok`,label:`OpenSSH private key (${Tn[e.keyType]??e.keyType})`,detail:e.encrypted?`Protected by a passphrase.`:`Not passphrase-protected.`}:{level:`error`,label:`OpenSSH private key, but it could not be read`,detail:`Check that it was copied completely.`}}case`PGP PRIVATE KEY BLOCK`:{let e=On(n);return e===!1?{level:`error`,label:`PGP private key, but the checksum fails`,detail:`Check for a typo or missing line.`}:{level:`ok`,label:`PGP private key block`,detail:e?`Checksum OK.`:void 0}}case`RSA PRIVATE KEY`:return{level:`ok`,label:`PEM RSA private key (PKCS#1)`,detail:r?`Protected by a passphrase.`:void 0};case`EC PRIVATE KEY`:return{level:`ok`,label:`PEM EC private key (SEC1)`,detail:r?`Protected by a passphrase.`:void 0};case`DSA PRIVATE KEY`:return{level:`ok`,label:`PEM DSA private key`,detail:r?`Protected by a passphrase.`:void 0};case`PRIVATE KEY`:return{level:`ok`,label:`PEM private key (PKCS#8)`};case`ENCRYPTED PRIVATE KEY`:return{level:`ok`,label:`PEM private key (PKCS#8)`,detail:`Protected by a passphrase.`};default:return{level:`info`,label:`PEM block (${e.toLowerCase()})`}}},Nn=e=>/PRIVATE KEY/.test(e),Pn=e=>{let t=[...e.matchAll(/-----BEGIN ([A-Z0-9 ]+)-----([\s\S]*?)-----END \1-----/g)],n=(e.match(/-----BEGIN [A-Z0-9 ]+-----/g)??[]).length,r={level:`error`,label:`Key block is incomplete`,detail:`The matching -----END ...----- line is missing.`},i=t.find(e=>Nn(e[1]));if(i)return Mn(i[1],i[2],i[0]);let a=/-----BEGIN (PGP MESSAGE|PGP SIGNATURE|PGP SIGNED MESSAGE)-----/.exec(e);if(a)return{level:`warn`,label:An[a[1]],detail:`This is not a key.`};if(n>t.length)return r;if(!t.length)return null;let o=t.map(e=>Mn(e[1],e[2],e[0]));return o.find(e=>e.level===`warn`)??o[0]},Fn=[{pattern:/^gh[pousr]_[A-Za-z0-9]{36,}$/,label:`GitHub token`},{pattern:/^github_pat_\w{50,}$/,label:`GitHub fine-grained token`},{pattern:/^glpat-[\w-]{20,}$/,label:`GitLab access token`},{pattern:/^npm_[A-Za-z0-9]{36}$/,label:`npm access token`},{pattern:/^(sk|rk)_(live|test)_[A-Za-z0-9]{16,}$/,label:`Stripe secret key`},{pattern:/^pk_(live|test)_[A-Za-z0-9]{16,}$/,label:`Stripe publishable key`,level:`warn`,detail:Q},{pattern:/^xox[abposr]-[A-Za-z0-9-]{10,}$/,label:`Slack token`},{pattern:/^AIza[\w-]{35}$/,label:`Google API key`},{pattern:/^(AKIA|ASIA)[0-9A-Z]{16}$/,label:`AWS access key ID`,level:`info`,detail:`The 40-character secret access key is a separate value; store it as well.`},{pattern:/^SG\.[\w-]{22}\.[\w-]{43}$/,label:`SendGrid API key`},{pattern:/^dop_v1_[a-f0-9]{64}$/,label:`DigitalOcean token`},{pattern:/^sk-[\w-]{20,}$/,label:`API secret key (sk-…)`},{pattern:/^eyJ[\w-]+\.eyJ[\w-]+\.[\w-]*$/,label:`JSON Web Token`,level:`info`,detail:`Tokens like this usually expire.`}],In=async e=>{let t=e.trim();if(!t)return null;if(/^\[[\w .-]+\]\s*$/m.test(t.split(` -`)[0])&&/^\s*[\w.-]+\s*=/m.test(t))return/aws_secret_access_key\s*=/i.test(t)?{level:`ok`,label:`AWS credentials file`,detail:`Contains a secret access key.`}:{level:`info`,label:`Settings file (INI)`};if(t.startsWith(`{`)||t.startsWith(`[`))return wn(t)??{level:`warn`,label:`Looks like JSON, but it does not parse.`};let n=/^AGE-SECRET-KEY-1[0-9A-Z]+$/m.exec(t);if(n&&t.includes(` -`))return In(n[0]);if(/^---- BEGIN SSH2 PUBLIC KEY ----/m.test(t))return{level:`warn`,label:`SSH public key (SSH2 format)`,detail:Q};let r=Pn(t);if(r)return r;let i=/^PuTTY-User-Key-File-\d+:\s*(\S+)/.exec(t);if(i){let e=/^Private-Lines:\s*(\d+)\s*$/m.exec(t);if(e&&(t.slice(e.index+e[0].length).split(` -`).map(e=>e.trim()).filter(e=>e&&!/^Private-MAC:/.test(e)).filter(e=>/^[A-Za-z0-9+/=]+$/.test(e)).lengthe.pattern.test(t));if(o)return{level:o.level??`ok`,label:o.label,detail:o.detail};let s=Kt(t);if(s.length>=12&&s.length<=48&&s.every(Ht))return{level:`warn`,label:`Looks like a ${s.length}-word seed phrase`,detail:`Use a "Seed phrase" entry to get word-by-word checks.`};if(/^(0x)?[0-9a-fA-F]+$/i.test(t)&&t.replace(/^0x/i,``).length%2==0){let e=Ve(t.replace(/^0X/,`0x`)),n=/^0x/i.test(t);return e.length===32?{level:`ok`,label:`Hex, 32 bytes${n?` (0x-prefixed)`:``}`,detail:`Raw 256-bit private key (Ethereum/EVM, Bitcoin, Cosmos and others).`}:e.length===20?{level:`warn`,label:`Hex, 20 bytes`,detail:Q+` (EVM address length)`}:e.length===33||e.length===65?{level:`warn`,label:`Hex, ${e.length} bytes`,detail:Q+` (public key length)`}:{level:`info`,label:`Hex, ${e.length} bytes`}}let c=yn(t);if(c){let e=c.variant===`bech32`?bn(c.words):null;switch(c.hrp){case`age-secret-key-`:return e?.length===32?{level:`ok`,label:`age secret key`,detail:`Checksum OK.`}:{level:`error`,label:`age secret key with unexpected length`,detail:`Check that it was copied completely.`};case`age`:return{level:`warn`,label:`age recipient (public key)`,detail:Q};case`nsec`:return e?.length===32?{level:`ok`,label:`Nostr private key (nsec)`,detail:`Checksum OK.`}:{level:`error`,label:`nsec with unexpected length`};case`npub`:return{level:`warn`,label:`Nostr public key (npub)`,detail:Q};case`bc`:case`tb`:case`ltc`:return{level:`warn`,label:`Address (bech32)`,detail:Q};default:return/_x?sk$/.test(c.hrp)||c.hrp.includes(`xprv`)?{level:`ok`,label:`Bech32 secret key (${c.hrp})`,detail:`Checksum OK.`}:/_x?vk$/.test(c.hrp)||c.hrp.includes(`xpub`)||c.hrp.startsWith(`addr`)||c.hrp.startsWith(`stake`)?{level:`warn`,label:`Bech32 (${c.hrp})`,detail:Q}:{level:`info`,label:`Bech32 data (${c.hrp})`,detail:`Checksum OK.`}}}{let e=t.toLowerCase(),n=/^([a-z0-9_-]+)1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]{6,}$/.exec(e);if(n&&(t===e||t===t.toUpperCase())&&vn.test(n[1]))return{level:`error`,label:`Bech32 checksum fails`,detail:`Check for a typo.`}}if(/^[A-Za-z0-9+/]+={0,2}$/.test(t)&&t.length%4==0&&/[+/=]/.test(t))try{let e=G(t);return e.length===32?{level:`ok`,label:`Base64, 32 bytes`,detail:`The format of WireGuard keys and many other 256-bit keys.`}:{level:`info`,label:`Base64, ${e.length} bytes`}}catch{}if(t.length<=200&&/^[1-9A-HJ-NP-Za-km-z]+$/.test(t)){if(Ue()){let e=await fn(t);if(e){if(e.length===78){let t=xn[Cn(e.slice(0,4))];return t?t.private?{level:`ok`,label:`Extended private key (${t.name})`,detail:`${t.note}. Checksum OK.`}:{level:`warn`,label:`Extended public key (${t.name})`,detail:Q}:{level:`info`,label:`Extended key (unknown version)`,detail:`Checksum OK.`}}let t=Sn[e[0]];return t&&(e.length===33||e.length===34&&e[33]===1)?{level:`ok`,label:`WIF private key (${t}, ${e.length===34?`compressed`:`uncompressed`})`,detail:`Checksum OK.`}:e.length===21?{level:`warn`,label:`Address (Base58Check)`,detail:Q}:{level:`info`,label:`Base58Check, ${e.length} bytes`,detail:`Checksum OK.`}}let n=dn(t);if(n&&(n.length===37||n.length===38)&&Sn[n[0]])return{level:`error`,label:`Looks like WIF, but the checksum fails`,detail:`Check for a typo.`};if(/^[xyztuvYZUV](prv|pub)/.test(t)){if(t.length===111)return{level:`error`,label:`Looks like an extended key, but the checksum fails`,detail:`Check for a typo.`};if(t.length===110||t.length===112)return{level:`error`,label:`Looks like an extended key, but a character may be missing or extra`,detail:`Extended keys are 111 characters.`}}}let e=dn(t);if(e?.length===64)return{level:`ok`,label:`Base58, 64 bytes`,detail:`Solana-style keypair (Phantom/Solflare export).`};if(e?.length===32)return{level:`info`,label:`Base58, 32 bytes`,detail:`Could be an ed25519 secret seed, or a Solana address.`};if(e)return{level:`info`,label:`Base58, ${e.length} bytes`}}return{level:`info`,label:`Unrecognized format`,detail:`Stored as typed.`}},Ln=async e=>{let t=e.trim();if(!t)return null;if(/-----BEGIN [A-Z0-9 ]*PRIVATE KEY[A-Z0-9 ]*-----/.test(t))return`a private key block`;let n=t.split(/[\s,;()[\]]+/).map(e=>e.split(`/`)[0]).filter(e=>e.length>=40);for(let e of[t,...n]){let t=await In(e);if(t?.level===`ok`&&!/^(Hex|Base64)/.test(t.label))return t.label}return null},Rn=`Bitcoin.Ethereum.Solana.Cardano.Monero.Litecoin.Dogecoin.Polkadot.Cosmos.Avalanche.Polygon.BNB Chain.Arbitrum.Base.Optimism.Tron.XRP Ledger.Tezos.Algorand.Stellar.Near.Sui.Aptos.Lightning (LND).Nostr.Multi-chain`.split(`.`),zn=[`Ledger`,`Trezor`,`Coldcard`,`BitBox02`,`Keystone`,`Blockstream Jade`,`Foundation Passport`,`Sparrow`,`Electrum`,`Nunchuk`,`BlueWallet`,`Phoenix`,`MetaMask`,`Rabby`,`Rainbow`,`Phantom`,`Solflare`,`Exodus`,`Trust Wallet`,`Coinbase Wallet`,`Cake Wallet`,`Feather`,`Monero GUI`],Bn=[`GitHub`,`GitLab`,`Bitbucket`,`AWS`,`Google Cloud`,`Azure`,`Cloudflare`,`DigitalOcean`,`Vercel`,`Stripe`,`Slack`,`npm`,`Docker Hub`,`Apple ID`,`Google account`,`Microsoft account`,`Proton`,`Standard Notes`,`Coinbase`,`Kraken`,`Binance`,`Gemini`,`Bitstamp`],Vn=[[`m/44'/0'/0'`,`BTC legacy (BIP44)`],[`m/49'/0'/0'`,`BTC nested SegWit (BIP49)`],[`m/84'/0'/0'`,`BTC native SegWit (BIP84)`],[`m/86'/0'/0'`,`BTC Taproot (BIP86)`],[`m/48'/0'/0'/2'`,`BTC multisig (BIP48)`],[`m/44'/60'/0'/0/0`,`Ethereum / EVM`],[`m/44'/501'/0'/0'`,`Solana`],[`m/1852'/1815'/0'`,`Cardano`],[`m/44'/118'/0'/0/0`,`Cosmos`]],Hn=()=>H(C,{children:[H(`datalist`,{id:`chains`,children:Rn.map(e=>H(`option`,{value:e}))}),H(`datalist`,{id:`wallets`,children:zn.map(e=>H(`option`,{value:e}))}),H(`datalist`,{id:`services`,children:Bn.map(e=>H(`option`,{value:e}))}),H(`datalist`,{id:`paths`,children:Vn.map(([e,t])=>H(`option`,{value:e,label:t}))})]}),Un=(e,t,n=`${t}s`)=>`${e} ${e===1?t:n}`,$=({label:e,hint:t,children:n,wide:r,safety:i})=>H(`div`,{class:`field ${r?`field-wide`:``}`,children:[H(`label`,{class:`field-control`,children:[H(`span`,{class:`field-label`,children:e}),n]}),t&&H(`span`,{class:`hint ${i?`hint-safety`:``}`,children:t})]}),Wn=({id:e,title:t,icon:n,summary:r,defaultOpen:i,action:a,children:o})=>{let[s]=R(i),[c,l]=Ot(e,s),u=`section-${e.replace(/[^a-z0-9]/gi,`-`)}`;return H(`section`,{class:`section ${c?`open`:`closed`}`,children:[H(`header`,{class:`section-header`,children:[H(`h3`,{class:`section-heading`,children:H(`button`,{type:`button`,class:`section-toggle`,"aria-expanded":c,"aria-controls":u,onClick:()=>l(!c),children:[H(U,{name:`chevron`,size:14,class:`chevron`}),n&&H(U,{name:n}),H(`span`,{children:t}),!c&&r&&H(`span`,{class:`section-summary`,children:r})]})}),a&&H(`button`,{type:`button`,class:`button small`,onClick:()=>{a.onClick(),l(!0)},children:[H(U,{name:`plus`}),` `,a.label]})]}),c&&H(`div`,{class:`section-body`,id:u,children:o})]})},Gn={valid:`ok`,invalid:`error`,incomplete:`info`,unchecked:`info`},Kn=({entry:e,update:t,showLabel:n,focusLabel:r})=>{let{readOnly:i}=Z(),a=B(null);z(()=>{r&&a.current?.focus()},[]);let o=J[e.kind],s=Xe(e.kind),c=Tt(e),l=[e.description&&`description`,e.createdOn&&`created ${e.createdOn}`,e.expiresOn&&o.expires&&`expires ${e.expiresOn}`].filter(Boolean).join(` · `);return H(Wn,{id:`${e.id}:details`,title:`Details`,summary:l||`empty`,defaultOpen:!e.label,children:[n&&H($,{label:`Label`,wide:!0,children:H(`input`,{ref:a,class:`input`,value:e.label,placeholder:cn(rn[e.kind]),readOnly:i,onInput:e=>t({label:e.currentTarget.value})})}),H($,{label:`Description`,wide:!0,children:H(`textarea`,{class:`input`,rows:2,value:e.description,placeholder:`What is this wallet or key for?`,readOnly:i,onInput:e=>t({description:e.currentTarget.value}),...Nt,"data-secret":void 0})}),Xn(e,e.description)&&H(`p`,{class:`status status-error`,role:`status`,children:[H(U,{name:`alert`}),` This text repeats the entry's secret, and it is not hidden.`]}),H(`div`,{class:`row`,children:[s?H(C,{children:[H($,{label:o.serviceLabel,children:H(`input`,{class:`input`,list:`chains`,value:e.chain,readOnly:i,onInput:e=>t({chain:e.currentTarget.value})})}),H($,{label:o.accountLabel,children:H(`input`,{class:`input`,list:`wallets`,value:e.wallet,readOnly:i,onInput:e=>t({wallet:e.currentTarget.value})})})]}):H(C,{children:[H($,{label:o.serviceLabel,children:H(`input`,{class:`input`,list:`services`,value:e.service,readOnly:i,onInput:e=>t({service:e.currentTarget.value})})}),H($,{label:o.accountLabel,children:H(`input`,{class:`input`,value:e.account,readOnly:i,onInput:e=>t({account:e.currentTarget.value}),...Pt})})]}),H($,{label:`Date created`,children:H(`input`,{class:`input`,type:`date`,value:e.createdOn,readOnly:i,onInput:e=>t({createdOn:e.currentTarget.value})})}),o.expires&&H($,{label:`Expires on`,hint:c===null?`Optional. You are warned 30 days ahead.`:void 0,children:H(`input`,{class:`input`,type:`date`,value:e.expiresOn,readOnly:i,onInput:e=>t({expiresOn:e.currentTarget.value})})})]}),c!==null&&c<=30&&H(`p`,{class:`status ${c<0?`status-error`:`status-warn`}`,children:[H(U,{name:`clock`}),` `,c<0?`Expired on ${e.expiresOn}.`:c===0?`Expires today.`:`Expires in ${c} day${c===1?``:`s`}.`]}),H($,{label:`Tags`,hint:`Comma separated.`,wide:!0,children:H(ur,{tags:e.tags,onChange:e=>t({tags:e})})})]})},qn=({entry:e,update:t})=>{let{readOnly:n,confirm:r}=Z(),i=At(()=>$t(e.scheme,e.words),[e.scheme,e.words.join(` `)]),a=Lt.find(t=>t.id===e.scheme),o=[...new Set([...a.counts,...Rt])].sort((e,t)=>e-t),s=e.words.filter(Boolean).length,[c,l]=R(!1),u=async n=>{if(!Number.isInteger(n)||n<1||n>48||n===e.words.length)return!1;let i=e.words.slice(n).filter(Boolean).length;return i>0&&!await r({title:`Remove words?`,message:`Shrinking to ${n} words removes ${i} word${i===1?``:`s`} you entered.`,confirmLabel:`Remove`,danger:!0})?!1:(t({words:Array.from({length:n},(t,n)=>e.words[n]??``)}),!0)},d=n=>{let r=Lt.find(e=>e.id===n);s===0&&r.counts.length&&!r.counts.includes(e.words.length)?t({scheme:n,words:Array(r.counts[0]).fill(``)}):t({scheme:n})},f=`${a.label} · ${s===e.words.length?Un(s,`word`):`${s} of ${e.words.length} words`}${e.passphrase?` + passphrase`:``}`;return H(Wn,{id:`${e.id}:seed`,title:`Seed phrase`,icon:`seed`,summary:f,defaultOpen:!0,children:[H(`div`,{class:`row`,children:[H($,{label:`Scheme`,children:H(`select`,{class:`input`,value:e.scheme,disabled:n,onChange:e=>d(e.currentTarget.value),children:Lt.map(e=>H(`option`,{value:e.id,children:e.label}))})}),H($,{label:`Words`,children:H(`select`,{class:`input`,value:c||!o.includes(e.words.length)?`custom`:String(e.words.length),disabled:n,onChange:async t=>{let n=t.currentTarget,r=n.value;r===`custom`?l(!0):(l(!1),await u(Number(r))||(n.value=o.includes(e.words.length)?String(e.words.length):`custom`))},children:[o.map(e=>H(`option`,{value:String(e),children:[e,a.counts.includes(e)?``:` (non-standard)`]})),H(`option`,{value:`custom`,children:`Custom…`})]})}),(c||!o.includes(e.words.length))&&H($,{label:`Custom count`,children:H(`input`,{class:`input`,type:`number`,min:1,max:48,value:e.words.length,readOnly:n,onChange:e=>u(Number(e.currentTarget.value))})})]}),H(nn,{words:e.words,scheme:e.scheme,unknownWords:i?.unknownWords??[],onChange:e=>t({words:e})}),i&&H(`p`,{class:`status status-${Gn[i.status]}`,role:`status`,children:[H(U,{name:i.status===`valid`?`check`:i.status===`invalid`?`alert`:`shield`}),` `,i.message]}),H(Zn,{entry:e,update:t})]})},Jn=e=>setTimeout(()=>document.querySelector(`[data-row="${e}"] input`)?.focus()),Yn=e=>e.passphrase.length>=4&&e.passphraseHint.toLowerCase().includes(e.passphrase.toLowerCase()),Xn=(e,t)=>{let n=t.toLowerCase();if(!n)return!1;if(e.secret.trim().length>=12&&n.includes(e.secret.trim().toLowerCase()))return!0;let r=e.words.filter(Boolean).map(e=>e.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g,`\\$&`));for(let e=0;e+4<=r.length;e++)if(RegExp(`\\b${r.slice(e,e+4).join(`\\s+`)}\\b`).test(n))return!0;return!1},Zn=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=J[e.kind];return r.passphraseLabel?H(`div`,{class:`row`,children:[H($,{label:r.passphraseLabel,hint:r.passphraseHint,safety:!0,children:H(Ft,{label:r.passphraseLabel,value:e.passphrase,onInput:e=>t({passphrase:e}),placeholder:`None`})}),H($,{label:`Passphrase hint`,hint:`Not hidden. Never write the passphrase itself here.`,safety:!0,children:H(`input`,{class:`input`,value:e.passphraseHint,readOnly:n,onInput:e=>t({passphraseHint:e.currentTarget.value}),...Pt})}),Yn(e)&&H(`p`,{class:`status status-error field-wide`,role:`status`,children:[H(U,{name:`alert`}),` The hint contains the passphrase. Anyone who opens this note can read it.`]})]}):null},Qn={ok:`ok`,info:`info`,warn:`warn`,error:`error`},$n=({entry:e,update:t})=>{let n=J[e.kind],r=At(()=>In(e.secret),[e.secret]);return H(Wn,{id:`${e.id}:key`,title:n.secretLabel,icon:`key`,summary:e.secret?r?.label??`set`:`empty`,defaultOpen:!0,children:[H($,{label:n.secretLabel,wide:!0,children:H(Ft,{label:n.secretLabel,value:e.secret,onInput:e=>t({secret:e}),placeholder:n.secretPlaceholder,multiline:n.secret===`key`&&(e.kind!==`privateKey`||e.secret.includes(` -`)),onMultilinePaste:e=>t({secret:e}),mono:!0})}),H(`p`,{class:`status ${r?`status-${Qn[r.level]}`:``}`,role:`status`,children:r&&H(C,{children:[H(U,{name:r.level===`ok`?`check`:r.level===`info`?`shield`:`alert`}),` `,r.label,r.detail&&H(`span`,{class:`muted`,children:[` · `,r.detail]})]})}),H(Zn,{entry:e,update:t})]})},er=({entry:e,update:t})=>{let n=e.secret.split(/\n/).filter(e=>e.trim()).length;return H(Wn,{id:`${e.id}:codes`,title:`Recovery codes`,icon:`list`,summary:n?`${n} code${n===1?``:`s`}`:`empty`,defaultOpen:!0,children:H($,{label:`Codes`,hint:`One per line. Delete or mark a code once used.`,wide:!0,children:H(Ft,{label:`Recovery codes`,value:e.secret,onInput:e=>t({secret:e}),placeholder:`One code per line`,multiline:!0,mono:!0})})})},tr=({text:e})=>{let t=At(()=>Ln(e),[e]);return t?H(`p`,{class:`status status-error`,role:`status`,children:[H(U,{name:`alert`}),` This looks like private key material (`,t,`). This field is not hidden: move it to the secret field.`]}):null},nr=(e,t)=>{let n=e.trim();return t&&(n=n.replace(/^\[([0-9a-fA-F]{8})[^\]]*\].*$/,`$1`).replace(/^0x/i,``).replace(/\s+/g,``)),n},rr=e=>e.trim().replace(/[’‘′`]/g,`'`).replace(/^M\//,`m/`),ir=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=J[e.kind].publicKey;if(!r)return null;let i=At(()=>Ln(e.fingerprint),[e.fingerprint]),a=[e.publicInfo&&`public key`,e.fingerprint&&(i?`fingerprint`:e.fingerprint)].filter(Boolean).join(` · `),o=e.kind===`pgpKey`&&e.fingerprint&&!/^([0-9a-fA-F]{40}|[0-9a-fA-F]{64})$/.test(e.fingerprint.replace(/\s/g,``));return H(Wn,{id:`${e.id}:public`,title:`Public info`,icon:`eye`,summary:a||`empty`,defaultOpen:!1,children:[H(`p`,{class:`muted small helper`,children:`Not secret. Lets you match this entry to a server, keyring or recipient.`}),H($,{label:r.label,wide:!0,children:H(`textarea`,{class:`input mono`,rows:e.publicInfo?3:2,value:e.publicInfo,placeholder:r.placeholder,readOnly:n,onInput:e=>t({publicInfo:e.currentTarget.value}),...Pt})}),H(tr,{text:e.publicInfo}),H($,{label:r.fingerprintLabel,wide:!0,children:H(`input`,{class:`input mono`,value:e.fingerprint,placeholder:r.fingerprintPlaceholder,readOnly:n,onInput:e=>t({fingerprint:e.currentTarget.value}),onBlur:n=>{let r=nr(n.currentTarget.value,!1);r!==e.fingerprint&&t({fingerprint:r})},...Pt})}),H(tr,{text:e.fingerprint}),o&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` PGP fingerprints are 40 hex characters (64 for newer v6 keys).`]})]})},ar=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=!!(e.derivationPath||e.fingerprint||e.publicInfo),i=At(()=>Ln(e.fingerprint),[e.fingerprint]),a=[e.derivationPath,e.fingerprint&&(i?`fingerprint`:e.fingerprint),e.publicInfo&&`addresses`].filter(Boolean).join(` · `),o=e.derivationPath.trim();return H(Wn,{id:`${e.id}:public`,title:`Public info`,icon:`eye`,summary:a||`empty`,defaultOpen:!1,children:[H(`p`,{class:`muted small helper`,children:`Not secret. Helps you recognize the wallet without revealing the secret.`}),H(`div`,{class:`row`,children:[H($,{label:`Derivation path`,children:H(`input`,{class:`input mono`,list:`paths`,value:e.derivationPath,placeholder:`m/84'/0'/0'`,readOnly:n,onInput:e=>t({derivationPath:e.currentTarget.value}),onBlur:n=>{let r=rr(n.currentTarget.value);r!==e.derivationPath&&t({derivationPath:r})},...Pt})}),H($,{label:`Master fingerprint`,children:H(`input`,{class:`input mono`,value:e.fingerprint,placeholder:`e.g. 73c5da0a`,readOnly:n,onInput:e=>t({fingerprint:e.currentTarget.value}),onBlur:n=>{let r=nr(n.currentTarget.value,!0);r!==e.fingerprint&&t({fingerprint:r})},...Pt})})]}),o&&!/^m(\/\d+['hH]?)*$/.test(o)&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` `,/[’‘′`]/.test(o)?`Use straight apostrophes (') in derivation paths; curly ones are fixed when you leave the field.`:`Derivation paths look like m/84'/0'/0'.`]}),e.fingerprint&&!i&&!/^[0-9a-fA-F]{8}$/.test(e.fingerprint.trim())&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` A master fingerprint is 8 hex characters.`]}),H($,{label:`Addresses / xpub`,wide:!0,children:H(`textarea`,{class:`input mono`,rows:r?3:2,value:e.publicInfo,placeholder:`First receive address, xpub/zpub…`,readOnly:n,onInput:e=>t({publicInfo:e.currentTarget.value}),...Pt})}),H(tr,{text:e.publicInfo}),H(tr,{text:e.fingerprint})]})},or=({entry:e,update:t,reminderMonths:n})=>{let{readOnly:r}=Z(),i=(n,r)=>t({backups:e.backups.map(e=>e.id===n?{...e,...r}:e)}),a=wt(e,n),o=Ct(e),s=H(`span`,{class:a?`status-warn`:void 0,children:[e.backups.length?Un(e.backups.length,`location`):`none recorded`,o?` · checked ${o}`:``,a?` · check due`:``]});return H(Wn,{id:`${e.id}:backups`,title:`Backups`,icon:`shield`,summary:s,defaultOpen:!1,action:r?void 0:{label:`Add location`,onClick:()=>{let n=qe();t({backups:[...e.backups,{id:n,location:``,verifiedOn:``}]}),Jn(n)}},children:[H(`p`,{class:`status ${a?`status-warn`:`status-info`}`,children:[H(U,{name:a?`alert`:`check`}),` `,o?`Last checked ${o}.`:`No backup check recorded.`,a&&n>0&&` Check your backups at least every ${n} months.`]}),e.backups.length===0&&H(`p`,{class:`muted small helper`,children:`Record where copies are kept, like "steel plate in home safe". Do not record the secret itself here.`}),e.backups.map(n=>H(`div`,{class:`row backup-row`,"data-row":n.id,children:[H(`input`,{class:`input grow`,value:n.location,placeholder:`Location, e.g. steel plate in safe`,"aria-label":`Backup location`,readOnly:r,onInput:e=>i(n.id,{location:e.currentTarget.value}),...Pt}),H(`input`,{class:`input`,type:`date`,value:n.verifiedOn,"aria-label":`Last checked`,readOnly:r,onInput:e=>i(n.id,{verifiedOn:e.currentTarget.value})}),!r&&H(C,{children:[H(`button`,{type:`button`,class:`button small`,onClick:()=>i(n.id,{verifiedOn:nt()}),children:`Checked today`}),H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Remove backup location`,title:`Remove`,onClick:()=>t({backups:e.backups.filter(e=>e.id!==n.id)}),children:H(U,{name:`x`})})]})]},n.id))]})},sr=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=(n,r)=>t({customFields:e.customFields.map(e=>e.id===n?{...e,...r}:e)}),i=J[e.kind].secret===`fields`;return H(Wn,{id:`${e.id}:fields`,title:i?`Fields`:`Extra fields`,icon:`plus`,summary:e.customFields.length?Un(e.customFields.length,`field`):`none`,defaultOpen:i,action:n?void 0:{label:`Add field`,onClick:()=>{let n=qe();t({customFields:[...e.customFields,{id:n,label:``,value:``,hidden:!0}]}),Jn(n)}},children:[e.customFields.length===0&&H(`p`,{class:`muted small helper`,children:`For PINs, keystore passwords, 2FA backup codes, multisig details or anything else.`}),e.customFields.map(i=>H(`div`,{class:`custom-field`,"data-row":i.id,children:[H(`input`,{class:`input custom-label`,value:i.label,placeholder:`Label`,"aria-label":`Field label`,readOnly:n,onInput:e=>r(i.id,{label:e.currentTarget.value})}),H(`div`,{class:`custom-value`,children:i.hidden?H(Ft,{label:i.label||`Field`,value:i.value,multiline:i.multiline,onInput:e=>r(i.id,{value:e}),onMultilinePaste:e=>r(i.id,{value:e,multiline:!0})}):i.multiline?H(`textarea`,{class:`input`,rows:3,value:i.value,"aria-label":i.label||`Field value`,readOnly:n,onInput:e=>r(i.id,{value:e.currentTarget.value}),...Pt}):H(`input`,{class:`input`,value:i.value,"aria-label":i.label||`Field value`,readOnly:n,onInput:e=>r(i.id,{value:e.currentTarget.value}),...Pt,onPaste:e=>{let t=e.clipboardData?.getData(`text`)??``;if(!/[\r\n]/.test(t))return;e.preventDefault();let n=e.currentTarget,a=n.selectionStart??i.value.length,o=n.selectionEnd??i.value.length;r(i.id,{value:i.value.slice(0,a)+t+i.value.slice(o),multiline:!0})}})}),!n&&H(`div`,{class:`custom-actions`,children:[H(`label`,{class:`check small`,children:[H(`input`,{type:`checkbox`,checked:i.hidden,"aria-label":`Hide ${i.label||`field`} value`,onChange:e=>r(i.id,{hidden:e.currentTarget.checked})}),` `,`Hidden`]}),H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Remove field`,title:`Remove`,onClick:()=>t({customFields:e.customFields.filter(e=>e.id!==i.id)}),children:H(U,{name:`x`})})]})]},i.id))]})},cr=({entry:e,update:t})=>{let{readOnly:n}=Z();return H(Wn,{id:`${e.id}:notes`,title:`Notes`,summary:e.notes?Un(e.notes.length,`character`):`empty`,defaultOpen:!!e.notes&&e.kind===`other`,children:[H(`textarea`,{class:`input`,rows:4,value:e.notes,placeholder:`Recovery instructions, inheritance notes, history…`,"aria-label":`Notes`,readOnly:n,onInput:e=>t({notes:e.currentTarget.value}),...Nt}),Xn(e,e.notes)&&H(`p`,{class:`status status-error`,role:`status`,children:[H(U,{name:`alert`}),` This text repeats the entry's secret, and it is not hidden.`]})]})},lr=e=>{let t=new Set;return e.split(`,`).map(e=>e.trim()).filter(e=>e&&!t.has(e.toLowerCase())&&t.add(e.toLowerCase()))},ur=({tags:e,onChange:t})=>{let{readOnly:n}=Z(),[r,i]=R(e.join(`, `));z(()=>{lr(r).join(`,`)!==e.join(`,`)&&i(e.join(`, `))},[e.join(`,`)]);let a=n=>{i(n);let r=lr(n);r.join(`,`)!==e.join(`,`)&&t(r)},o=()=>i(lr(r).join(`, `));return H(`input`,{class:`input`,value:r,placeholder:`cold storage, inheritance`,readOnly:n,onInput:e=>a(e.currentTarget.value),onBlur:o,onKeyDown:e=>e.key===`Enter`&&o()})},dr=({entry:e,onUpdate:t,onDelete:n,onDuplicate:r})=>{let{readOnly:i}=Z();return i?null:H(`div`,{class:`entry-actions`,children:[H(`button`,{type:`button`,class:`icon-button ${e.favorite?`active`:``}`,"aria-pressed":e.favorite,"aria-label":`Favorite`,title:`Favorite`,disabled:i,onClick:()=>t({favorite:!e.favorite}),children:H(U,{name:`star`,fill:e.favorite?`currentColor`:`none`})}),!i&&H(C,{children:[H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Duplicate`,title:`Duplicate`,onClick:r,children:H(U,{name:`duplicate`})}),H(`button`,{type:`button`,class:`icon-button ${e.archived?`active`:``}`,"aria-label":e.archived?`Unarchive`:`Archive`,title:e.archived?`Unarchive`:`Archive (e.g. an emptied or retired wallet)`,onClick:()=>t({archived:!e.archived}),children:H(U,{name:`archive`})}),H(`button`,{type:`button`,class:`icon-button danger`,"aria-label":`Delete`,title:`Delete`,onClick:n,children:H(U,{name:`trash`})})]})]})},fr=e=>{let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString()},pr=({entry:e,reminderMonths:t,onUpdate:n,showLabel:r,focusLabel:i=!1})=>{let{readOnly:a}=Z(),o=e=>!a&&n(e),s=J[e.kind].secret;return H(`div`,{class:`entry-body`,children:[H(Kn,{entry:e,update:o,showLabel:r,focusLabel:i}),s===`words`&&H(qn,{entry:e,update:o}),(s===`key`||s===`token`)&&H($n,{entry:e,update:o}),s===`codes`&&H(er,{entry:e,update:o}),s===`fields`&&H(sr,{entry:e,update:o}),Xe(e.kind)?H(ar,{entry:e,update:o}):H(ir,{entry:e,update:o}),s!==`fields`&&H(sr,{entry:e,update:o}),H(or,{entry:e,update:o,reminderMonths:t}),H(cr,{entry:e,update:o}),H(`footer`,{class:`editor-footer muted small`,children:[`Added `,fr(e.addedAt),` · Updated `,fr(e.updatedAt)]})]})},mr=({entry:e,reminderMonths:t,onUpdate:n,onDelete:r,onDuplicate:i,onBack:a,focusLabel:o})=>{let{readOnly:s}=Z(),c=B(null);return z(()=>{o&&c.current?.focus()},[]),H(`article`,{class:`editor`,"aria-label":e.label||`Untitled entry`,children:[H(`header`,{class:`editor-header`,children:[H(`button`,{type:`button`,class:`icon-button back-button`,"aria-label":`Back to list`,title:`Back`,onClick:a,children:H(U,{name:`back`})}),H(`input`,{ref:c,class:`input title-input`,value:e.label,placeholder:cn(rn[e.kind]),"aria-label":`Label`,readOnly:s,onInput:e=>!s&&n({label:e.currentTarget.value})}),H(`span`,{class:`badge badge-${e.kind}`,children:rn[e.kind]}),H(dr,{entry:e,onUpdate:n,onDelete:r,onDuplicate:i})]}),H(`div`,{class:`editor-body`,children:H(pr,{entry:e,reminderMonths:t,onUpdate:n,showLabel:!1})})]})},hr=[[`all`,`All`],[`crypto`,`Crypto`],...Je.map(e=>[e,an[e]]),[`favorites`,`Favorites`],[`attention`,`Backup check due`],[`expiring`,`Expiring or expired`],[`archived`,`Archived`]],gr=new Intl.Collator(void 0,{numeric:!0,sensitivity:`base`}),_r=(e,t)=>{if(!t)return!0;let n=[e.label,e.description,e.chain,e.wallet,e.service,e.account,e.notes,e.derivationPath,e.fingerprint,e.publicInfo,...e.tags,...e.customFields.flatMap(e=>e.hidden?[e.label]:[e.label,e.value]),...e.backups.map(e=>e.location)].join(` `).toLowerCase();return t.toLowerCase().split(/\s+/).every(e=>n.includes(e))},vr=(e,t,n,r,i)=>e.filter(e=>t===`archived`?e.archived:!e.archived).filter(e=>{switch(t){case`all`:case`archived`:return!0;case`crypto`:return Xe(e.kind);case`favorites`:return e.favorite;case`attention`:return wt(e,i);case`expiring`:return Et(e);default:return e.kind===t}}).filter(e=>_r(e,r.trim())).sort((e,t)=>e.favorite===t.favorite?n===`label`?!e.label==!t.label?gr.compare(e.label,t.label):e.label?-1:1:n===`created`?(t.createdOn||``).localeCompare(e.createdOn||``):t.updatedAt.localeCompare(e.updatedAt):e.favorite?-1:1),yr=Je,br={none:``,kind:``,chain:`No chain or service`,wallet:`No wallet or account`,tag:`Untagged`},xr=(e,t)=>{if(t===`none`)return[{key:`all`,label:``,entries:e}];let n=e=>t===`kind`?e.kind:t===`chain`?(e.chain||e.service).trim():t===`wallet`?(e.wallet||e.account).trim():(e.tags[0]??``).trim(),r=new Map;for(let i of e){let e=n(i),a=`${t}:${e.toLowerCase()}`,o=r.get(a);o||(o={key:a,label:t===`kind`?an[e]:e||br[t],entries:[]},r.set(a,o)),o.entries.push(i)}let i=[...r.values()];if(t===`kind`)return i.sort((e,t)=>yr.indexOf(e.entries[0].kind)-yr.indexOf(t.entries[0].kind));let a=e=>e.key.endsWith(`:`);return i.sort((e,t)=>Number(a(e))-Number(a(t))||gr.compare(e.label,t.label))},Sr=e=>({order:e.flatMap(e=>e.entries.map(e=>e.id)),groupOf:new Map(e.flatMap(e=>e.entries.map(t=>[t.id,e.key]))),labelOf:new Map(e.map(e=>[e.key,e.label]))}),Cr=(e,t)=>{let n=new Map(t.order.map((e,t)=>[e,t])),r=new Map(e.flatMap(e=>e.entries.map(t=>[t.id,e.key]))),i=new Map(e.map(e=>[e.key,e.label])),a=e.flatMap(e=>e.entries).sort((e,t)=>(n.get(e.id)??-1)-(n.get(t.id)??-1)),o=new Map;for(let e of a){let n=t.groupOf.get(e.id)??r.get(e.id),a=o.get(n);a||(a={key:n,label:t.labelOf.get(n)??i.get(n)??``,entries:[]},o.set(n,a)),a.entries.push(e)}return[...new Set([...t.labelOf.keys(),...e.map(e=>e.key)])].flatMap(e=>o.get(e)??[])},wr=({entry:e})=>{let t=At(()=>$t(e.scheme,e.words),[e.scheme,e.words.join(` `)]);return!t||t.status===`incomplete`||t.status===`unchecked`?null:t.status===`valid`?H(`span`,{class:`pill pill-ok`,title:t.message,children:[H(U,{name:`check`,size:12}),` checksum`]}):H(`span`,{class:`pill pill-error`,title:t.message,children:[H(U,{name:`alert`,size:12}),` check words`]})},Tr=({entry:e})=>{let t=Tt(e);return t===null||!Et(e)?null:t<0?H(`span`,{class:`pill pill-error`,title:`Expired ${e.expiresOn}`,children:`expired`}):H(`span`,{class:`pill pill-warn`,title:`Expires ${e.expiresOn}`,children:t===0?`expires today`:`expires in ${t} day${t===1?``:`s`}`})},Er=({entry:e,reminderMonths:t,idPrefix:n})=>{let r=(Xe(e.kind)?[e.chain,e.wallet,e.kind===`mnemonic`?`${e.words.length} words`:``]:[rn[e.kind],e.service,e.account]).filter(Boolean).join(` · `);return H(C,{children:[H(`span`,{class:`entry-icon badge-${e.kind}`,title:rn[e.kind],children:H(U,{name:on[e.kind]})}),H(`span`,{class:`entry-main`,children:[H(`span`,{class:`entry-title`,id:n&&`${n}-title`,children:[e.favorite&&H(U,{name:`star`,size:12,fill:`currentColor`,class:`star`}),e.label||H(`em`,{class:`muted`,children:cn(rn[e.kind])})]}),r&&H(`span`,{class:`entry-meta`,id:n&&`${n}-meta`,children:r}),H(`span`,{class:`entry-pills`,id:n&&`${n}-pills`,children:[e.kind===`mnemonic`&&H(wr,{entry:e}),e.passphrase&&H(`span`,{class:`pill`,children:`+ passphrase`}),e.archived&&H(`span`,{class:`pill`,children:`archived`}),H(Tr,{entry:e}),wt(e,t)&&H(`span`,{class:`pill pill-warn`,children:e.backups.length?`backup check due`:`no backup recorded`}),e.tags.map(e=>H(`span`,{class:`pill`,children:e},e))]})]}),e.createdOn&&H(`span`,{class:`entry-date`,children:e.createdOn})]})},Dr=({group:e,bare:t,collapsed:n,onToggle:r,children:i})=>{let a=`group-${e.key.replace(/[^a-z0-9]/gi,`-`)}`;return!e.label||t?H(`section`,{class:`group bare`,children:H(`div`,{id:a,children:i})}):H(`section`,{class:`group ${n?`collapsed`:``}`,children:[H(`h2`,{class:`group-heading`,children:H(`button`,{type:`button`,class:`group-toggle`,"aria-expanded":!n,"aria-controls":a,onClick:r,children:[H(U,{name:`chevron`,size:14,class:`chevron`}),H(`span`,{children:e.label}),H(`span`,{class:`count`,children:e.entries.length})]})}),!n&&H(`div`,{id:a,children:i})]})},Or=({groups:e,collapsedGroups:t,selectedId:n,reminderMonths:r,onSelect:i,onToggleGroup:a})=>H(`div`,{class:`entry-list`,children:e.map(o=>H(Dr,{group:o,bare:e.length===1,collapsed:t.has(o.key)&&e.length>1,onToggle:()=>a(o.key),children:H(`ul`,{class:`entry-rows`,"aria-label":o.label||`Entries`,children:o.entries.map(e=>H(`li`,{children:H(`button`,{type:`button`,class:`entry-item ${e.id===n?`selected`:``}`,"aria-current":e.id===n,onClick:()=>i(e.id),children:H(Er,{entry:e,reminderMonths:r})})},e.id))})},o.key))}),kr=(e,t)=>{let n=Object.keys(e);return n.length===Object.keys(t).length&&n.every(n=>Object.is(e[n],t[n]))},Ar=(e=>class extends te{shouldComponentUpdate(e){return!kr(this.props,e)}render(t){return x(e,t)}})(({entry:e,open:t,reminderMonths:n,isNew:r,onToggle:i,...a})=>{let o=B(null);z(()=>{r&&o.current?.scrollIntoView({block:`nearest`})},[r]);let s=`entry-${e.id}`;return H(`li`,{ref:o,class:`card-entry ${t?`open`:``}`,children:[H(`div`,{class:`card-header`,children:[H(`button`,{type:`button`,class:`card-toggle`,"aria-expanded":t,"aria-controls":s,"aria-labelledby":`${s}-title`,"aria-describedby":`${s}-meta ${s}-pills`,onClick:()=>i(e.id),children:[H(U,{name:`chevron`,size:14,class:`chevron`}),H(Er,{entry:e,reminderMonths:n,idPrefix:s})]}),t&&H(dr,{entry:e,...a})]}),t&&H(`div`,{class:`card-body`,id:s,children:H(pr,{entry:e,reminderMonths:n,onUpdate:a.onUpdate,showLabel:!0,focusLabel:r})})]})}),jr=({groups:e,expanded:t,collapsedGroups:n,reminderMonths:r,newId:i,onToggle:a,onToggleGroup:o,handlersFor:s})=>H(`div`,{class:`stack`,children:e.map(c=>H(Dr,{group:c,bare:e.length===1,collapsed:n.has(c.key)&&e.length>1,onToggle:()=>o(c.key),children:H(`ul`,{class:`cards`,"aria-label":c.label||`Entries`,children:c.entries.map(e=>H(Ar,{entry:e,open:t.has(e.id),reminderMonths:r,isNew:e.id===i,onToggle:a,...s(e.id)},e.id))})},c.key))}),Mr=({label:e,icon:t,kind:n,buttonClass:r=`button small`,children:i})=>{let[a,o]=R(!1),s=B(null),c=B(null);return z(()=>{if(!a)return;let e=e=>{s.current?.contains(e.target)||o(!1)};return document.addEventListener(`pointerdown`,e),()=>document.removeEventListener(`pointerdown`,e)},[a]),H(`div`,{class:`popover-wrap`,ref:s,onKeyDown:e=>{e.key===`Escape`&&a&&(e.stopPropagation(),o(!1),c.current?.focus())},onFocusOut:e=>{let t=e.relatedTarget;t&&!s.current?.contains(t)&&o(!1)},children:[H(`button`,{type:`button`,ref:c,class:r,"aria-expanded":a,"aria-label":e,title:e,onClick:()=>o(!a),children:[H(U,{name:t}),` `,H(`span`,{class:`button-text`,children:e})]}),a&&H(`div`,{class:`popover popover-${n}`,children:i(()=>o(!1))})]})},Nr=[`crypto`,`keys`,`secrets`],Pr=({icon:e,label:t,onClick:n,disabled:r})=>H(`button`,{type:`button`,class:`button small`,"aria-label":t,title:t,onClick:n,disabled:r,children:[H(U,{name:e}),` `,H(`span`,{class:`button-text`,children:t})]}),Fr=e=>{let t=e.view.layout===`stacked`;return H(`div`,{class:`toolbar`,children:[H(`div`,{class:`toolbar-row`,children:[H(`div`,{class:`search`,children:[H(U,{name:`search`}),H(`input`,{class:`input`,type:`search`,placeholder:`Search labels, tags, notes`,"aria-label":`Search`,value:e.query,onInput:t=>e.onQuery(t.currentTarget.value),spellcheck:!1})]}),H(`select`,{class:`input`,"aria-label":`Filter`,value:e.filter,onChange:t=>e.onFilter(t.currentTarget.value),children:hr.map(([t,n])=>H(`option`,{value:t,children:[n,t===`attention`&&e.dueCount?` (${e.dueCount})`:``]}))}),!e.readOnly&&H(Mr,{label:`Add`,icon:`plus`,kind:`menu`,buttonClass:`button small primary`,children:t=>Nr.map(n=>H(`div`,{role:`group`,"aria-label":Ye[n],class:`menu-group`,children:[H(`div`,{class:`menu-heading`,"aria-hidden":`true`,children:Ye[n]}),Je.filter(e=>J[e].group===n).map(n=>H(`button`,{type:`button`,class:`menu-item`,onClick:()=>{t(),e.onAdd(n)},children:[H(U,{name:on[n]}),` `,rn[n]]}))]}))})]}),H(`div`,{class:`toolbar-row`,children:[H(`span`,{class:`muted small count`,role:`status`,children:e.shown===e.total?`${e.total} ${e.total===1?`entry`:`entries`}`:`${e.shown} of ${e.total} entries`}),H(`span`,{class:`spacer`}),t&&H(C,{children:[H(Pr,{icon:`expand`,label:`Expand all`,onClick:e.onExpandAll,disabled:e.view.singleExpand||e.shown===0}),H(Pr,{icon:`collapse`,label:`Collapse all`,onClick:e.onCollapseAll,disabled:e.shown===0})]}),H(Mr,{label:`View`,icon:`sliders`,kind:`dialog`,children:()=>H(`div`,{class:`view-options`,children:[H(`fieldset`,{children:[H(`legend`,{children:`Layout`}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`layout`,checked:t,onChange:()=>e.onView({layout:`stacked`})}),` Expandable cards`]}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`layout`,checked:!t,onChange:()=>e.onView({layout:`split`})}),` List + editor side by side`]})]}),H(`fieldset`,{children:[H(`legend`,{children:`Density`}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`density`,checked:e.view.density===`comfortable`,onChange:()=>e.onView({density:`comfortable`})}),` `,`Comfortable`]}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`density`,checked:e.view.density===`compact`,onChange:()=>e.onView({density:`compact`})}),` Compact`]})]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Group by`}),H(`select`,{class:`input`,value:e.view.groupBy,onChange:t=>e.onView({groupBy:t.currentTarget.value}),children:sn.map(([e,t])=>H(`option`,{value:e,children:t}))})]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Sort`}),H(`select`,{class:`input`,value:e.view.sort,onChange:t=>e.onView({sort:t.currentTarget.value}),children:[H(`option`,{value:`updated`,children:`Recently updated`}),H(`option`,{value:`label`,children:`Label`}),H(`option`,{value:`created`,children:`Date created`})]})]}),t&&H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:e.view.singleExpand,onChange:t=>e.onView({singleExpand:t.currentTarget.checked})}),` Open one entry at a time`]})]})}),H(Pr,{icon:`settings`,label:`Settings`,onClick:e.onSettings}),e.hasPassword&&H(Pr,{icon:`lock`,label:`Lock`,onClick:e.onLock}),H(Pr,{icon:`eyeOff`,label:`Hide all`,onClick:e.onHideAll})]})]})},Ir=6e5,Lr=16,Rr=12,zr=Ue,Br=1,Vr=e=>W(`${Ze}|${Br}|PBKDF2-SHA256|${e}|AES-256-GCM`),Hr=async(e,t=q(Lr),n=Ir)=>{let r=await crypto.subtle.importKey(`raw`,K(W(e.normalize(`NFC`))),`PBKDF2`,!1,[`deriveKey`]);return{key:await crypto.subtle.deriveKey({name:`PBKDF2`,hash:`SHA-256`,salt:K(t),iterations:n},r,{name:`AES-GCM`,length:256},!1,[`encrypt`,`decrypt`]),salt:t,iterations:n}},Ur=async(e,t)=>{let n=q(Rr),r=await crypto.subtle.encrypt({name:`AES-GCM`,iv:K(n),additionalData:K(Vr(t.iterations))},t.key,K(W(JSON.stringify(e))));return{kdf:`PBKDF2-SHA256`,iterations:t.iterations,salt:He(t.salt),cipher:`AES-256-GCM`,iv:He(n),ciphertext:He(new Uint8Array(r))}},Wr=class extends Error{constructor(){super(`Wrong password, or the vault data is damaged.`)}},Gr=class extends Error{constructor(){super(`The vault data in this note is damaged. Restore an earlier version from note history.`)}},Kr=e=>{try{return G(e)}catch{throw new Gr}},qr=class extends Error{constructor(){super(`This browser cannot decrypt vaults here: encryption needs a secure (https) page. Open the note in the Standard Notes app or at app.standardnotes.com.`)}},Jr=async(e,t)=>{let n=Kr(e.iv),r=Kr(e.ciphertext),i;try{i=await crypto.subtle.decrypt({name:`AES-GCM`,iv:K(n),additionalData:K(Vr(e.iterations))},t.key,K(r))}catch{throw new Wr}try{return _t(JSON.parse(ze(new Uint8Array(i))))}catch{throw new Gr}},Yr=async(e,t)=>{if(!zr())throw new qr;let n=await Hr(t,Kr(e.salt),e.iterations);return{vault:await Jr(e,n),vaultKey:n}},Xr=(e,t)=>e.salt===He(t.salt)&&e.iterations===t.iterations,Zr=`keyfold-viewer.html`,Qr=`Encrypted backup of a Keyfold vault (https://github.com/nickstruglia/standard-notes-keyfold). To read it without Standard Notes, open ${Zr} (keep a copy next to this file; it is also at https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/${Zr}) in a browser and choose this file; it works offline. To restore it, paste the whole text of this file into a new Standard Notes note, change the note type to Keyfold and unlock it with the backup password. `+et(`the password chosen when the backup was made`),$r=(e=nt())=>`keyfold-backup-${e}.json`,ei=async(e,t,n=Ir)=>{let r=new Date().toISOString(),i=await Ur({...e,settings:{...e.settings,lastExportedAt:r}},await Hr(t,void 0,n));return{text:JSON.stringify({app:Ze,version:1,readme:Qr,exportedAt:r,encryption:i},null,1)+` -`,fileName:$r(),exportedAt:r,entries:e.entries.length}},ti=e=>{let t=e.settings.lastExportedAt;return t?e.entries.filter(e=>e.updatedAt>t||e.addedAt>t).length:e.entries.length},ni=e=>e===0?`Never`:e<60?`${e} seconds`:`${e/60} minute${e===60?``:`s`}`,ri=({value:e,options:t,format:n,onChange:r,disabled:i})=>H(`select`,{class:`input`,value:String(e),disabled:i,onChange:e=>r(Number(e.currentTarget.value)),children:[...new Set([...t,e])].sort((e,t)=>e-t).map(e=>H(`option`,{value:String(e),children:n(e)}))}),ii=new Set([`1234567890`,`12345678910`,`0123456789`,`1111111111`,`qwertyuiop`,`asdfghjkl;`,`password12`,`password123`,`password1!`,`password123!`,`iloveyou12`,`letmein123`,`welcome123`,`abcdefghij`,`qwerty1234`,`1q2w3e4r5t`,`q1w2e3r4t5`,`zaq12wsxcde`,`passw0rd123`,`administrator`,`trustno1234`,`football123`,`baseball12`]),ai=e=>{if(ii.has(e.toLowerCase()))return{bits:0,label:`Very common`,tone:`error`};let t=(/[a-z]/.test(e)?26:0)+(/[A-Z]/.test(e)?26:0)+(/[0-9]/.test(e)?10:0)+(/[^a-zA-Z0-9]/.test(e)?33:0),n=new Set(e).size,r=Math.round(Math.min(e.length,n*2)*Math.log2(Math.max(t,1)));return r<50?{bits:r,label:`Weak`,tone:`error`}:r<75?{bits:r,label:`Fair`,tone:`warn`}:{bits:r,label:`Strong`,tone:`ok`}},oi=10,si={set:`Set password`,change:`Change password`,remove:`Remove password`,export:`Encrypt backup`},ci=({mode:e,onSubmit:t,onCancel:n})=>{let r=e===`change`||e===`remove`,i=e===`export`,a=kt(r),o=kt(!r),[s,c]=R(``),[l,u]=R(``),[d,f]=R(``),[p,m]=R(!1),[h,g]=R(!1),_={strength:Oe(),mismatch:Oe()},[v,y]=R(!1),[b,ee]=R(``),x=ai(l),S=x.tone===`error`,te=e!==`remove`,w=d!==``&&d!==l,T=(!r||s.length>0)&&(!te||l.length>=oi&&l===d&&p&&(!S||h));return H(`form`,{class:`password-form`,onSubmit:async e=>{if(e.preventDefault(),T&&!v){y(!0),ee(``);try{await t(s,l)}catch(e){ee(e instanceof Error?e.message:String(e)),y(!1)}}},children:[r&&H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Current vault password`}),H(`input`,{class:`input`,type:`password`,autocomplete:`current-password`,value:s,onInput:e=>c(e.currentTarget.value),ref:a})]}),te&&H(C,{children:[H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:i?`Backup password`:`New vault password`}),H(`input`,{class:`input`,type:`password`,autocomplete:`new-password`,value:l,onInput:e=>u(e.currentTarget.value),ref:o,"aria-describedby":l?_.strength:void 0}),l&&H(`span`,{id:_.strength,class:`hint status-${x.tone}`,children:[x.label,` (~`,x.bits,` bits).`,` `,l.lengthf(e.currentTarget.value),"aria-invalid":w,"aria-describedby":w?_.mismatch:void 0}),w&&H(`span`,{id:_.mismatch,class:`hint status-error`,role:`alert`,children:`Passwords do not match.`})]}),S&&l.length>=oi&&H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:h,onChange:e=>g(e.currentTarget.checked)}),H(`span`,{children:i?`Use this weak password anyway. Anyone who finds the backup file could guess it quickly.`:`Use this weak password anyway. Someone with access to your Standard Notes account could guess it quickly.`})]}),e===`change`&&H(`p`,{class:`small status-warn`,children:[H(U,{name:`alert`}),` Older versions of this note in Standard Notes' note history still open with the old password. If it leaked, delete those revisions too.`]}),H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:p,onChange:e=>m(e.currentTarget.checked)}),H(`span`,{children:i?`I understand that if I forget this password, no one (not Standard Notes, not the developer) can open this backup.`:`I understand that if I forget this password, no one (not Standard Notes, not the developer) can recover the secrets in this note.`})]})]}),b&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` `,b]}),H(`div`,{class:`row`,children:[H(`button`,{type:`submit`,class:`button ${e===`remove`?`danger`:`primary`}`,disabled:!T||v,children:v?i?`Encrypting…`:`Working…`:si[e]}),H(`button`,{type:`button`,class:`button`,onClick:n,disabled:v,children:`Cancel`})]})]})},li=e=>`${(e/1024).toFixed(+(e<10240))} KB`,ui=({vault:e,mobileApp:t,onExport:n,onExported:r,onCopy:i})=>{let{toast:a}=Z(),[o,s]=R(!1),[c,l]=R(null),u=Te(()=>{if(!c)return null;let e=new Blob([c.text],{type:`application/json`});return{url:URL.createObjectURL(e),size:e.size}},[c]);z(()=>{if(u)return()=>{setTimeout(()=>URL.revokeObjectURL(u.url),6e4)}},[u]);let d=B(null),f=B(null);z(()=>(t?f:d).current?.focus(),[u]);let p=e.settings.lastExportedAt,m=p?ti(e):0,h=zr()?mt(e)?`This vault was saved by a newer version of Keyfold. Update Keyfold first, so the backup leaves nothing out.`:e.entries.length===0?`There is nothing to back up yet.`:``:`Your browser does not provide WebCrypto here, so a backup cannot be encrypted.`,g=async()=>{c&&(await i(c.text)?(r(c),a(`Backup copied. Paste it into a text file or another app; only its password opens it.`,`success`)):a(`Could not copy the backup: clipboard access was blocked.`,`error`))},_=c&&u&&H(`a`,{ref:d,class:`button ${t?``:`primary`}`,href:u.url,download:c.fileName,onClick:()=>r(c),children:[H(U,{name:`download`}),` Save file`]}),v=H(`button`,{ref:f,type:`button`,class:`button ${t?`primary`:``}`,onClick:g,children:[H(U,{name:`copy`}),` Copy as text`]});return H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`download`}),` Backup file`]}),H(`p`,{class:`small`,children:`Save an encrypted copy of this vault outside Standard Notes, for example on a flash drive, so you can still read it if Standard Notes is ever unavailable. The Keyfold offline viewer opens it in any browser, with no account and no internet connection.`}),H(`p`,{class:`muted small`,children:[p?`Last backup file: ${ln(p)}.`:`No backup file made yet.`,m>0&&` ${m} ${m===1?`entry was`:`entries were`} added or changed since.`]}),c&&u?H(`div`,{class:`backup-ready`,children:[H(`p`,{class:`status status-ok`,role:`status`,children:[H(U,{name:`check`}),` Encrypted `,c.entries,` `,c.entries===1?`entry`:`entries`,` into `,c.fileName,` (`,li(u.size),`).`]}),H(`div`,{class:`row`,children:[t?v:_,t?_:v,H(`button`,{type:`button`,class:`button`,onClick:()=>l(null),children:`Done`})]}),(t||Mt())&&H(`p`,{class:`small`,children:[t?`The Standard Notes phone app may not save files from plugins. `:``,`If Save file does nothing, copy the text and paste it into a file or another app, or make the backup on a computer.`]}),H(`p`,{class:`muted small`,children:`Keep it somewhere other than Standard Notes, with the offline viewer next to it, and make a new one after adding or changing keys.`})]}):o?H(C,{children:[H(`p`,{class:`small`,children:`Choose a password for this backup. It can be your vault password or a different one, as long as you will still remember it in years.`}),H(ci,{mode:`export`,onSubmit:async(e,t)=>{l(await n(t)),s(!1)},onCancel:()=>s(!1)})]}):H(C,{children:[h&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` `,h]}),H(`div`,{class:`row`,children:[H(`button`,{type:`button`,class:`button primary`,disabled:!!h,onClick:()=>s(!0),children:[H(U,{name:`download`}),` Make a backup file`]}),H(`a`,{class:`button`,href:`https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/${Zr}`,target:`_blank`,rel:`noopener noreferrer`,children:`Get the offline viewer`})]})]})]})},di=({vault:e,settings:t,hasPassword:n,onChange:r,onSetPassword:i,onChangePassword:a,onRemovePassword:o,onExport:s,onExported:c,onCopyBackup:l,mobileApp:u,onLock:d,onClose:f})=>{let{readOnly:p}=Z(),[m,h]=R(null);return H(`article`,{class:`editor settings`,children:[H(`header`,{class:`editor-header`,children:[H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Close settings`,title:`Back`,onClick:f,children:H(U,{name:`back`})}),H(`h2`,{children:`Vault settings`})]}),H(`div`,{class:`editor-body`,children:[H(`p`,{class:`muted small`,children:`Settings are saved in this note, so every device uses the same ones.`}),H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`eye`}),` Privacy`]}),H(`div`,{class:`row`,children:[H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Hide revealed secrets after`}),H(ri,{value:t.autoHideSeconds,options:[0,10,30,60,120,300],format:ni,disabled:p,onChange:e=>r({autoHideSeconds:e})})]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Clear clipboard after`}),H(ri,{value:t.clipboardClearSeconds,options:[0,10,20,30,60,120],format:ni,disabled:p,onChange:e=>r({clipboardClearSeconds:e})})]})]}),H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:t.hideOnBlur,disabled:p,onChange:e=>r({hideOnBlur:e.currentTarget.checked})}),H(`span`,{children:`Hide revealed secrets when the editor loses focus`})]}),H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:t.privacyScreen,disabled:p,onChange:e=>r({privacyScreen:e.currentTarget.checked})}),H(`span`,{children:`Privacy screen: blur the whole vault while the editor is not focused`})]})]}),H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`shield`}),` Backup reminders`]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Flag entries whose backups were not checked within`}),H(ri,{value:t.backupReminderMonths,options:[0,3,6,12,24],format:e=>e===0?`Off`:`${e} months`,disabled:p,onChange:e=>r({backupReminderMonths:e})})]})]}),H(ui,{vault:e,mobileApp:u,onExport:s,onExported:c,onCopy:l}),H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`lock`}),` Vault password`]}),H(`p`,{class:`small`,children:`Standard Notes already end-to-end encrypts this note. A vault password adds a second layer: the note stays unreadable even to someone using your unlocked Standard Notes account, until the password is entered.`}),H(`p`,{class:`muted small`,children:[`AES-256-GCM, key derived with PBKDF2-SHA256 (`,Ir.toLocaleString(),` iterations). The key is kept only in memory while the vault is unlocked.`]}),!n&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` Older versions of this note in Standard Notes' note history are not re-encrypted. To keep no unprotected copy, set the password on a new, empty vault note before adding secrets, or delete the old revisions.`]}),zr()?m?H(ci,{mode:m,onSubmit:async(e,t)=>{m===`set`&&await i(t),m===`change`&&await a(e,t),m===`remove`&&await o(e),h(null)},onCancel:()=>h(null)}):n?H(C,{children:[H(`p`,{class:`status status-ok`,children:[H(U,{name:`check`}),` This vault is password protected.`]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Lock automatically after inactivity`}),H(ri,{value:t.autoLockMinutes,options:[0,1,2,5,10,15,30,60],format:e=>e===0?`Never`:`${e} minute${e===1?``:`s`}`,disabled:p,onChange:e=>r({autoLockMinutes:e})})]}),H(`div`,{class:`row`,children:[H(`button`,{type:`button`,class:`button primary`,onClick:d,children:[H(U,{name:`lock`}),` Lock now`]}),H(`button`,{type:`button`,class:`button`,disabled:p,onClick:()=>h(`change`),children:`Change password`}),H(`button`,{type:`button`,class:`button danger`,disabled:p,onClick:()=>h(`remove`),children:`Remove password`})]})]}):H(`button`,{type:`button`,class:`button primary`,disabled:p,onClick:()=>h(`set`),children:[H(U,{name:`lock`}),` Set a vault password`]}):H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` Your browser does not provide WebCrypto here, so a vault password is not available.`]})]}),H(`section`,{class:`section`,children:[H(`h3`,{children:`About`}),H(`p`,{class:`small`,children:[`Keyfold `,`1.0.23 (9f45f89)`,`, from `,`https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/`,`. Open source (MIT):`,` `,H(`a`,{href:`https://github.com/nickstruglia/standard-notes-keyfold`,target:`_blank`,rel:`noopener noreferrer`,children:`github.com/nickstruglia/standard-notes-keyfold`}),`. Its Content Security Policy blocks all outgoing connections, images and fonts from other sites; only your Standard Notes theme's stylesheets load.`]})]})]})]})},fi=({onUnlock:e,autoFocus:t,exportedAt:n})=>{let r=n?`Backup password`:`Vault password`,i=zr(),a=kt(t&&i),[o,s]=R(``),[c,l]=R(!1),[u,d]=R(``);return H(`div`,{class:`screen`,children:H(`form`,{class:`card lock-card`,onSubmit:async t=>{if(t.preventDefault(),o&&!c){l(!0),d(``);try{await e(o)}catch(e){d(e instanceof Error?e.message:String(e)),l(!1)}}},children:[H(U,{name:`lock`,size:32}),H(`h2`,{children:n?`Encrypted backup`:`Vault locked`}),H(`p`,{class:`muted small`,children:n?`Made ${ln(n)}. Enter the password chosen when the backup was made.`:`This note has an extra vault password. Standard Notes cannot recover it for you.`}),!i&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` This page cannot decrypt vaults: encryption needs a secure (https) connection. Open the note in the Standard Notes app or at app.standardnotes.com.`]}),H(`input`,{class:`input`,type:`password`,autocomplete:`current-password`,placeholder:r,"aria-label":r,value:o,disabled:!i,onInput:e=>s(e.currentTarget.value),ref:a}),u&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` `,u]}),H(`button`,{type:`submit`,class:`button primary`,disabled:!o||c,children:c?`Unlocking…`:`Unlock`})]})})},pi=({length:e,readOnly:t,onConvert:n})=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(U,{name:`alert`,size:32}),H(`h2`,{children:`This note already has other content`}),H(`p`,{class:`small`,children:[`It holds `,e.toLocaleString(),` characters that are not a Keyfold vault. Nothing has been changed.`]}),H(`p`,{class:`small`,children:`To keep the note as it is, switch it back to another editor in Standard Notes. Or convert it: the existing text is kept, line breaks included, in a hidden field of a new "Imported note" entry.`}),H(`button`,{type:`button`,class:`button primary`,disabled:t,onClick:n,children:`Convert to a vault`})]})}),mi=({version:e})=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(U,{name:`alert`,size:32}),H(`h2`,{children:`Saved by a newer version`}),H(`p`,{class:`small`,children:[`This vault uses format version `,e,`, which this copy of Keyfold does not understand yet. Nothing has been changed. Update the plugin in Standard Notes (Preferences → Plugins) to open it.`]})]})}),hi=()=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(U,{name:`alert`,size:32}),H(`h2`,{children:`Vault encryption not recognized`}),H(`p`,{class:`small`,children:`This is a Keyfold vault, but its password protection uses settings this copy of Keyfold cannot read, or the data is damaged. Nothing has been changed. Update the plugin in Standard Notes (Preferences → Plugins), or restore an earlier version from note history.`})]})}),gi=({slow:e})=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(`p`,{class:`muted`,children:`Connecting to Standard Notes…`}),e&&H(`p`,{class:`small muted`,children:`Still waiting. If Standard Notes asks to activate Keyfold, choose Continue; otherwise, close and reopen the note.`})]})}),_i=({dialog:e,onClose:t})=>{let[n]=R(()=>document.activeElement),r=kt();return z(()=>()=>{n?.isConnected&&n.focus()},[]),z(()=>{let e=e=>e.key===`Escape`&&t(!1);return document.addEventListener(`keydown`,e),()=>document.removeEventListener(`keydown`,e)},[t]),H(`div`,{class:`overlay`,role:`presentation`,onClick:e=>e.target===e.currentTarget&&t(!1),onKeyDown:e=>{if(e.key!==`Tab`)return;let t=Array.from(e.currentTarget.querySelectorAll(`button`)),n=t[0],r=t[t.length-1];e.shiftKey&&document.activeElement===n?(e.preventDefault(),r.focus()):!e.shiftKey&&document.activeElement===r&&(e.preventDefault(),n.focus())},children:H(`div`,{class:`card dialog`,role:`alertdialog`,"aria-modal":`true`,"aria-labelledby":`dialog-title`,"aria-describedby":`dialog-message`,children:[H(`h2`,{id:`dialog-title`,children:e.title}),H(`p`,{id:`dialog-message`,class:`small`,children:e.message}),H(`div`,{class:`row end`,children:[H(`button`,{type:`button`,class:`button`,onClick:()=>t(!1),ref:r,children:`Cancel`}),H(`button`,{type:`button`,class:`button ${e.danger?`danger`:`primary`}`,onClick:()=>t(!0),children:e.confirmLabel??`OK`})]})]})})},vi=({toasts:e,onDismiss:t})=>H(`div`,{class:`toasts`,role:`status`,"aria-live":`polite`,children:e.map(e=>H(`div`,{class:`toast toast-${e.tone}`,children:[H(`span`,{children:e.message}),e.action&&H(`button`,{type:`button`,class:`button small`,onClick:()=>{e.action.run(),t(e.id)},children:e.action.label}),H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Dismiss`,onClick:()=>t(e.id),children:H(U,{name:`x`,size:14})})]},e.id))}),yi=e=>{let t=document.activeElement,n=t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement?t:null,r=n?[n.selectionStart,n.selectionEnd]:null,i=document.createElement(`textarea`);i.value=e,i.setAttribute(`readonly`,``),i.style.position=`fixed`,i.style.opacity=`0`,document.body.appendChild(i),i.select(),i.setSelectionRange(0,e.length);let a=!1;try{a=document.execCommand(`copy`)}catch{a=!1}if(i.remove(),t?.focus?.({preventScroll:!0}),n&&r&&r[0]!==null&&r[1]!==null)try{n.setSelectionRange(r[0],r[1])}catch{}return a},bi=async e=>{if(yi(e))return!0;try{if(navigator.clipboard?.writeText)return await navigator.clipboard.writeText(e),!0}catch{}return!1},xi=()=>yi(` `),Si=async()=>{if(xi())return!0;try{if(navigator.clipboard?.writeText)return await navigator.clipboard.writeText(``),!0}catch{}return!1},Ci=2e3,wi=class{host;onError;delayMs;maxWaitMs;version=0;ready=null;timer;inflight=Promise.resolve();unsentSince=null;readyVersion=0;pending=[];lastText=``;constructor(e,t,n=300,r=1e3){this.host=e,this.onError=t,this.delayMs=n,this.maxWaitMs=r}schedule(e){let t=++this.version;this.unsentSince??=Date.now();let n=async()=>{if(t===this.version)try{let n=await e();if(t!==this.version)return;this.ready=n,this.readyVersion=t,clearTimeout(this.timer);let r=this.unsentSince??Date.now(),i=Math.max(0,Math.min(this.delayMs,r+this.maxWaitMs-Date.now()));this.timer=setTimeout(()=>this.flush(),i)}catch(e){t===this.version&&this.onError(e)}};this.inflight=this.inflight.then(n)}flush(){clearTimeout(this.timer),this.timer=void 0;let e=this.ready;e&&(this.ready=null,this.readyVersion===this.version&&(this.unsentSince=null),this.remember(e.text),this.host.save(e.text,e.preview))}hasUnsent(){return this.unsentSince!==null}async settle(){await this.inflight,this.flush()}cancel(){this.version++,clearTimeout(this.timer),this.timer=void 0,this.ready=null,this.unsentSince=null}isEcho(e){let t=Date.now();this.pending=this.pending.filter(e=>t-e.att.text===e);return n===-1?e!==``&&e===this.lastText:(this.pending.splice(0,n),!0)}forget(){this.cancel(),this.pending=[]}noteSeen(e){this.lastText=e}remember(e){this.lastText=e,this.pending.push({text:e,at:Date.now()}),this.pending.length>20&&this.pending.shift()}},Ti=e=>e instanceof Error?e.message:String(e),Ei=H(`datalist`,{id:`bip39-words`,children:It.map(e=>H(`option`,{value:e}))}),Di=H(Hn,{}),Oi=`The note changed while this was running. Please try again.`,ki=({host:e})=>{let[t,n]=R({name:`connecting`}),[r,i]=R(rt),[a,o]=R(!1),[s,c]=R(!1),[l,u]=R(0),[d,f]=R(()=>document.hasFocus()),[p,m]=R(!1),[h,g]=R({type:`list`}),[_,v]=R(``),[y,b]=R(`all`),[ee,x]=R(()=>new Set),[S,te]=R(()=>new Set),[w,T]=R({}),[ne,E]=R({}),[D,re]=R(null),[ie,ae]=R([]),[oe,O]=R(null),k=B(r),A=B(null),se=B(!1),j=B(0),ce=B(0),le=B(0),M=B(null),ue=Ee(e=>ae(t=>t.filter(t=>t.id!==e)),[]),N=Ee((e,t=`info`,n,r=4e3)=>{let i=++le.current;return ae(r=>{let a=[...r,{id:i,message:e,tone:t,action:n}];for(;a.length>4;){let e=a.findIndex(e=>!e.action&&e.id!==i);a.splice(e===-1?0:e,1)}return a}),setTimeout(()=>ue(i),r),i},[]),P=Te(()=>new wi(e,e=>N(`Could not save: ${Ti(e)}`,`error`,void 0,8e3)),[e]),de=async e=>{let t=A.current;return t?{text:xt(await Ur(e,t)),preview:St(null)}:{text:bt(e),preview:St(e)}},fe=e=>{k.current=e,i(e)},pe=mt(r),F=a||pe||t.name!==`ready`,me=B(F);me.current=F;let he=B(a);he.current=a;let ge=()=>{let e=j.current;return()=>{if(e!==j.current)throw Error(Oi);if(me.current)throw Error(`This note is read-only right now.`)}},_e=()=>{A.current=null,P.cancel(),fe(rt()),u(e=>e+1),g({type:`list`}),x(new Set),T({}),re(null),ae([]),O(e=>(e?.resolve(!1),null))},I=Ee(e=>{if(me.current)return!1;let t=e(k.current);return fe(t),P.schedule(()=>de(t)),!0},[P]);z(()=>{e.subscribe(async e=>{if(o(e.locked),e.metadataOnly||P.isEcho(e.text))return;let t=P.hasUnsent();P.cancel(),P.noteSeen(e.text);let r=++j.current,i=r===1,a=yt(e.text),s=()=>t&&N(`A newer version arrived from another device or note history and replaced your last few keystrokes.`,`error`,void 0,8e3);switch(a.kind){case`empty`:case`plain`:{let e=se.current;A.current&&_e(),se.current=!1,c(!1),fe(a.kind===`plain`?a.vault:rt()),n({name:`ready`}),e&&!i?N(`This vault is no longer password protected: the note was changed on another device or restored from history. Set a password again in Settings if this was not you.`,`error`,void 0,6e4):s();return}case`encrypted`:{c(!0),se.current=!0;let e=A.current;if(e&&Xr(a.blob,e))try{let t=await Jr(a.blob,e);if(r!==j.current)return;P.cancel(),fe(t),n({name:`ready`}),s();return}catch{}if(r!==j.current)return;A.current&&_e(),fe(rt()),n({name:`locked`,blob:a.blob,autoFocus:i||document.hasFocus(),exportedAt:a.exportedAt});return}case`foreign`:case`newer`:case`unsupported`:A.current&&_e(),se.current=!1,c(!1),n(a.kind===`foreign`?{name:`foreign`,text:a.text}:a.kind===`newer`?{name:`newer`,version:a.version}:{name:`unsupported`});return}})},[e,P]),z(()=>{let e=setTimeout(()=>m(!0),5e3);return()=>clearTimeout(e)},[]);let L=r.settings,ve=B(L);ve.current=L,z(()=>{let e=()=>P.flush(),t=()=>{P.flush(),f(!1),ve.current.hideOnBlur&&u(e=>e+1)},n=()=>f(!0),r=()=>document.visibilityState===`hidden`&&P.flush();return window.addEventListener(`blur`,t),window.addEventListener(`focus`,n),window.addEventListener(`pagehide`,e),window.addEventListener(`beforeunload`,e),document.addEventListener(`visibilitychange`,r),()=>{window.removeEventListener(`blur`,t),window.removeEventListener(`focus`,n),window.removeEventListener(`pagehide`,e),window.removeEventListener(`beforeunload`,e),document.removeEventListener(`visibilitychange`,r)}},[P]);let ye=Ee(async(e=!1)=>{e&&M.current&&xi()&&(M.current.blockedToast&&ue(M.current.blockedToast),M.current=null,ce.current++),document.activeElement instanceof HTMLElement&&document.activeElement.blur(),await P.settle();let t=yt(P.lastText);t.kind===`encrypted`?(_e(),n({name:`locked`,blob:t.blob,autoFocus:e||document.hasFocus(),exportedAt:t.exportedAt})):(c(!1),e&&N(`This note is not password protected, so it cannot be locked.`,`error`))},[P]);z(()=>{if(!s||t.name!==`ready`||!L.autoLockMinutes)return;let e=Date.now(),n=()=>e=Date.now(),r=[`pointerdown`,`keydown`,`input`,`wheel`,`touchstart`];r.forEach(e=>window.addEventListener(e,n,{passive:!0}));let i=()=>{Date.now()-e>=L.autoLockMinutes*6e4&&ye()},a=setInterval(i,5e3);return document.addEventListener(`visibilitychange`,i),window.addEventListener(`pageshow`,i),window.addEventListener(`focus`,i),()=>{r.forEach(e=>window.removeEventListener(e,n)),clearInterval(a),document.removeEventListener(`visibilitychange`,i),window.removeEventListener(`pageshow`,i),window.removeEventListener(`focus`,i)}},[s,t.name,L.autoLockMinutes,ye]);let be=async e=>{if(t.name!==`locked`)return;let r=j.current,{vault:i,vaultKey:a}=await Yr(t.blob,e);if(r!==j.current){let e=yt(P.lastText);if(e.kind!==`encrypted`||!Xr(e.blob,a))throw Error(Oi);let t=j.current;if(i=await Jr(e.blob,a),t!==j.current)throw Error(Oi)}if(A.current=a,fe(i),n({name:`ready`}),a.iterations<6e5){let t=ge(),n=await Hr(e);try{t()}catch{return}A.current=n,P.schedule(()=>de(k.current))}},xe=async e=>{await P.settle();let t=yt(P.lastText);if(t.kind!==`encrypted`)throw Error(`The vault is not password protected.`);await Yr(t.blob,e)},Se=async e=>{let t=ge(),n=await Hr(e);t(),A.current=n,c(!0),P.schedule(()=>de(k.current)),N(`Vault password set. The note is now encrypted with it.`,`success`)},Ce=async(e,t)=>{let n=ge();await xe(e);let r=await Hr(t);n(),A.current=r,P.schedule(()=>de(k.current)),N(`Vault password changed.`,`success`)},we=async e=>{let t=ge();await xe(e),t(),A.current=null,c(!1),P.schedule(()=>de(k.current)),N(`Vault password removed. Standard Notes encryption still protects the note.`,`success`)},De=e=>{if(mt(k.current))throw Error(`Update Keyfold before making a backup of this vault.`);return ei(k.current,e)},Oe=async e=>await bi(e)?(ce.current++,M.current?.blockedToast&&ue(M.current.blockedToast),M.current=null,!0):!1,ke=Ee(e=>{let t=ve.current.clipboardClearSeconds,n=++ce.current;M.current?.blockedToast&&ue(M.current.blockedToast),M.current=t?{id:n}:null;let r=Mt(),i=t?`${e} copied. The clipboard is cleared after ${t}s, on your next click or tap here if the browser requires one. It stays copied if you leave this note first.`:`${e} copied.`;if(N(r?`${i} Your keyboard's clipboard history may keep its own copy.`:i,`success`,void 0,r?8e3:6e3),!t)return;let a=()=>{M.current?.blockedToast&&ue(M.current.blockedToast),M.current?.id===n&&(M.current=null),r?N(`Clipboard cleared. Delete it from your keyboard's clipboard history too.`,`info`,void 0,6e3):N(`Clipboard cleared.`,`info`,void 0,3e3)};setTimeout(async()=>{if(n!==ce.current)return;if(await Si()){a();return}let e=[`click`,`touchend`,`pointerup`],t=!1,r=()=>e.forEach(e=>window.removeEventListener(e,i,!0)),i=()=>{if(!t){if(n!==ce.current)return r();xi()&&(t=!0,r(),a())}};e.forEach(e=>window.addEventListener(e,i,!0));let o=N(`Waiting for a click or tap to clear the clipboard.`,`info`,{label:`Clear now`,run:i},2e4);M.current?.id===n&&(M.current.blockedToast=o)},t*1e3)},[N]),Ae=Ee(async(e,t)=>{e&&(await bi(e)?ke(t):N(`Could not copy ${t.toLowerCase()}: clipboard access was blocked.`,`error`))},[ke]);z(()=>{let e=e=>{e.target?.closest?.(`[data-secret]`)&&ke(`Selection`)};return document.addEventListener(`copy`,e,!0),document.addEventListener(`cut`,e,!0),()=>{document.removeEventListener(`copy`,e,!0),document.removeEventListener(`cut`,e,!0)}},[ke]);let je=Ee(e=>new Promise(t=>O({...e,resolve:t})),[]),Me=Te(()=>({settings:L,readOnly:F,hideEpoch:l,copy:Ae,toast:N,confirm:je,sectionOpen:(e,t)=>w[e]??t,setSectionOpen:(e,t)=>T(n=>({...n,[e]:t}))}),[L,F,l,Ae,N,je,w]),V={layout:L.layout,density:L.density,singleExpand:L.singleExpand,groupBy:L.groupBy,sort:L.sort,...ne},Ne=e=>{E(t=>({...t,...e})),I(t=>({...t,settings:{...t.settings,...e}}))},Pe=V.singleExpand,Fe=Ee(e=>{re(null),x(t=>{if(t.has(e)){let n=new Set(t);return n.delete(e),n}return Pe?new Set([e]):new Set(t).add(e)})},[Pe]),Ie=Ee(e=>te(t=>{let n=new Set(t);return n.delete(e)||n.add(e),n}),[]),Le=e=>{b(`all`),v(``),te(new Set),re(e),x(t=>V.singleExpand?new Set([e]):new Set(t).add(e)),g({type:`entry`,id:e})},Re=e=>{let t=it(e);I(e=>({...e,entries:[t,...e.entries]})),Le(t.id)},W=(e,t)=>{I(n=>({...n,entries:n.entries.map(n=>n.id===e?{...n,...t,updatedAt:new Date().toISOString()}:n)}))&&t.archived===!0&&N(`Archived. It is under the "Archived" filter.`,`info`,{label:`Undo`,run:()=>W(e,{archived:!1})},6e3)},ze=e=>{let t=k.current.entries.find(t=>t.id===e);if(!t)return;let n=new Date().toISOString(),r={...JSON.parse(JSON.stringify(t)),id:qe(),label:t.label?`${t.label} (copy)`:``,archived:!1,addedAt:n,updatedAt:n};I(e=>({...e,entries:[r,...e.entries]})),Le(r.id)},Be=async e=>{let t=k.current.entries.findIndex(t=>t.id===e),n=k.current.entries[t];n&&await je({title:`Delete this entry?`,message:`"${n.label||`Untitled`}" will be removed from this note. You can undo right after, and Standard Notes keeps note history.`,confirmLabel:`Delete`,danger:!0})&&k.current.entries.some(t=>t.id===e)&&(I(t=>({...t,entries:t.entries.filter(t=>t.id!==e)}))?(g({type:`list`}),x(t=>{let n=new Set(t);return n.delete(e),n}),N(`Deleted "${n.label||`Untitled`}".`,`info`,{label:`Undo`,run:()=>{k.current.entries.some(e=>e.id===n.id)||I(e=>{let r=[...e.entries];return r.splice(Math.min(t,r.length),0,n),{...e,entries:r}})}},1e4)):N(`Nothing was deleted: the note is read-only right now.`,`error`))},Ve=e=>I(t=>({...t,settings:{...t.settings,...e}})),He=async e=>{let t=j.current;if(!await je({title:`Convert this note?`,message:`The existing text is moved into a hidden field of a new "Imported note" entry, and the note becomes a vault.`,confirmLabel:`Convert`})||t!==j.current||he.current)return;let r=rt();r.entries.push(it(`other`,{label:`Imported note`,customFields:[{id:qe(),label:`Imported text`,value:e,hidden:!0,multiline:!0}]})),fe(r),n({name:`ready`}),c(A.current!==null),P.schedule(()=>de(r))},G=h.type===`entry`?r.entries.find(e=>e.id===h.id)??null:null,Ue=r.entries.filter(e=>wt(e,L.backupReminderMonths)).length,K=V.layout===`stacked`?ee.size>0:G!==null,We=[V.layout,V.sort,V.groupBy,y,_,V.layout===`stacked`?``:G?.id].join(`|`),Ge=B(null),Ke=K&&Ge.current?.key===We?Ge.current.snapshot:null,q=vr(r.entries,y,V.sort,_,L.backupReminderMonths);if(Ke){let e=new Set(q.map(e=>e.id));q=[...q,...r.entries.filter(t=>!e.has(t.id)&&Ke.groupOf.has(t.id))]}let Je=xr(q,V.groupBy);Ke&&(Je=Cr(Je,Ke)),Ge.current={key:We,snapshot:Sr(Je)};let J=B({updateEntry:W,deleteEntry:Be,duplicateEntry:ze});J.current={updateEntry:W,deleteEntry:Be,duplicateEntry:ze};let Ye=B(new Map),Xe=e=>{let t=Ye.current.get(e);return t||(t={onUpdate:t=>J.current.updateEntry(e,t),onDelete:()=>J.current.deleteEntry(e),onDuplicate:()=>J.current.duplicateEntry(e)},Ye.current.set(e,t)),t},Ze=H(`div`,{class:`empty`,children:[H(U,{name:`shield`,size:28}),H(`p`,{children:H(`strong`,{children:`No keys yet.`})}),H(`p`,{class:`small muted`,children:`Keep every seed phrase and wallet key in this note, plus SSH, PGP and API keys and recovery codes. Each one folds into a single line until you open it, and secrets stay hidden until you reveal them.`}),!F&&H(C,{children:[H(`div`,{class:`row tight center`,children:[H(`button`,{type:`button`,class:`button primary small`,onClick:()=>Re(`mnemonic`),children:[H(U,{name:`plus`}),` Seed phrase`]}),H(`button`,{type:`button`,class:`button small`,onClick:()=>Re(`privateKey`),children:[H(U,{name:`plus`}),` Wallet key`]})]}),H(`p`,{class:`small muted`,children:`Other key types are under Add.`})]})]}),Qe=r.entries.length>0&&r.entries.every(e=>e.archived)&&y!==`archived`?H(`p`,{class:`empty small muted`,children:[`Every entry is archived.`,` `,H(`button`,{type:`button`,class:`link-button`,onClick:()=>b(`archived`),children:`Show archived entries`})]}):H(`p`,{class:`empty small muted`,children:`No entries match.`}),$e;switch(t.name){case`connecting`:$e=H(gi,{slow:p});break;case`locked`:$e=H(fi,{onUnlock:be,autoFocus:t.autoFocus,exportedAt:t.exportedAt});break;case`foreign`:$e=H(pi,{length:t.text.length,readOnly:a,onConvert:()=>He(t.text)});break;case`newer`:$e=H(mi,{version:t.version});break;case`unsupported`:$e=H(hi,{});break;case`ready`:{let t=H(Fr,{query:_,onQuery:v,filter:y,onFilter:b,dueCount:Ue,shown:q.length,total:r.entries.filter(e=>y===`archived`?e.archived:!e.archived).length,readOnly:F,onAdd:Re,view:V,onView:Ne,onExpandAll:()=>{te(new Set),x(new Set(q.map(e=>e.id)))},onCollapseAll:()=>{re(null),x(new Set)},onSettings:()=>g({type:`settings`}),hasPassword:s,onLock:()=>ye(!0),onHideAll:()=>u(e=>e+1)});$e=h.type===`settings`?H(`main`,{class:`detail full`,children:H(di,{vault:r,settings:L,hasPassword:s,onChange:Ve,onSetPassword:Se,onChangePassword:Ce,onRemovePassword:we,onExport:De,onExported:e=>Ve({lastExportedAt:e.exportedAt}),onCopyBackup:Oe,mobileApp:e.inMobileApp(),onLock:()=>ye(!0),onClose:()=>g({type:`list`})})}):V.layout===`stacked`?H(C,{children:[t,H(`main`,{class:`detail full`,children:r.entries.length===0?Ze:q.length===0?Qe:H(jr,{groups:Je,expanded:ee,collapsedGroups:S,reminderMonths:L.backupReminderMonths,newId:D,onToggle:Fe,onToggleGroup:Ie,handlersFor:Xe})})]}):H(C,{children:[t,H(`div`,{class:`layout ${G?`has-detail`:``}`,children:[H(`aside`,{class:`sidebar`,children:r.entries.length===0?Ze:q.length===0?Qe:H(Or,{groups:Je,collapsedGroups:S,selectedId:G?.id??null,reminderMonths:L.backupReminderMonths,onSelect:e=>{re(null),g({type:`entry`,id:e})},onToggleGroup:Ie})}),H(`main`,{class:`detail`,children:G?H(mr,{entry:G,reminderMonths:L.backupReminderMonths,focusLabel:G.id===D,onBack:()=>{re(null),g({type:`list`})},...Xe(G.id)},G.id):H(`div`,{class:`placeholder muted`,children:[H(U,{name:`shield`,size:36}),H(`p`,{children:`Select an entry, or add a new one.`})]})})]})]})}}return H(Dt.Provider,{value:Me,children:[H(`div`,{class:`app ${V.density} ${L.privacyScreen&&!d&&t.name===`ready`?`privacy`:``}`,children:[e.mode===`demo`&&H(`div`,{class:`banner banner-warn`,role:`note`,children:[H(U,{name:`alert`}),` Demo mode: not connected to Standard Notes, nothing is saved. Do not type real secrets here. To install, add `,H(`code`,{children:new URL(`ext.json`,location.href).href}),` in Standard Notes → Preferences → Plugins.`,` `,`Lost access to Keyfold? `,H(`a`,{href:`#open`,onClick:()=>setTimeout(()=>location.reload()),children:`Open a backup or note read-only`}),`.`]}),e.mode===`viewer`&&H(`div`,{class:`banner`,role:`note`,children:[H(U,{name:`lock`}),` Read-only viewer: nothing you open here is saved or sent anywhere.`,H(`button`,{type:`button`,class:`link-button`,onClick:()=>location.reload(),children:`Close`})]}),pe&&t.name===`ready`&&H(`div`,{class:`banner`,role:`note`,children:[H(U,{name:`alert`}),` This vault was saved by a newer version of Keyfold, so it is read-only here. Update the plugin in Standard Notes (Preferences → Plugins) to edit it.`]}),a&&e.mode!==`viewer`&&t.name===`ready`&&H(`div`,{class:`banner`,role:`note`,children:[H(U,{name:`lock`}),` "Prevent editing" is on for this note. You can still reveal and copy secrets.`]}),$e,L.privacyScreen&&!d&&t.name===`ready`&&H(`button`,{type:`button`,class:`privacy-cover`,onClick:()=>{window.focus(),f(!0)},children:[H(U,{name:`eyeOff`,size:28}),H(`span`,{children:Mt()?`Tap to show the vault`:`Click to show the vault`})]})]}),Di,Ei,oe&&H(_i,{dialog:oe,onClose:e=>{oe.resolve(e),O(null)}}),H(vi,{toasts:ie,onDismiss:e=>ae(t=>t.filter(t=>t.id!==e))})]})},Ai=()=>typeof crypto.randomUUID==`function`?crypto.randomUUID():Array.from(crypto.getRandomValues(new Uint8Array(16)),e=>e.toString(16).padStart(2,`0`)).join(``),ji=e=>e&&/^https?:\/\//.test(e)?e:`*`,Mi=`https://app.standardnotes.com/components/assets/`,Ni=e=>{if(/^https?:\/\//i.test(e)||/^data:text\/css[;,]/i.test(e))return e;let t=/\/components\/assets\/([a-z0-9][a-z0-9.-]*)\/([\w.-]+(?:\/[\w.-]+)*\.css)$/i.exec(e);if(t&&!t[0].includes(`..`))return`${Mi}${t[1]}/${t[2]}`},Pi=2e3,Fi=[`Shift`,`Alt`,`Control`,`Meta`,`AltGraph`],Ii=class{win;sessionKey;origin;environment;queue=[];callbacks=new Map;themeLoads=new WeakMap;themeGeneration=0;constructor(e=window){this.win=e,e.addEventListener(`message`,this.onMessage),e.addEventListener(`click`,this.onClick),e.addEventListener(`keydown`,this.onKey),e.addEventListener(`keyup`,this.onKey),setTimeout(this.reveal,Pi)}get inMobileApp(){return this.environment===`native-mobile-web`||this.environment===`mobile`}streamContextItem(e){this.send(`stream-context-item`,{},t=>t?.item&&e(t.item),!0)}saveItem(e,t){this.send(`save-items`,{items:[e]},()=>t?.())}send(e,t,n,r=!1){if(!this.sessionKey){this.queue.push({action:e,data:t,callback:n,keep:r});return}let i={action:e,data:t,messageId:Ai(),sessionKey:this.sessionKey,api:`component`};n&&this.callbacks.set(i.messageId,{callback:n,keep:r});let a=this.environment===`mobile`?JSON.stringify(i):i;this.win.parent.postMessage(a,ji(this.origin))}onMessage=e=>{if(e.source!==this.win.parent||this.win.parent===this.win)return;let t;try{t=typeof e.data==`string`?JSON.parse(e.data):e.data}catch{return}if(t&&typeof t==`object`)switch(t.action){case`component-registered`:if(this.sessionKey||!t.sessionKey)return;this.sessionKey=t.sessionKey,this.origin=e.origin,this.environment=t.data?.environment,this.activateThemes(t.data?.activeThemeUrls),this.send(`themes-activated`,{});for(let e of this.queue.splice(0))this.send(e.action,e.data,e.callback,e.keep);return;case`themes`:this.activateThemes(t.data?.themes);return;case`reply`:{let e=t.original?.messageId,n=e?this.callbacks.get(e):void 0;if(!n)return;n.keep||this.callbacks.delete(e),n.callback(t.data);return}}};onClick=()=>{this.sessionKey&&this.send(`click`,{})};onKey=e=>{if(!this.sessionKey)return;let t=Fi.includes(e.key),n=e.type===`keyup`&&t;(!e.getModifierState?.(`AltGraph`)||t)&&(e.ctrlKey||e.metaKey||e.key===`Control`||e.key===`Meta`||n)&&(e.type===`keydown`&&(e.ctrlKey||e.metaKey)&&e.key.toLowerCase()===`s`&&e.preventDefault(),this.send(e.type===`keydown`?`key-down`:`key-up`,{key:e.key,code:e.code,ctrlKey:e.ctrlKey,metaKey:e.metaKey,shiftKey:e.shiftKey,altKey:e.altKey}))};activateThemes(e){let t=Array.isArray(e)?e.filter(e=>typeof e==`string`):[],n=[...new Set(t.map(Ni).filter(e=>!!e))],r=this.win.document,i=[...r.querySelectorAll(`link[data-sn-theme]`)],a=[];for(let e of n){let t=i.find(t=>t.getAttribute(`href`)===e);if(t){a.push(this.themeLoads.get(t)??Promise.resolve());continue}let n=r.createElement(`link`),o=new Promise(e=>{n.onload=n.onerror=e});this.themeLoads.set(n,o),a.push(o),n.rel=`stylesheet`,n.href=e,n.setAttribute(`data-sn-theme`,``),r.head.appendChild(n)}let o=++this.themeGeneration;Promise.all(a).then(()=>{if(o===this.themeGeneration){for(let e of i)n.includes(e.getAttribute(`href`)??``)||e.remove();this.updateColorScheme(),this.reveal()}})}updateColorScheme(){let e=this.win.document,t=/^rgba?\(([^)]*)\)/.exec(this.win.getComputedStyle(e.body).backgroundColor)?.[1].split(/[\s,/]+/).map(Number);if(!t||t.length<3||t[3]===0)return;let n=.2126*t[0]+.7152*t[1]+.0722*t[2];e.documentElement.style.colorScheme=n<128?`dark`:`light`}reveal=()=>{this.win.document.documentElement.classList.remove(`theme-pending`)}},Li=e=>e.content?.appData?.[`org.standardnotes.sn`]?.locked===!0,Ri=()=>{let e=new Ii(window),t=null;return{mode:`standardnotes`,inMobileApp:()=>e.inMobileApp,subscribe(n){e.streamContextItem(e=>{t=e,n({text:e.content?.text??``,locked:Li(e),metadataOnly:e.isMetadataUpdate===!0})})},save(n,r){let i=t;i&&(i.content.text=n,i.content.preview_plain=r,i.content.preview_html=``,e.saveItem(i))}}},zi=e=>{let t=e;return{mode:`demo`,inMobileApp:()=>!1,subscribe(e){queueMicrotask(()=>e({text:t,locked:!1,metadataOnly:!1}))},save(e){t=e}}},Bi=e=>({mode:`viewer`,inMobileApp:()=>!1,subscribe(t){queueMicrotask(()=>t({text:e,locked:!0,metadataOnly:!1}))},save(){}}),Vi=()=>{try{return window.parent!==window}catch{return!0}},Hi=20971520,Ui=e=>new Promise((t,n)=>{let r=new FileReader;r.onload=()=>t(String(r.result??``)),r.onerror=()=>n(r.error),r.readAsText(e)}),Wi=({offlineViewer:e,onOpen:t})=>{let[n,r]=R(``),[i,a]=R(``),[o,s]=R(!1),c=B(null),l=kt(),u=(e,n)=>{let r=yt(e).kind;if(r===`empty`)return a(n===`file`?`This file is empty.`:`Paste the text first.`);if(r===`foreign`)return a(n===`file`?`This file is not a Keyfold backup or note.`:`This is not the text of a Keyfold note. Copy all of it, from the first { to the last }, without editing.`);t(e)},d=async e=>{if(e){if(a(``),e.size>Hi)return a(`This file is too large to be a Keyfold backup.`);try{u(await Ui(e),`file`)}catch{a(`Could not read this file.`)}}};return H(`div`,{class:`app`,children:H(`div`,{class:`screen ${o?`dragging`:``}`,onDragOver:e=>{e.preventDefault(),s(!0)},onDragLeave:e=>{e.currentTarget===e.target&&s(!1)},onDrop:e=>{e.preventDefault(),s(!1),d(e.dataTransfer?.files[0])},children:H(`form`,{class:`card open-note`,onSubmit:e=>{e.preventDefault(),a(``),u(n,`paste`)},children:[H(U,{name:`lock`,size:32}),H(`h2`,{children:e?`Keyfold offline viewer`:`Open a Keyfold backup or note`}),H(`p`,{class:`small`,children:[`Open a Keyfold backup file, or paste the text of a Keyfold note. It opens read-only. Nothing is saved, and this page cannot send anything anywhere`,e?`, so it works offline`:``,`.`]}),H(`input`,{ref:c,type:`file`,hidden:!0,"aria-label":`Backup file`,onChange:e=>{let t=e.currentTarget;d(t.files?.[0]).finally(()=>{t.value=``})}}),H(`button`,{ref:l,type:`button`,class:`button primary`,onClick:()=>c.current?.click(),children:[H(U,{name:`file`}),` Choose backup file`]}),!Mt()&&H(`p`,{class:`muted small`,children:`or drop it on this page`}),i&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` `,i]}),H(`details`,{class:`paste-note`,children:[H(`summary`,{children:`Paste a note's text instead`}),H(`p`,{class:`small`,children:`In Standard Notes, change the note type to Plain text, then select all and copy, without editing.`}),H(`textarea`,{class:`input mono`,rows:8,value:n,"aria-label":`Note text`,placeholder:`{ "app": "keyfold", ... }`,onInput:e=>r(e.currentTarget.value),autocomplete:`off`,spellcheck:!1}),H(`button`,{type:`submit`,class:`button`,disabled:!n.trim(),children:`Open read-only`})]}),location.protocol!==`file:`&&H(`a`,{class:`small`,href:`./keyfold-viewer.html`,download:`keyfold-viewer.html`,children:`Save this viewer as a single file, to keep next to your backups`}),!e&&H(`a`,{class:`small`,href:`./`,children:`Back to the demo`})]})})})},Gi=e=>e.split(` `),Ki=e=>{let t=new Uint8Array(4+e.length);return new DataView(t.buffer).setUint32(0,e.length),t.set(e,4),t},qi=(...e)=>{let t=new Uint8Array(e.reduce((e,t)=>e+t.length,0)),n=0;for(let r of e)t.set(r,n),n+=r.length;return t},Ji=()=>{let e=qi(Ki(W(`ssh-ed25519`)),Ki(q(32)));return{privateKey:`-----BEGIN OPENSSH PRIVATE KEY-----\n${He(qi(W(`openssh-key-v1\0`),Ki(W(`aes256-ctr`)),Ki(W(`bcrypt`)),Ki(q(24)),new Uint8Array([0,0,0,1]),Ki(e),Ki(q(144)))).match(/.{1,70}/g).join(` -`)}\n-----END OPENSSH PRIVATE KEY-----`,publicKey:`ssh-ed25519 ${He(e)} demo@example`}},Yi=(e,t=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`)=>Array.from(q(e),e=>t[e%t.length]).join(``),Xi=e=>{let t=new Date;return t.setDate(t.getDate()+e),t.toISOString().slice(0,10)},Zi=()=>{let e=Ji(),t=rt();return t.entries.push(it(`mnemonic`,{label:`Example: cold storage`,description:`Public BIP39 test vector. Do not send funds to it.`,chain:`Bitcoin`,wallet:`Coldcard`,tags:[`example`,`long-term`],favorite:!0,words:Gi(`legal winner thank year wave sausage worth useful legal winner thank yellow`),passphrase:`example passphrase`,passphraseHint:`Example hint only`,derivationPath:`m/84'/0'/0'`,createdOn:`2021-03-14`,backups:[{id:`b1`,location:`Steel plate in home safe`,verifiedOn:nt()}]}),it(`mnemonic`,{label:`Example: multisig key 2 of 3`,chain:`Bitcoin`,wallet:`Trezor`,tags:[`example`,`multisig`],words:Gi(`letter advice cage absurd amount doctor acoustic avoid letter advice cage above`),derivationPath:`m/48'/0'/0'/2'`,createdOn:`2022-08-02`,backups:[{id:`b2`,location:`Bank deposit box`,verifiedOn:`2025-01-10`}]}),it(`mnemonic`,{label:`Example: DeFi hot wallet`,chain:`Ethereum`,wallet:`MetaMask`,tags:[`example`],words:Gi(`${`abandon `.repeat(23)}art`),derivationPath:`m/44'/60'/0'/0/0`,createdOn:`2023-11-20`}),it(`privateKey`,{label:`Example: paper wallet`,description:`WIF test vector from the Bitcoin wiki.`,chain:`Bitcoin`,tags:[`example`],secret:`5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ`,createdOn:`2013-04-01`}),it(`sshKey`,{label:`Example: deploy key`,description:`Random bytes in OpenSSH format, not a working key.`,service:`github.com`,account:`git`,tags:[`example`],secret:e.privateKey,passphrase:`example passphrase`,publicInfo:e.publicKey,expiresOn:Xi(365)}),it(`apiKey`,{label:`Example: CI token`,description:`Random characters in GitHub token format, not a real token.`,service:`GitHub`,account:`release workflow`,tags:[`example`],secret:`ghp_${Yi(36)}`,expiresOn:Xi(12)}),it(`recoveryCodes`,{label:`Example: exchange 2FA backup codes`,service:`Kraken`,account:`you@example.com`,tags:[`example`],secret:Array.from({length:8},()=>`${Yi(4,`0123456789`)}-${Yi(4,`0123456789`)}`).join(` -`)})),t.entries.forEach((e,t)=>e.updatedAt=new Date(Date.now()-t*6e4).toISOString()),bt(t)},Qi=document.documentElement.hasAttribute(`data-viewer`),$i=!Qi&&Vi();document.documentElement.classList.toggle(`standalone`,!$i),$i||document.documentElement.classList.remove(`theme-pending`);var ea=document.getElementById(`app`);$i?de(H(ki,{host:Ri()}),ea):Qi||location.hash===`#open`?de(H(Wi,{offlineViewer:Qi,onOpen:e=>de(H(ki,{host:Bi(e)}),ea)}),ea):de(H(ki,{host:zi(Zi())}),ea)})(); \ No newline at end of file diff --git a/packages/io.github.nickstruglia.keyfold/prebuilt/index.html b/packages/io.github.nickstruglia.keyfold/prebuilt/index.html index c0eb4a1..eaab82d 100644 --- a/packages/io.github.nickstruglia.keyfold/prebuilt/index.html +++ b/packages/io.github.nickstruglia.keyfold/prebuilt/index.html @@ -8,7 +8,7 @@ Keyfold - +
diff --git a/packages/io.github.nickstruglia.keyfold/prebuilt/keyfold-viewer.html b/packages/io.github.nickstruglia.keyfold/prebuilt/keyfold-viewer.html index 9aad608..533cb4a 100644 --- a/packages/io.github.nickstruglia.keyfold/prebuilt/keyfold-viewer.html +++ b/packages/io.github.nickstruglia.keyfold/prebuilt/keyfold-viewer.html @@ -2,20 +2,20 @@ - + - + Keyfold offline viewer
- + yellow you young youth zebra zero zone zoo`.split(/\s+/),Lt=`Copyright (c) 2014-2024, The Monero Project +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be + used to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.`,Rt=`abbey abducts ability ablaze abnormal abort abrasive absorb + abyss academy aces aching acidic acoustic acquire across + actress acumen adapt addicted adept adhesive adjust adopt + adrenalin adult adventure aerial afar affair afield afloat + afoot afraid after against agenda aggravate agile aglow + agnostic agony agreed ahead aided ailments aimless airport + aisle ajar akin alarms album alchemy alerts algebra + alkaline alley almost aloof alpine already also altitude + alumni always amaze ambush amended amidst ammo amnesty + among amply amused anchor android anecdote angled ankle + annoyed answers antics anvil anxiety anybody apart apex + aphid aplomb apology apply apricot aptitude aquarium arbitrary + archer ardent arena argue arises army around arrow + arsenic artistic ascend ashtray aside asked asleep aspire + assorted asylum athlete atlas atom atrium attire auburn + auctions audio august aunt austere autumn avatar avidly + avoid awakened awesome awful awkward awning awoken axes + axis axle aztec azure baby bacon badge baffles + bagpipe bailed bakery balding bamboo banjo baptism basin + batch bawled bays because beer befit begun behind + being below bemused benches berries bested betting bevel + beware beyond bias bicycle bids bifocals biggest bikini + bimonthly binocular biology biplane birth biscuit bite biweekly + blender blip bluntly boat bobsled bodies bogeys boil + boldly bomb border boss both bounced bovine bowling + boxes boyfriend broken brunt bubble buckets budget buffet + bugs building bulb bumper bunch business butter buying + buzzer bygones byline bypass cabin cactus cadets cafe + cage cajun cake calamity camp candy casket catch + cause cavernous cease cedar ceiling cell cement cent + certain chlorine chrome cider cigar cinema circle cistern + citadel civilian claim click clue coal cobra cocoa + code coexist coffee cogs cohesive coils colony comb + cool copy corrode costume cottage cousin cowl criminal + cube cucumber cuddled cuffs cuisine cunning cupcake custom + cycling cylinder cynical dabbing dads daft dagger daily + damp dangerous dapper darted dash dating dauntless dawn + daytime dazed debut decay dedicated deepest deftly degrees + dehydrate deity dejected delayed demonstrate dented deodorant depth + desk devoid dewdrop dexterity dialect dice diet different + digit dilute dime dinner diode diplomat directed distance + ditch divers dizzy doctor dodge does dogs doing + dolphin domestic donuts doorway dormant dosage dotted double + dove down dozen dreams drinks drowning drunk drying + dual dubbed duckling dude duets duke dullness dummy + dunes duplex duration dusted duties dwarf dwelt dwindling + dying dynamite dyslexic each eagle earth easy eating + eavesdrop eccentric echo eclipse economics ecstatic eden edgy + edited educated eels efficient eggs egotistic eight either + eject elapse elbow eldest eleven elite elope else + eluded emails ember emerge emit emotion empty emulate + energy enforce enhanced enigma enjoy enlist enmity enough + enraged ensign entrance envy epoxy equip erase erected + erosion error eskimos espionage essential estate etched eternal + ethics etiquette evaluate evenings evicted evolved examine excess + exhale exit exotic exquisite extra exult fabrics factual + fading fainted faked fall family fancy farming fatal + faulty fawns faxed fazed feast february federal feel + feline females fences ferry festival fetches fever fewest + fiat fibula fictional fidget fierce fifteen fight films + firm fishing fitting five fixate fizzle fleet flippant + flying foamy focus foes foggy foiled folding fonts + foolish fossil fountain fowls foxes foyer framed friendly + frown fruit frying fudge fuel fugitive fully fuming + fungal furnished fuselage future fuzzy gables gadget gags + gained galaxy gambit gang gasp gather gauze gave + gawk gaze gearbox gecko geek gels gemstone general + geometry germs gesture getting geyser ghetto ghost giant + giddy gifts gigantic gills gimmick ginger girth giving + glass gleeful glide gnaw gnome goat goblet godfather + goes goggles going goldfish gone goodbye gopher gorilla + gossip gotten gourmet governing gown greater grunt guarded + guest guide gulp gumball guru gusts gutter guys + gymnast gypsy gyrate habitat hacksaw haggled hairy hamburger + happens hashing hatchet haunted having hawk haystack hazard + hectare hedgehog heels hefty height hemlock hence heron + hesitate hexagon hickory hiding highway hijack hiker hills + himself hinder hippo hire history hitched hive hoax + hobby hockey hoisting hold honked hookup hope hornet + hospital hotel hounded hover howls hubcaps huddle huge + hull humid hunter hurried husband huts hybrid hydrogen + hyper iceberg icing icon identity idiom idled idols + igloo ignore iguana illness imagine imbalance imitate impel + inactive inbound incur industrial inexact inflamed ingested initiate + injury inkling inline inmate innocent inorganic input inquest + inroads insult intended inundate invoke inwardly ionic irate + iris irony irritate island isolated issued italics itches + items itinerary itself ivory jabbed jackets jaded jagged + jailed jamming january jargon jaunt javelin jaws jazz + jeans jeers jellyfish jeopardy jerseys jester jetting jewels + jigsaw jingle jittery jive jobs jockey jogger joining + joking jolted jostle journal joyous jubilee judge juggled + juicy jukebox july jump junk jury justice juvenile + kangaroo karate keep kennel kept kernels kettle keyboard + kickoff kidneys king kiosk kisses kitchens kiwi knapsack + knee knife knowledge knuckle koala laboratory ladder lagoon + lair lakes lamb language laptop large last later + launching lava lawsuit layout lazy lectures ledge leech + left legion leisure lemon lending leopard lesson lettuce + lexicon liar library licks lids lied lifestyle light + likewise lilac limits linen lion lipstick liquid listen + lively loaded lobster locker lodge lofty logic loincloth + long looking lopped lordship losing lottery loudly love + lower loyal lucky luggage lukewarm lullaby lumber lunar + lurk lush luxury lymph lynx lyrics macro madness + magically mailed major makeup malady mammal maps masterful + match maul maverick maximum mayor maze meant mechanic + medicate meeting megabyte melting memoir menu merger mesh + metro mews mice midst mighty mime mirror misery + mittens mixture moat mobile mocked mohawk moisture molten + moment money moon mops morsel mostly motherly mouth + movement mowing much muddy muffin mugged mullet mumble + mundane muppet mural musical muzzle myriad mystery myth + nabbing nagged nail names nanny napkin narrate nasty + natural nautical navy nearby necklace needed negative neither + neon nephew nerves nestle network neutral never newt + nexus nibs niche niece nifty nightly nimbly nineteen + nirvana nitrogen nobody nocturnal nodes noises nomad noodles + northern nostril noted nouns novelty nowhere nozzle nuance + nucleus nudged nugget nuisance null number nuns nurse + nutshell nylon oaks oars oasis oatmeal obedient object + obliged obnoxious observant obtains obvious occur ocean october + odds odometer offend often oilfield ointment okay older + olive olympics omega omission omnibus onboard oncoming oneself + ongoing onion online onslaught onto onward oozed opacity + opened opposite optical opus orange orbit orchid orders + organs origin ornament orphans oscar ostrich otherwise otter + ouch ought ounce ourselves oust outbreak oval oven + owed owls owner oxidant oxygen oyster ozone pact + paddles pager pairing palace pamphlet pancakes paper paradise + pastry patio pause pavements pawnshop payment peaches pebbles + peculiar pedantic peeled pegs pelican pencil people pepper + perfect pests petals phase pheasants phone phrases physics + piano picked pierce pigment piloted pimple pinched pioneer + pipeline pirate pistons pitched pivot pixels pizza playful + pledge pliers plotting plus plywood poaching pockets podcast + poetry point poker polar ponies pool popular portents + possible potato pouch poverty powder pram present pride + problems pruned prying psychic public puck puddle puffin + pulp pumpkins punch puppy purged push putty puzzled + pylons pyramid python queen quick quote rabbits racetrack + radar rafts rage railway raking rally ramped randomly + rapid rarest rash rated ravine rays razor react + rebel recipe reduce reef refer regular reheat reinvest + rejoices rekindle relic remedy renting reorder repent request + reruns rest return reunion revamp rewind rhino rhythm + ribbon richly ridges rift rigid rims ringing riots + ripped rising ritual river roared robot rockets rodent + rogue roles romance roomy roped roster rotate rounded + rover rowboat royal ruby rudely ruffled rugged ruined + ruling rumble runway rural rustled ruthless sabotage sack + sadness safety saga sailor sake salads sample sanity + sapling sarcasm sash satin saucepan saved sawmill saxophone + sayings scamper scenic school science scoop scrub scuba + seasons second sedan seeded segments seismic selfish semifinal + sensible september sequence serving session setup seventh sewage + shackles shelter shipped shocking shrugged shuffled shyness siblings + sickness sidekick sieve sifting sighting silk simplest sincerely + sipped siren situated sixteen sizes skater skew skirting + skulls skydive slackens sleepless slid slower slug smash + smelting smidgen smog smuggled snake sneeze sniff snout + snug soapy sober soccer soda software soggy soil + solved somewhere sonic soothe soprano sorry southern sovereign + sowed soya space speedy sphere spiders splendid spout + sprig spud spying square stacking stellar stick stockpile + strained stunning stylishly subtly succeed suddenly suede suffice + sugar suitcase sulking summon sunken superior surfer sushi + suture swagger swept swiftly sword swung syllabus symptoms + syndrome syringe system taboo tacit tadpoles tagged tail + taken talent tamper tanks tapestry tarnished tasked tattoo + taunts tavern tawny taxi teardrop technical tedious teeming + tell template tender tepid tequila terminal testing tether + textbook thaw theatrics thirsty thorn threaten thumbs thwart + ticket tidy tiers tiger tilt timber tinted tipsy + tirade tissue titans toaster tobacco today toenail toffee + together toilet token tolerant tomorrow tonic toolbox topic + torch tossed total touchy towel toxic toyed trash + trendy tribal trolling truth trying tsunami tubes tucks + tudor tuesday tufts tugs tuition tulips tumbling tunnel + turnip tusks tutor tuxedo twang tweezers twice twofold + tycoon typist tyrant ugly ulcers ultimate umbrella umpire + unafraid unbending uncle under uneven unfit ungainly unhappy + union unjustly unknown unlikely unmask unnoticed unopened unplugs + unquoted unrest unsafe until unusual unveil unwind unzip + upbeat upcoming update upgrade uphill upkeep upload upon + upper upright upstairs uptight upwards urban urchins urgent + usage useful usher using usual utensils utility utmost + utopia uttered vacation vague vain value vampire vane + vapidly vary vastness vats vaults vector veered vegan + vehicle vein velvet venomous verification vessel veteran vexed + vials vibrate victim video viewpoint vigilant viking village + vinegar violin vipers virtual visited vitals vivid vixen + vocal vogue voice volcano vortex voted voucher vowels + voyage vulture wade waffle wagtail waist waking wallets + wanted warped washing water waveform waxing wayside weavers + website wedge weekday weird welders went wept were + western wetsuit whale when whipped whole wickets width + wield wife wiggle wildly winter wipeout wiring wise + withdrawn wives wizard wobbly woes woken wolf womanly + wonders woozy worry wounded woven wrap wrist wrong + yacht yahoo yanks yard yawning yearbook yellow yesterday + yeti yields yodel yoga younger yoyo zapped zeal + zebra zero zesty zigzags zinger zippers zodiac zombie + zones zoom`.split(/\s+/),zt=[{id:`bip39`,label:`BIP39 (English)`,counts:[12,15,18,21,24]},{id:`electrum`,label:`Electrum`,counts:[12]},{id:`aezeed`,label:`Aezeed (LND)`,counts:[24]},{id:`slip39`,label:`SLIP-39 share (Shamir)`,counts:[20,33]},{id:`monero`,label:`Monero`,counts:[25,13,16]},{id:`other`,label:`Other`,counts:[]}],Bt=[12,13,15,16,18,20,21,24,25,33],Vt=e=>e===`bip39`||e===`electrum`||e===`aezeed`,Ht=new Map(It.map((e,t)=>[e,t])),Ut=e=>e.normalize(`NFKD`).trim().toLowerCase(),Wt=e=>e.normalize(`NFC`).trim().toLowerCase(),Gt=e=>Ht.has(Ut(e)),Kt=/[\u200B-\u200D\u2060\uFEFF]/g,qt=/[\p{L}\p{M}\p{N}]/u,Jt=e=>{let t=[...e],n=0,r=t.length;for(;nn&&!qt.test(t[r-1]);)r--;return t.slice(n,r).join(``)},Yt=e=>{let t=e.replace(Kt,` `).replace(/(?{if(/^\p{L}[.)]$/u.test(e))return[];let t=Jt(e);return t?/^\d+$/.test(t)?[{n:Number(t)}]:/\p{L}/u.test(t)?[{word:Wt(t)}]:[]:[]}),n=t.flatMap((e,t)=>`n`in e?[t]:[]),r=n.map(e=>t[e-1]);if(n.length>1&&r.every(e=>e&&`word`in e&&e.word===r[0].word))for(let e of n.reverse())t.splice(e-1,1);let i=[],a=[],o=null,s=!0;for(let e of t)`n`in e?o=e.n:(a.push(e.word),o===null?s=!1:i.push({n:o,word:e.word}),o=null);if(s&&a.length>1){let e=[...i].sort((e,t)=>e.n-t.n);if(e.every((t,n)=>t.n===e[0].n+n)&&e[0].n>=1)return{words:e.map(e=>e.word),firstNumber:e[0].n,reordered:e.some((e,t)=>e!==i[t])}}return{words:a,reordered:!1}},Xt=e=>Yt(e).words,Zt=e=>{let t=Ut(e);if(t.length<4||Ht.has(t))return Wt(e);let n=It.filter(e=>e.startsWith(t));return n.length===1?n[0]:Wt(e)},Qt=(e,t)=>{let n=Array.from({length:t.length+1},(e,t)=>t);for(let r=1;r<=e.length;r++){let i=n[0];n[0]=r;for(let a=1;a<=t.length;a++){let o=n[a];n[a]=Math.min(n[a]+1,n[a-1]+1,i+(e[r-1]===t[a-1]?0:1)),i=o}}return n[t.length]},$t=(e,t=3)=>{let n=Ut(e);if(!n||n.length>10)return[];let r=It.filter(e=>e.startsWith(n.slice(0,4)));return r.length>0&&r.length<=t?r:It.map(e=>[e,Qt(n,e)]).filter(([,e])=>e<=2).sort((e,t)=>e[1]-t[1]).slice(0,t).map(([e])=>e)},en=async e=>{let t=e.length*11,n=t/33,r=t-n,i=e.map(e=>e.toString(2).padStart(11,`0`)).join(``),a=new Uint8Array(r/8);for(let e=0;ee.toString(2).padStart(8,`0`)).join(``);return i.slice(r)===s.slice(0,n)},tn=[[`01`,`standard`],[`100`,`segwit`],[`101`,`2fa`],[`102`,`2fa-segwit`]],nn=async e=>{let t=e.map(e=>Ut(e).replace(/[̀-ͯ]/g,``)).join(` `),n=ze(await Ge(G(`Seed version`),G(t)));return tn.find(([e])=>n.startsWith(e))?.[1]??null},rn=async(e,t)=>{let n=t.map(Ut),r=n.filter(Boolean).length,i=Vt(e)?n.flatMap((e,t)=>e&&!Ht.has(e)?[t]:[]):[];if(r===0)return{status:`incomplete`,message:`No words entered yet.`,unknownWords:i};if(r0)return{status:`invalid`,message:`Not in the English BIP39 wordlist: ${i.map(e=>`#${e+1}`).join(`, `)}. For other languages or old Electrum seeds, choose Other.`,unknownWords:i};if(!Ue()&&(e===`bip39`||e===`electrum`))return{status:`unchecked`,message:`Checksum check needs a secure (https) context.`,unknownWords:i};switch(e){case`bip39`:{if(![12,15,18,21,24].includes(n.length))return{status:`invalid`,message:`BIP39 phrases have 12, 15, 18, 21 or 24 words (this has ${n.length}).`,unknownWords:i};if(await en(n.map(e=>Ht.get(e))))return{status:`valid`,message:`Valid BIP39 checksum (${n.length} words).`,unknownWords:i};let e=n.length===12?await nn(n):null,t=n.length===24&&cn(n.map(e=>Ht.get(e)))===`valid`;return{status:`invalid`,message:e?`BIP39 checksum mismatch. The words do pass Electrum's check (${e} seed): if this seed came from Electrum, choose the Electrum scheme; otherwise check every word.`:t?`Not a BIP39 phrase, but these words are a valid aezeed seed. Choose the Aezeed (LND) scheme.`:`Checksum mismatch. Check the spelling and order of every word.`,unknownWords:i}}case`electrum`:{let e=await nn(n);return e?{status:`valid`,message:`Valid Electrum seed (${e}).`,unknownWords:i}:{status:`invalid`,message:`Not a valid Electrum 2.0+ seed. Check the words, or pick another scheme.`,unknownWords:i}}case`monero`:{if(n.length!==25&&n.length!==13)break;if(n.filter(e=>dn.has(e)).lengthfn.has(un(e))?[]:[t]);return e.length>0?{status:`invalid`,message:`Not in the Monero English wordlist: ${e.map(e=>`#${e+1}`).join(`, `)}.`,unknownWords:e}:pn(n)?{status:`valid`,message:`Monero checksum word OK (English, ${n.length} words).`,unknownWords:i}:{status:`invalid`,message:`The last word does not match the Monero checksum. Check the spelling and order of every word.`,unknownWords:i}}case`aezeed`:{if(n.length!==24)return{status:`invalid`,message:`Aezeed seeds have 24 words (this has ${n.length}).`,unknownWords:i};let e=n.map(e=>Ht.get(e)),t=cn(e);return t===`valid`?{status:`valid`,message:`Valid aezeed checksum. A seed password, if it has one, is not checked.`,unknownWords:i}:{status:`invalid`,message:t===`version`&&Ue()&&await en(e)?`Not an aezeed seed, but these words pass the BIP39 checksum. Choose the BIP39 scheme.`:t===`version`?`The first word does not match a known aezeed version. Check it, or pick another scheme.`:`Checksum mismatch. Check the spelling and order of every word.`,unknownWords:i}}}return{status:`unchecked`,message:`${n.length} words. Checksums for this scheme are not checked here.`,unknownWords:i}},an=3988292384,on=2197175160,sn=(e,t=an)=>{let n=4294967295;for(let r of e){let e=(n^r)&255;for(let n=0;n<8;n++)e=e&1?e>>>1^t:e>>>1;n=n>>>8^e}return(n^4294967295)>>>0},cn=e=>{let t=new Uint8Array(33),n=0,r=0,i=0;for(let a of e){for(n=n<<11|a,r+=11;r>=8;)r-=8,t[i++]=n>>>r&255;n&=(1<[...e].slice(0,ln).join(``),dn=new Set(Rt),fn=new Set(Rt.map(un)),pn=e=>{let t=e.slice(0,-1),n=e[e.length-1];return un(t[sn(G(t.map(un).join(``)))%t.length])===un(n)},mn=({words:e,scheme:t,unknownWords:n,onChange:r})=>{let{readOnly:i,copy:a,settings:o}=Z(),[s,c]=jt(e),[l,u]=z(null),[d,f]=z(null),[p,m]=z(``),h=V([]),g=V(new WeakSet),_=Vt(t),v=!Mt();B(()=>{if(d===null||!o.autoHideSeconds)return;let e=setTimeout(()=>f(null),o.autoHideSeconds*1e3);return()=>clearTimeout(e)},[d,e,o.autoHideSeconds]);let y=(t,n)=>{let i=[...e];i[t]=n,r(i)},b=(t,n)=>{let i=Math.min(48,Math.max(e.length,t+n.length)),a=Array.from({length:i},(t,n)=>e[n]??``);n.slice(0,i-t).forEach((e,n)=>a[t+n]=e),r(a),h.current[Math.min(t+n.length,i-1)]?.focus()},x=(e,t)=>{let n=Yt(t.clipboardData?.getData(`text`)??``);if(n.words.length<2)return;t.preventDefault();let r=n.firstNumber!==void 0&&n.firstNumber-1<48?n.firstNumber-1:e;b(r,n.words),m(n.reordered?`Placed the pasted words by their numbers. Check the order.`:``)},S=(e,t)=>{let n=t.currentTarget,r=n.value;t.isComposing?y(e,r):C(e,n)},C=(e,t)=>{let n=t.value;if(!/\s/.test(n)){let r=n.toLowerCase();if(r!==n){let[e,n]=[t.selectionStart,t.selectionEnd];t.value=r,e!==null&&n!==null&&t.setSelectionRange(e,n)}y(e,r);return}let r=Xt(n);r.length>1?b(e,r):(y(e,r[0]??``),r.length===1&&h.current[e+1]?.focus())},w=(t,n)=>{n.isComposing||n.keyCode===229||(n.key===` `||n.key===`Enter`?(n.preventDefault(),h.current[t+1]?.focus()):n.key===`Backspace`&&!e[t]&&t>0?(n.preventDefault(),h.current[t-1]?.focus()):v&&(n.key.length===1||n.key===`Backspace`)&&!n.ctrlKey&&!n.metaKey&&f(t))},T=()=>{u(null),f(null)},E=(e,t)=>{y(e,t),h.current[e]?.focus()},D=_?n.map(t=>[t,Zt(e[t]??``)]).filter(([t,n])=>n!==e[t]&&Gt(n)):[],O=D.length>0&&D.length===n.length,ee=()=>{let t=[...e];for(let[e,n]of D)t[e]=n;r(t)},te=e.filter(Boolean),k=e=>s||v&&d===e,ne=l!==null&&n.includes(l)&&e[l],re=_&&ne&&k(l)?$t(e[l]):[];return H(`div`,{class:`word-grid-wrap`,children:[H(`div`,{class:`word-toolbar`,children:[H(`button`,{type:`button`,class:`button small`,onClick:()=>c(!s),children:[H(U,{name:s?`eyeOff`:`eye`}),` `,s?`Hide words`:`Reveal words`]}),H(`button`,{type:`button`,class:`button small`,disabled:te.length===0,onClick:()=>a(te.join(` `),te.length===e.length?`Seed phrase`:`Seed phrase (only ${te.length} of ${e.length} words)`),children:[H(U,{name:`copy`}),` Copy phrase`]}),H(`span`,{class:`muted small helper`,children:[`Tip: paste a whole phrase into word 1.`,Mt()?` Phrases in other scripts (Japanese, Chinese…) can only be pasted on phones.`:``]})]}),H(`ol`,{class:`word-grid`,"aria-label":`Seed words`,children:e.map((t,r)=>{let a=k(r),o=n.includes(r)&&l!==r;return H(`li`,{class:`word ${o?`word-invalid`:``}`,children:[H(`span`,{class:`word-index`,"aria-hidden":`true`,children:r+1}),H(`input`,{ref:e=>{e&&!g.current.has(e)&&(g.current.add(e),e.type===`text`&&(e.type=`password`,e.type=`text`)),h.current[r]=e},class:`input mono`,...a?{type:`text`,list:_?`bip39-words`:void 0}:{type:`password`},value:t,"aria-label":`Word ${r+1}`,"aria-invalid":o,enterkeyhint:r===e.length-1?`done`:`next`,readOnly:i,onInput:e=>S(r,e),onPaste:e=>x(r,e),onKeyDown:e=>w(r,e),onFocus:()=>u(r),onBlur:T,oncompositionend:e=>C(r,e.currentTarget),...Nt})]},r)})}),re.length>0&&H(`p`,{class:`hint`,role:`status`,children:[`Not in the wordlist. Did you mean:`,` `,re.map(e=>H(`button`,{type:`button`,class:`link-button`,onMouseDown:e=>e.preventDefault(),onClick:()=>E(l,e),children:e},e)),`?`]}),O&&!i&&H(`p`,{class:`hint`,children:[H(`button`,{type:`button`,class:`button small`,onClick:ee,children:`Expand abbreviated words`}),` `,H(`span`,{class:`muted small`,children:`Only for English BIP39 phrases.`})]}),p&&H(`p`,{class:`hint`,role:`status`,children:p})]})},hn=Object.fromEntries(Object.entries(J).map(([e,t])=>[e,t.label])),gn={mnemonic:`Seed phrases`,privateKey:`Wallet keys`,sshKey:`SSH keys`,pgpKey:`PGP keys`,apiKey:`API keys and tokens`,genericKey:`Other keys`,recoveryCodes:`Recovery codes`,other:`Other secrets`},_n={mnemonic:`seed`,privateKey:`wallet`,sshKey:`terminal`,pgpKey:`mail`,apiKey:`code`,genericKey:`key`,recoveryCodes:`list`,other:`lock`},vn=[[`none`,`No grouping`],[`kind`,`Type`],[`chain`,`Chain or service`],[`wallet`,`Wallet or account`],[`tag`,`First tag`]],yn=e=>`Untitled ${/^[A-Z][A-Z]/.test(e)?e:e.toLowerCase()}`,bn=e=>{let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleDateString(void 0,{year:`numeric`,month:`long`,day:`numeric`})},xn=new Map([...`123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`].map((e,t)=>[e,BigInt(t)])),Sn=e=>{let t=0n;for(let n of e){let e=xn.get(n);if(e===void 0)return null;t=t*58n+e}let n=[];for(;t>0n;)n.unshift(Number(t%256n)),t/=256n;let r=0;for(;r{let t=Sn(e);if(!t||t.length<5)return null;let n=t.slice(0,-4);return Ke((await We(await We(n))).slice(0,4),t.slice(-4))?n:null},wn=`qpzry9x8gf2tvdw0s3jn54khce6mua7l`,Tn=1,En=734539939,Dn=e=>{let t=[996825010,642813549,513874426,1027748829,705979059],n=1;for(let r of e){let e=n>>>25;n=(n&33554431)<<5^r;for(let r=0;r<5;r++)e>>>r&1&&(n^=t[r])}return n>>>0},On=e=>[...[...e].map(e=>e.charCodeAt(0)>>5),0,...[...e].map(e=>e.charCodeAt(0)&31)],kn=/^(nsec|npub|bc|tb|ltc|age|age-secret-key-)$|_x?[sv]k$|xprv|xpub|^addr|^stake/,An=e=>{if(e!==e.toLowerCase()&&e!==e.toUpperCase())return null;let t=e.toLowerCase(),n=t.lastIndexOf(`1`);if(n<1||n+7>t.length)return null;let r=t.slice(0,n),i=[];for(let e of t.slice(n+1)){let t=wn.indexOf(e);if(t===-1)return null;i.push(t)}let a=Dn([...On(r),...i]),o=a===Tn?`bech32`:a===En?`bech32m`:null;return o?{hrp:r,variant:o,words:i.slice(0,-6)}:null},jn=e=>{let t=0,n=0,r=[];for(let i of e)for(t=t<<5|i,n+=5;n>=8;)n-=8,r.push(t>>n&255);return n>=5||t&(1<Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``),Fn=e=>{let t;try{t=JSON.parse(e)}catch{return null}if(Array.isArray(t)&&t.length===0)return{level:`info`,label:`Empty list`};if(Array.isArray(t)&&t.every(e=>Number.isInteger(e)&&e>=0&&e<=255))return t.length===64?{level:`ok`,label:`Byte array, 64 bytes`,detail:`Solana CLI keypair file format.`}:{level:`info`,label:`Byte array, ${t.length} bytes`};if(t&&typeof t==`object`){let e=t;if(e.crypto&&Number(e.version)===4&&typeof e.pubkey==`string`)return{level:`ok`,label:`Encrypted keystore (EIP-2335, Ethereum validator)`,detail:`Store its password in the keystore password field.`};if((e.crypto||e.Crypto)&&Number(e.version)===3)return{level:`ok`,label:`Encrypted keystore (Web3 Secret Storage v3)`,detail:`Store its password in the keystore password field.`};if(e.type===`service_account`&&typeof e.private_key==`string`)return{level:`ok`,label:`Google Cloud service account key`,detail:`JSON key file with a private key.`};let n=Array.isArray(e.keys)?e.keys.filter(e=>e&&typeof e==`object`):[e],r=n.find(e=>`d`in e||`k`in e)??n[0];return r&&typeof r.kty==`string`?`d`in r||`k`in r?{level:`ok`,label:`JSON Web Key (${r.kty}, private)`}:{level:`warn`,label:`JSON Web Key (${r.kty}, public)`,detail:Q}:{level:`info`,label:`JSON document`}}return null},In={"ssh-ed25519":`Ed25519`,"ssh-rsa":`RSA`,"ssh-dss":`DSA`,"ecdsa-sha2-nistp256":`ECDSA P-256`,"ecdsa-sha2-nistp384":`ECDSA P-384`,"ecdsa-sha2-nistp521":`ECDSA P-521`,"sk-ssh-ed25519@openssh.com":`Ed25519 security key`,"sk-ecdsa-sha2-nistp256@openssh.com":`ECDSA security key`},Ln=e=>{let t;try{t=He(e.replace(/\s+/g,``))}catch{return null}if(Re(t.slice(0,15))!==`openssh-key-v1\0`)return null;let n=15,r=new DataView(t.buffer,t.byteOffset,t.byteLength),i=()=>{if(n+4>t.length)throw Error(`truncated`);let e=r.getUint32(n);if(n+=4,n+e>t.length)throw Error(`truncated`);let i=t.slice(n,n+e);return n+=e,i};try{let e=Re(i());i(),i(),n+=4;let t=i(),r=i(),a=new DataView(t.buffer,t.byteOffset).getUint32(0),o=Re(t.slice(4,4+a)),s=e!==`none`;if(!s){let e=new DataView(r.buffer,r.byteOffset,r.byteLength);if(r.length<8||e.getUint32(0)!==e.getUint32(4))return null}return{keyType:o,encrypted:s}}catch{return null}},Rn=e=>{let t=11994318;for(let n of e){t^=n<<16;for(let e=0;e<8;e++)t<<=1,t&16777216&&(t^=25578747)}return t&16777215},zn=e=>{let t=e.split(/\r?\n/).map(e=>e.trim()),n=t.indexOf(``),r=t.slice(n===-1?1:n+1).filter(e=>e&&!e.startsWith(`-----`)),i=r.findIndex(e=>/^=[A-Za-z0-9+/]{4}$/.test(e));if(i===-1)return null;try{let e=He(r.slice(0,i).join(``)),t=He(r[i].slice(1));return Rn(e)===(t[0]<<16|t[1]<<8|t[2])}catch{return!1}},Bn={"PUBLIC KEY":`PEM public key`,"RSA PUBLIC KEY":`PEM RSA public key`,CERTIFICATE:`Certificate`,"PGP PUBLIC KEY BLOCK":`PGP public key block`},Vn={"PGP MESSAGE":`PGP message`,"PGP SIGNATURE":`PGP signature`,"PGP SIGNED MESSAGE":`PGP signed message`},Hn=e=>{if(e.includes(`:`))return null;let t;try{t=He(e.replace(/\s+/g,``))}catch{return!1}if(t.length<2||t[0]!==48)return!1;let n=t[1],r=2;if(n&128){let e=n&127;if(e<1||e>4||t.length<2+e)return!1;n=0;for(let r=0;r{let r=/Proc-Type:\s*4,ENCRYPTED/i.test(t);if(Vn[e])return{level:`warn`,label:Vn[e],detail:`This is not a key.`};if(Bn[e])return{level:`warn`,label:Bn[e],detail:Q};if(/PRIVATE KEY$/.test(e)&&e!==`OPENSSH PRIVATE KEY`&&Hn(t)===!1)return{level:`error`,label:`Private key block is damaged or incomplete`,detail:`A line may be missing or changed.`};switch(e){case`OPENSSH PRIVATE KEY`:{let e=Ln(t);return e?{level:`ok`,label:`OpenSSH private key (${In[e.keyType]??e.keyType})`,detail:e.encrypted?`Protected by a passphrase.`:`Not passphrase-protected.`}:{level:`error`,label:`OpenSSH private key, but it could not be read`,detail:`Check that it was copied completely.`}}case`PGP PRIVATE KEY BLOCK`:{let e=zn(n);return e===!1?{level:`error`,label:`PGP private key, but the checksum fails`,detail:`Check for a typo or missing line.`}:{level:`ok`,label:`PGP private key block`,detail:e?`Checksum OK.`:void 0}}case`RSA PRIVATE KEY`:return{level:`ok`,label:`PEM RSA private key (PKCS#1)`,detail:r?`Protected by a passphrase.`:void 0};case`EC PRIVATE KEY`:return{level:`ok`,label:`PEM EC private key (SEC1)`,detail:r?`Protected by a passphrase.`:void 0};case`DSA PRIVATE KEY`:return{level:`ok`,label:`PEM DSA private key`,detail:r?`Protected by a passphrase.`:void 0};case`PRIVATE KEY`:return{level:`ok`,label:`PEM private key (PKCS#8)`};case`ENCRYPTED PRIVATE KEY`:return{level:`ok`,label:`PEM private key (PKCS#8)`,detail:`Protected by a passphrase.`};default:return{level:`info`,label:`PEM block (${e.toLowerCase()})`}}},Wn=e=>/PRIVATE KEY/.test(e),Gn=e=>{let t=[...e.matchAll(/-----BEGIN ([A-Z0-9 ]+)-----([\s\S]*?)-----END \1-----/g)],n=(e.match(/-----BEGIN [A-Z0-9 ]+-----/g)??[]).length,r={level:`error`,label:`Key block is incomplete`,detail:`The matching -----END ...----- line is missing.`},i=t.find(e=>Wn(e[1]));if(i)return Un(i[1],i[2],i[0]);let a=/-----BEGIN (PGP MESSAGE|PGP SIGNATURE|PGP SIGNED MESSAGE)-----/.exec(e);if(a)return{level:`warn`,label:Vn[a[1]],detail:`This is not a key.`};if(n>t.length)return r;if(!t.length)return null;let o=t.map(e=>Un(e[1],e[2],e[0]));return o.find(e=>e.level===`warn`)??o[0]},Kn=[{pattern:/^gh[pousr]_[A-Za-z0-9]{36,}$/,label:`GitHub token`},{pattern:/^github_pat_\w{50,}$/,label:`GitHub fine-grained token`},{pattern:/^glpat-[\w-]{20,}$/,label:`GitLab access token`},{pattern:/^npm_[A-Za-z0-9]{36}$/,label:`npm access token`},{pattern:/^(sk|rk)_(live|test)_[A-Za-z0-9]{16,}$/,label:`Stripe secret key`},{pattern:/^pk_(live|test)_[A-Za-z0-9]{16,}$/,label:`Stripe publishable key`,level:`warn`,detail:Q},{pattern:/^xox[abposr]-[A-Za-z0-9-]{10,}$/,label:`Slack token`},{pattern:/^AIza[\w-]{35}$/,label:`Google API key`},{pattern:/^(AKIA|ASIA)[0-9A-Z]{16}$/,label:`AWS access key ID`,level:`info`,detail:`The 40-character secret access key is a separate value; store it as well.`},{pattern:/^SG\.[\w-]{22}\.[\w-]{43}$/,label:`SendGrid API key`},{pattern:/^dop_v1_[a-f0-9]{64}$/,label:`DigitalOcean token`},{pattern:/^sk-[\w-]{20,}$/,label:`API secret key (sk-…)`},{pattern:/^eyJ[\w-]+\.eyJ[\w-]+\.[\w-]*$/,label:`JSON Web Token`,level:`info`,detail:`Tokens like this usually expire.`}],qn=async e=>{let t=e.trim();if(!t)return null;if(/^\[[\w .-]+\][ \t]*\r?$/.test(t.split(` +`)[0])&&/^[ \t]*[\w.-]+[ \t]*=/m.test(t))return/aws_secret_access_key\s*=/i.test(t)?{level:`ok`,label:`AWS credentials file`,detail:`Contains a secret access key.`}:{level:`info`,label:`Settings file (INI)`};let n=/^\[([0-9a-fA-F]{8}(?:\/\d+['hH]?)*)\]\s*(?=\S)/.exec(t);if(n){let e=await qn(t.slice(n[0].length));if(e)return{...e,detail:[e.detail,`Key origin [${n[1]}].`].filter(Boolean).join(` `)}}if(t.startsWith(`{`)||t.startsWith(`[`))return Fn(t)??{level:`warn`,label:`Looks like JSON, but it does not parse.`};let r=/^AGE-SECRET-KEY-1[0-9A-Z]+$/m.exec(t);if(r&&t.includes(` +`))return qn(r[0]);if(/^---- BEGIN SSH2 PUBLIC KEY ----/m.test(t))return{level:`warn`,label:`SSH public key (SSH2 format)`,detail:Q};let i=Gn(t);if(i)return i;let a=/^PuTTY-User-Key-File-\d+:\s*(\S+)/.exec(t);if(a){let e=/^Private-Lines:\s*(\d+)\s*$/m.exec(t);if(e&&(t.slice(e.index+e[0].length).split(` +`).map(e=>e.trim()).filter(e=>e&&!/^Private-MAC:/.test(e)).filter(e=>/^[A-Za-z0-9+/=]+$/.test(e)).lengthe.pattern.test(t));if(s)return{level:s.level??`ok`,label:s.label,detail:s.detail};let c=Xt(t);if(c.length>=12&&c.length<=48&&c.every(Gt))return{level:`warn`,label:`Looks like a ${c.length}-word seed phrase`,detail:`Use a "Seed phrase" entry to get word-by-word checks.`};if(/^(0x)?[0-9a-fA-F]+$/i.test(t)&&t.replace(/^0x/i,``).length%2==0){let e=Be(t.replace(/^0X/,`0x`)),n=/^0x/i.test(t);return e.length===32?{level:`ok`,label:`Hex, 32 bytes${n?` (0x-prefixed)`:``}`,detail:`Raw 256-bit private key (Ethereum/EVM, Bitcoin, Cosmos and others).`}:e.length===20?{level:`warn`,label:`Hex, 20 bytes`,detail:Q+` (EVM address length)`}:e.length===33||e.length===65?{level:`warn`,label:`Hex, ${e.length} bytes`,detail:Q+` (public key length)`}:{level:`info`,label:`Hex, ${e.length} bytes`}}let l=An(t);if(l){let e=l.variant===`bech32`?jn(l.words):null;switch(l.hrp){case`age-secret-key-`:return e?.length===32?{level:`ok`,label:`age secret key`,detail:`Checksum OK.`}:{level:`error`,label:`age secret key with unexpected length`,detail:`Check that it was copied completely.`};case`age`:return{level:`warn`,label:`age recipient (public key)`,detail:Q};case`nsec`:return e?.length===32?{level:`ok`,label:`Nostr private key (nsec)`,detail:`Checksum OK.`}:{level:`error`,label:`nsec with unexpected length`};case`npub`:return{level:`warn`,label:`Nostr public key (npub)`,detail:Q};case`bc`:case`tb`:case`ltc`:return{level:`warn`,label:`Address (bech32)`,detail:Q};default:return/_x?sk$/.test(l.hrp)||l.hrp.includes(`xprv`)?{level:`ok`,label:`Bech32 secret key (${l.hrp})`,detail:`Checksum OK.`}:/_x?vk$/.test(l.hrp)||l.hrp.includes(`xpub`)||l.hrp.startsWith(`addr`)||l.hrp.startsWith(`stake`)?{level:`warn`,label:`Bech32 (${l.hrp})`,detail:Q}:{level:`info`,label:`Bech32 data (${l.hrp})`,detail:`Checksum OK.`}}}{let e=t.toLowerCase(),n=/^([a-z0-9_-]+)1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]{6,}$/.exec(e);if(n&&(t===e||t===t.toUpperCase())&&kn.test(n[1]))return{level:`error`,label:`Bech32 checksum fails`,detail:`Check for a typo.`}}if(/^[A-Za-z0-9+/]+={0,2}$/.test(t)&&t.length%4==0&&/[+/=]/.test(t))try{let e=He(t);return e.length===32?{level:`ok`,label:`Base64, 32 bytes`,detail:`The format of WireGuard keys and many other 256-bit keys.`}:{level:`info`,label:`Base64, ${e.length} bytes`}}catch{}if(t.length<=200&&/^[1-9A-HJ-NP-Za-km-z]+$/.test(t)){if(Ue()){let e=await Cn(t);if(e){if(e.length===78){let t=Mn[Pn(e.slice(0,4))];return t?t.private?{level:`ok`,label:`Extended private key (${t.name})`,detail:`${t.note}. Checksum OK.`}:{level:`warn`,label:`Extended public key (${t.name})`,detail:Q}:{level:`info`,label:`Extended key (unknown version)`,detail:`Checksum OK.`}}let t=Nn[e[0]];return t&&(e.length===33||e.length===34&&e[33]===1)?{level:`ok`,label:`WIF private key (${t}, ${e.length===34?`compressed`:`uncompressed`})`,detail:`Checksum OK.`}:e.length===21?{level:`warn`,label:`Address (Base58Check)`,detail:Q}:{level:`info`,label:`Base58Check, ${e.length} bytes`,detail:`Checksum OK.`}}let n=Sn(t);if(n&&(n.length===37||n.length===38)&&Nn[n[0]])return{level:`error`,label:`Looks like WIF, but the checksum fails`,detail:`Check for a typo.`};if(/^(?:[xyztuvYZUV](?:prv|pub)|[LM]t(?:pv|ub)|dg(?:pv|ub))/.test(t)){if(t.length===111)return{level:`error`,label:`Looks like an extended key, but the checksum fails`,detail:`Check for a typo.`};if(t.length===110||t.length===112)return{level:`error`,label:`Looks like an extended key, but a character may be missing or extra`,detail:`Extended keys are 111 characters.`}}}let e=Sn(t);if(e?.length===64)return{level:`ok`,label:`Base58, 64 bytes`,detail:`Solana-style keypair (Phantom/Solflare export).`};if(e?.length===32)return{level:`info`,label:`Base58, 32 bytes`,detail:`Could be an ed25519 secret seed, or a Solana address.`};if(e)return{level:`info`,label:`Base58, ${e.length} bytes`}}return{level:`info`,label:`Unrecognized format`,detail:`Stored as typed.`}},Jn=async e=>{let t=e.trim();if(!t)return null;if(/-----BEGIN [A-Z0-9 ]*PRIVATE KEY[A-Z0-9 ]*-----/.test(t))return`a private key block`;let n=t.split(/[\s,;()[\]]+/).map(e=>e.split(`/`)[0]).filter(e=>e.length>=40);for(let e of[t,...n]){let t=await qn(e);if(t?.level===`ok`&&!/^(Hex|Base64)/.test(t.label))return t.label}return null},Yn=`Bitcoin.Ethereum.Solana.Cardano.Monero.Litecoin.Dogecoin.Polkadot.Cosmos.Avalanche.Polygon.BNB Chain.Arbitrum.Base.Optimism.Tron.XRP Ledger.Tezos.Algorand.Stellar.Near.Sui.Aptos.Lightning (LND).Nostr.Multi-chain`.split(`.`),Xn=[`Ledger`,`Trezor`,`Coldcard`,`BitBox02`,`Keystone`,`Blockstream Jade`,`Foundation Passport`,`Sparrow`,`Electrum`,`Nunchuk`,`BlueWallet`,`Phoenix`,`MetaMask`,`Rabby`,`Rainbow`,`Phantom`,`Solflare`,`Exodus`,`Trust Wallet`,`Coinbase Wallet`,`Cake Wallet`,`Feather`,`Monero GUI`],Zn=[`GitHub`,`GitLab`,`Bitbucket`,`AWS`,`Google Cloud`,`Azure`,`Cloudflare`,`DigitalOcean`,`Vercel`,`Stripe`,`Slack`,`npm`,`Docker Hub`,`Apple ID`,`Google account`,`Microsoft account`,`Proton`,`Standard Notes`,`Coinbase`,`Kraken`,`Binance`,`Gemini`,`Bitstamp`],Qn=[[`m/44'/0'/0'`,`BTC legacy (BIP44)`],[`m/49'/0'/0'`,`BTC nested SegWit (BIP49)`],[`m/84'/0'/0'`,`BTC native SegWit (BIP84)`],[`m/86'/0'/0'`,`BTC Taproot (BIP86)`],[`m/48'/0'/0'/2'`,`BTC multisig (BIP48)`],[`m/44'/60'/0'/0/0`,`Ethereum / EVM`],[`m/44'/501'/0'/0'`,`Solana`],[`m/1852'/1815'/0'`,`Cardano`],[`m/44'/118'/0'/0/0`,`Cosmos`]],$n=()=>H(C,{children:[H(`datalist`,{id:`chains`,children:Yn.map(e=>H(`option`,{value:e}))}),H(`datalist`,{id:`wallets`,children:Xn.map(e=>H(`option`,{value:e}))}),H(`datalist`,{id:`services`,children:Zn.map(e=>H(`option`,{value:e}))}),H(`datalist`,{id:`paths`,children:Qn.map(([e,t])=>H(`option`,{value:e,label:t}))})]}),er=(e,t,n=`${t}s`)=>`${e} ${e===1?t:n}`,$=({label:e,hint:t,children:n,wide:r,safety:i})=>H(`div`,{class:`field ${r?`field-wide`:``}`,children:[H(`label`,{class:`field-control`,children:[H(`span`,{class:`field-label`,children:e}),n]}),t&&H(`span`,{class:`hint ${i?`hint-safety`:``}`,children:t})]}),tr=({id:e,title:t,icon:n,summary:r,defaultOpen:i,action:a,children:o})=>{let[s]=z(i),[c,l]=Ot(e,s),u=`section-${e.replace(/[^a-z0-9]/gi,`-`)}`;return H(`section`,{class:`section ${c?`open`:`closed`}`,children:[H(`header`,{class:`section-header`,children:[H(`h3`,{class:`section-heading`,children:H(`button`,{type:`button`,class:`section-toggle`,"aria-expanded":c,"aria-controls":u,onClick:()=>l(!c),children:[H(U,{name:`chevron`,size:14,class:`chevron`}),n&&H(U,{name:n}),H(`span`,{children:t}),!c&&r&&H(`span`,{class:`section-summary`,children:r})]})}),a&&H(`button`,{type:`button`,class:`button small`,onClick:()=>{a.onClick(),l(!0)},children:[H(U,{name:`plus`}),` `,a.label]})]}),c&&H(`div`,{class:`section-body`,id:u,children:o})]})},nr={valid:`ok`,invalid:`error`,incomplete:`info`,unchecked:`info`},rr=({entry:e,update:t,showLabel:n,focusLabel:r})=>{let{readOnly:i}=Z(),a=V(null);B(()=>{r&&a.current?.focus()},[]);let o=J[e.kind],s=Xe(e.kind),c=Tt(e),l=[e.description&&`description`,e.createdOn&&`created ${e.createdOn}`,e.expiresOn&&o.expires&&`expires ${e.expiresOn}`].filter(Boolean).join(` · `);return H(tr,{id:`${e.id}:details`,title:`Details`,summary:l||`empty`,defaultOpen:!e.label,children:[n&&H($,{label:`Label`,wide:!0,children:H(`input`,{ref:a,class:`input`,value:e.label,placeholder:yn(hn[e.kind]),readOnly:i,onInput:e=>t({label:e.currentTarget.value})})}),H($,{label:`Description`,wide:!0,children:H(`textarea`,{class:`input`,rows:2,value:e.description,placeholder:`What is this wallet or key for?`,readOnly:i,onInput:e=>t({description:e.currentTarget.value}),...Nt,"data-secret":void 0})}),sr(e,e.description)&&H(`p`,{class:`status status-error`,role:`status`,children:[H(U,{name:`alert`}),` This text repeats the entry's secret, and it is not hidden.`]}),H(`div`,{class:`row`,children:[s?H(C,{children:[H($,{label:o.serviceLabel,children:H(`input`,{class:`input`,list:`chains`,value:e.chain,readOnly:i,onInput:e=>t({chain:e.currentTarget.value})})}),H($,{label:o.accountLabel,children:H(`input`,{class:`input`,list:`wallets`,value:e.wallet,readOnly:i,onInput:e=>t({wallet:e.currentTarget.value})})})]}):H(C,{children:[H($,{label:o.serviceLabel,children:H(`input`,{class:`input`,list:`services`,value:e.service,readOnly:i,onInput:e=>t({service:e.currentTarget.value})})}),H($,{label:o.accountLabel,children:H(`input`,{class:`input`,value:e.account,readOnly:i,onInput:e=>t({account:e.currentTarget.value}),...Pt})})]}),H($,{label:`Date created`,children:H(`input`,{class:`input`,type:`date`,value:e.createdOn,readOnly:i,onInput:e=>t({createdOn:e.currentTarget.value})})}),o.expires&&H($,{label:`Expires on`,hint:c===null?`Optional. You are warned 30 days ahead.`:void 0,children:H(`input`,{class:`input`,type:`date`,value:e.expiresOn,readOnly:i,onInput:e=>t({expiresOn:e.currentTarget.value})})})]}),c!==null&&c<=30&&H(`p`,{class:`status ${c<0?`status-error`:`status-warn`}`,children:[H(U,{name:`clock`}),` `,c<0?`Expired on ${e.expiresOn}.`:c===0?`Expires today.`:`Expires in ${c} day${c===1?``:`s`}.`]}),H($,{label:`Tags`,hint:`Comma separated.`,wide:!0,children:H(xr,{tags:e.tags,onChange:e=>t({tags:e})})})]})},ir=({entry:e,update:t})=>{let{readOnly:n,confirm:r,toast:i}=Z(),a=V(e);a.current=e;let o=At(()=>rn(e.scheme,e.words),[e.scheme,e.words.join(` `)]),s=zt.find(t=>t.id===e.scheme),c=[...new Set([...s.counts,...Bt])].sort((e,t)=>e-t),l=e.words.filter(Boolean).length,[u,d]=z(!1),f=async n=>{if(!Number.isInteger(n)||n<1||n>48||n===e.words.length)return!1;let o=e.words,s=o.slice(n).filter(Boolean).length;if(s>0){if(!await r({title:`Remove words?`,message:`Shrinking to ${n} words removes ${s} word${s===1?``:`s`} you entered.`,confirmLabel:`Remove`,danger:!0}))return!1;if(a.current.words.join(` +`)!==o.join(` +`))return i(`The words changed while this was open. Nothing was removed.`,`error`),!1}return t({words:Array.from({length:n},(e,t)=>o[t]??``)}),!0},p=n=>{let r=zt.find(e=>e.id===n);l===0&&r.counts.length&&!r.counts.includes(e.words.length)?t({scheme:n,words:Array(r.counts[0]).fill(``)}):t({scheme:n})},m=`${s.label} · ${l===e.words.length?er(l,`word`):`${l} of ${e.words.length} words`}${e.passphrase?` + passphrase`:``}`;return H(tr,{id:`${e.id}:seed`,title:`Seed phrase`,icon:`seed`,summary:m,defaultOpen:!0,children:[H(`div`,{class:`row`,children:[H($,{label:`Scheme`,children:H(`select`,{class:`input`,value:e.scheme,disabled:n,onChange:e=>p(e.currentTarget.value),children:zt.map(e=>H(`option`,{value:e.id,children:e.label}))})}),H($,{label:`Words`,children:H(`select`,{class:`input`,value:u||!c.includes(e.words.length)?`custom`:String(e.words.length),disabled:n,onChange:async t=>{let n=t.currentTarget,r=n.value;r===`custom`?d(!0):(d(!1),await f(Number(r))||(n.value=c.includes(e.words.length)?String(e.words.length):`custom`))},children:[c.map(e=>H(`option`,{value:String(e),children:[e,s.counts.includes(e)?``:` (non-standard)`]})),H(`option`,{value:`custom`,children:`Custom…`})]})}),(u||!c.includes(e.words.length))&&H($,{label:`Custom count`,children:H(`input`,{class:`input`,type:`number`,min:1,max:48,value:e.words.length,readOnly:n,onChange:e=>f(Number(e.currentTarget.value))})})]}),H(mn,{words:e.words,scheme:e.scheme,unknownWords:o?.unknownWords??[],onChange:e=>t({words:e})}),o&&H(`p`,{class:`status status-${nr[o.status]}`,role:`status`,children:[H(U,{name:o.status===`valid`?`check`:o.status===`invalid`?`alert`:`shield`}),` `,o.message]}),H(cr,{entry:e,update:t})]})},ar=e=>setTimeout(()=>document.querySelector(`[data-row="${e}"] input`)?.focus()),or=e=>e.passphrase.length>=4&&e.passphraseHint.toLowerCase().includes(e.passphrase.toLowerCase()),sr=(e,t)=>{let n=t.toLowerCase();if(!n)return!1;if(e.secret.trim().length>=12&&n.includes(e.secret.trim().toLowerCase()))return!0;let r=e.words.filter(Boolean).map(e=>e.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g,`\\$&`));for(let e=0;e+4<=r.length;e++)if(RegExp(`\\b${r.slice(e,e+4).join(`\\s+`)}\\b`).test(n))return!0;return!1},cr=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=J[e.kind];return r.passphraseLabel?H(`div`,{class:`row`,children:[H($,{label:r.passphraseLabel,hint:r.passphraseHint,safety:!0,children:H(Ft,{label:r.passphraseLabel,value:e.passphrase,onInput:e=>t({passphrase:e}),placeholder:`None`})}),H($,{label:`Passphrase hint`,hint:`Not hidden. Never write the passphrase itself here.`,safety:!0,children:H(`input`,{class:`input`,value:e.passphraseHint,readOnly:n,onInput:e=>t({passphraseHint:e.currentTarget.value}),...Pt})}),or(e)&&H(`p`,{class:`status status-error field-wide`,role:`status`,children:[H(U,{name:`alert`}),` The hint contains the passphrase. Anyone who opens this note can read it.`]})]}):null},lr={ok:`ok`,info:`info`,warn:`warn`,error:`error`},ur=({entry:e,update:t})=>{let n=J[e.kind],r=At(()=>qn(e.secret),[e.secret]);return H(tr,{id:`${e.id}:key`,title:n.secretLabel,icon:`key`,summary:e.secret?r?.label??`set`:`empty`,defaultOpen:!0,children:[H($,{label:n.secretLabel,wide:!0,children:H(Ft,{label:n.secretLabel,value:e.secret,onInput:e=>t({secret:e}),placeholder:n.secretPlaceholder,multiline:n.secret===`key`&&(e.kind!==`privateKey`||e.secret.includes(` +`)),onMultilinePaste:e=>t({secret:e}),mono:!0})}),H(`p`,{class:`status ${r?`status-${lr[r.level]}`:``}`,role:`status`,children:r&&H(C,{children:[H(U,{name:r.level===`ok`?`check`:r.level===`info`?`shield`:`alert`}),` `,r.label,r.detail&&H(`span`,{class:`muted`,children:[` · `,r.detail]})]})}),H(cr,{entry:e,update:t})]})},dr=({entry:e,update:t})=>{let n=e.secret.split(/\n/).filter(e=>e.trim()).length;return H(tr,{id:`${e.id}:codes`,title:`Recovery codes`,icon:`list`,summary:n?`${n} code${n===1?``:`s`}`:`empty`,defaultOpen:!0,children:H($,{label:`Codes`,hint:`One per line. Delete or mark a code once used.`,wide:!0,children:H(Ft,{label:`Recovery codes`,value:e.secret,onInput:e=>t({secret:e}),placeholder:`One code per line`,multiline:!0,mono:!0})})})},fr=({text:e})=>{let t=At(()=>Jn(e),[e]);return t?H(`p`,{class:`status status-error`,role:`status`,children:[H(U,{name:`alert`}),` This looks like private key material (`,t,`). This field is not hidden: move it to the secret field.`]}):null},pr=(e,t)=>{let n=e.trim();return t&&(n=n.replace(/^\[([0-9a-fA-F]{8})[^\]]*\].*$/,`$1`).replace(/^0x/i,``).replace(/\s+/g,``)),n},mr=e=>e.trim().replace(/[’‘′`]/g,`'`).replace(/^M\//,`m/`),hr=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=J[e.kind].publicKey;if(!r)return null;let i=At(()=>Jn(e.fingerprint),[e.fingerprint]),a=[e.publicInfo&&`public key`,e.fingerprint&&(i?`fingerprint`:e.fingerprint)].filter(Boolean).join(` · `),o=e.kind===`pgpKey`&&e.fingerprint&&!/^([0-9a-fA-F]{40}|[0-9a-fA-F]{64})$/.test(e.fingerprint.replace(/\s/g,``));return H(tr,{id:`${e.id}:public`,title:`Public info`,icon:`eye`,summary:a||`empty`,defaultOpen:!1,children:[H(`p`,{class:`muted small helper`,children:`Not secret. Lets you match this entry to a server, keyring or recipient.`}),H($,{label:r.label,wide:!0,children:H(`textarea`,{class:`input mono`,rows:e.publicInfo?3:2,value:e.publicInfo,placeholder:r.placeholder,readOnly:n,onInput:e=>t({publicInfo:e.currentTarget.value}),...Pt})}),H(fr,{text:e.publicInfo}),H($,{label:r.fingerprintLabel,wide:!0,children:H(`input`,{class:`input mono`,value:e.fingerprint,placeholder:r.fingerprintPlaceholder,readOnly:n,onInput:e=>t({fingerprint:e.currentTarget.value}),onBlur:n=>{let r=pr(n.currentTarget.value,!1);r!==e.fingerprint&&t({fingerprint:r})},...Pt})}),H(fr,{text:e.fingerprint}),o&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` PGP fingerprints are 40 hex characters (64 for newer v6 keys).`]})]})},gr=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=!!(e.derivationPath||e.fingerprint||e.publicInfo),i=At(()=>Jn(e.fingerprint),[e.fingerprint]),a=[e.derivationPath,e.fingerprint&&(i?`fingerprint`:e.fingerprint),e.publicInfo&&`addresses`].filter(Boolean).join(` · `),o=e.derivationPath.trim();return H(tr,{id:`${e.id}:public`,title:`Public info`,icon:`eye`,summary:a||`empty`,defaultOpen:!1,children:[H(`p`,{class:`muted small helper`,children:`Not secret. Helps you recognize the wallet without revealing the secret.`}),H(`div`,{class:`row`,children:[H($,{label:`Derivation path`,children:H(`input`,{class:`input mono`,list:`paths`,value:e.derivationPath,placeholder:`m/84'/0'/0'`,readOnly:n,onInput:e=>t({derivationPath:e.currentTarget.value}),onBlur:n=>{let r=mr(n.currentTarget.value);r!==e.derivationPath&&t({derivationPath:r})},...Pt})}),H($,{label:`Master fingerprint`,children:H(`input`,{class:`input mono`,value:e.fingerprint,placeholder:`e.g. 73c5da0a`,readOnly:n,onInput:e=>t({fingerprint:e.currentTarget.value}),onBlur:n=>{let r=pr(n.currentTarget.value,!0);r!==e.fingerprint&&t({fingerprint:r})},...Pt})})]}),o&&!/^m(\/\d+['hH]?)*$/.test(o)&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` `,/[’‘′`]/.test(o)?`Use straight apostrophes (') in derivation paths; curly ones are fixed when you leave the field.`:`Derivation paths look like m/84'/0'/0'.`]}),e.fingerprint&&!i&&!/^[0-9a-fA-F]{8}$/.test(e.fingerprint.trim())&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` A master fingerprint is 8 hex characters.`]}),H($,{label:`Addresses / xpub`,wide:!0,children:H(`textarea`,{class:`input mono`,rows:r?3:2,value:e.publicInfo,placeholder:`First receive address, xpub/zpub…`,readOnly:n,onInput:e=>t({publicInfo:e.currentTarget.value}),...Pt})}),H(fr,{text:e.publicInfo}),H(fr,{text:e.fingerprint})]})},_r=({entry:e,update:t,reminderMonths:n})=>{let{readOnly:r}=Z(),i=(n,r)=>t({backups:e.backups.map(e=>e.id===n?{...e,...r}:e)}),a=wt(e,n),o=Ct(e),s=H(`span`,{class:a?`status-warn`:void 0,children:[e.backups.length?er(e.backups.length,`location`):`none recorded`,o?` · checked ${o}`:``,a?` · check due`:``]});return H(tr,{id:`${e.id}:backups`,title:`Backups`,icon:`shield`,summary:s,defaultOpen:!1,action:r?void 0:{label:`Add location`,onClick:()=>{let n=qe();t({backups:[...e.backups,{id:n,location:``,verifiedOn:``}]}),ar(n)}},children:[H(`p`,{class:`status ${a?`status-warn`:`status-info`}`,children:[H(U,{name:a?`alert`:`check`}),` `,o?`Last checked ${o}.`:`No backup check recorded.`,a&&n>0&&` Check your backups at least every ${n} months.`]}),e.backups.length===0&&H(`p`,{class:`muted small helper`,children:`Record where copies are kept, like "steel plate in home safe". Do not record the secret itself here.`}),e.backups.map(n=>H(`div`,{class:`row backup-row`,"data-row":n.id,children:[H(`input`,{class:`input grow`,value:n.location,placeholder:`Location, e.g. steel plate in safe`,"aria-label":`Backup location`,readOnly:r,onInput:e=>i(n.id,{location:e.currentTarget.value}),...Pt}),H(`input`,{class:`input`,type:`date`,value:n.verifiedOn,"aria-label":`Last checked`,readOnly:r,onInput:e=>i(n.id,{verifiedOn:e.currentTarget.value})}),!r&&H(C,{children:[H(`button`,{type:`button`,class:`button small`,onClick:()=>i(n.id,{verifiedOn:nt()}),children:`Checked today`}),H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Remove backup location`,title:`Remove`,onClick:()=>t({backups:e.backups.filter(e=>e.id!==n.id)}),children:H(U,{name:`x`})})]})]},n.id))]})},vr=({entry:e,update:t})=>{let{readOnly:n}=Z(),r=(n,r)=>t({customFields:e.customFields.map(e=>e.id===n?{...e,...r}:e)}),i=J[e.kind].secret===`fields`;return H(tr,{id:`${e.id}:fields`,title:i?`Fields`:`Extra fields`,icon:`plus`,summary:e.customFields.length?er(e.customFields.length,`field`):`none`,defaultOpen:i,action:n?void 0:{label:`Add field`,onClick:()=>{let n=qe();t({customFields:[...e.customFields,{id:n,label:``,value:``,hidden:!0}]}),ar(n)}},children:[e.customFields.length===0&&H(`p`,{class:`muted small helper`,children:`For PINs, keystore passwords, 2FA backup codes, multisig details or anything else.`}),e.customFields.map(i=>H(`div`,{class:`custom-field`,"data-row":i.id,children:[H(`input`,{class:`input custom-label`,value:i.label,placeholder:`Label`,"aria-label":`Field label`,readOnly:n,onInput:e=>r(i.id,{label:e.currentTarget.value})}),H(`div`,{class:`custom-value`,children:i.hidden?H(Ft,{label:i.label||`Field`,value:i.value,multiline:i.multiline,onInput:e=>r(i.id,{value:e}),onMultilinePaste:e=>r(i.id,{value:e,multiline:!0})}):i.multiline?H(`textarea`,{class:`input`,rows:3,value:i.value,"aria-label":i.label||`Field value`,readOnly:n,onInput:e=>r(i.id,{value:e.currentTarget.value}),...Pt}):H(`input`,{class:`input`,value:i.value,"aria-label":i.label||`Field value`,readOnly:n,onInput:e=>r(i.id,{value:e.currentTarget.value}),...Pt,onPaste:e=>{let t=e.clipboardData?.getData(`text`)??``;if(!/[\r\n]/.test(t))return;e.preventDefault();let n=e.currentTarget,a=n.selectionStart??i.value.length,o=n.selectionEnd??i.value.length;r(i.id,{value:i.value.slice(0,a)+t+i.value.slice(o),multiline:!0})}})}),!n&&H(`div`,{class:`custom-actions`,children:[H(`label`,{class:`check small`,children:[H(`input`,{type:`checkbox`,checked:i.hidden,"aria-label":`Hide ${i.label||`field`} value`,onChange:e=>r(i.id,{hidden:e.currentTarget.checked})}),` `,`Hidden`]}),H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Remove field`,title:`Remove`,onClick:()=>t({customFields:e.customFields.filter(e=>e.id!==i.id)}),children:H(U,{name:`x`})})]})]},i.id))]})},yr=({entry:e,update:t})=>{let{readOnly:n}=Z();return H(tr,{id:`${e.id}:notes`,title:`Notes`,summary:e.notes?er(e.notes.length,`character`):`empty`,defaultOpen:!!e.notes&&e.kind===`other`,children:[H(`textarea`,{class:`input`,rows:4,value:e.notes,placeholder:`Recovery instructions, inheritance notes, history…`,"aria-label":`Notes`,readOnly:n,onInput:e=>t({notes:e.currentTarget.value}),...Nt}),sr(e,e.notes)&&H(`p`,{class:`status status-error`,role:`status`,children:[H(U,{name:`alert`}),` This text repeats the entry's secret, and it is not hidden.`]})]})},br=e=>{let t=new Set;return e.split(`,`).map(e=>e.trim()).filter(e=>e&&!t.has(e.toLowerCase())&&t.add(e.toLowerCase()))},xr=({tags:e,onChange:t})=>{let{readOnly:n}=Z(),[r,i]=z(e.join(`, `));B(()=>{br(r).join(`,`)!==e.join(`,`)&&i(e.join(`, `))},[e.join(`,`)]);let a=n=>{i(n);let r=br(n);r.join(`,`)!==e.join(`,`)&&t(r)},o=()=>i(br(r).join(`, `));return H(`input`,{class:`input`,value:r,placeholder:`cold storage, inheritance`,readOnly:n,onInput:e=>a(e.currentTarget.value),onBlur:o,onKeyDown:e=>e.key===`Enter`&&o()})},Sr=({lock:e,onEditing:t,children:n})=>{let r=Z(),i=r.readOnly||e===`locked`,a=Ce(()=>i===r.readOnly?r:{...r,readOnly:i},[r,i]),o=e===`locked`;return H(Dt.Provider,{value:a,children:[e!==`off`&&!r.readOnly&&H(`div`,{class:`lock-bar ${e}`,children:[H(U,{name:o?`lock`:`edit`}),H(`span`,{children:o?`Locked against accidental changes.`:`Editing.`}),H(`button`,{type:`button`,class:`button small`,onClick:()=>t(o),children:[H(U,{name:o?`edit`:`check`}),` `,o?`Edit`:`Done`]})]}),n]})},Cr=({entry:e,onUpdate:t,onDelete:n,onDuplicate:r})=>{let{readOnly:i}=Z();return i?null:H(`div`,{class:`entry-actions`,children:[H(`button`,{type:`button`,class:`icon-button ${e.favorite?`active`:``}`,"aria-pressed":e.favorite,"aria-label":`Favorite`,title:`Favorite`,disabled:i,onClick:()=>t({favorite:!e.favorite}),children:H(U,{name:`star`,fill:e.favorite?`currentColor`:`none`})}),!i&&H(C,{children:[H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Duplicate`,title:`Duplicate`,onClick:r,children:H(U,{name:`duplicate`})}),H(`button`,{type:`button`,class:`icon-button ${e.archived?`active`:``}`,"aria-label":e.archived?`Unarchive`:`Archive`,title:e.archived?`Unarchive`:`Archive (e.g. an emptied or retired wallet)`,onClick:()=>t({archived:!e.archived}),children:H(U,{name:`archive`})}),H(`button`,{type:`button`,class:`icon-button danger`,"aria-label":`Delete`,title:`Delete`,onClick:n,children:H(U,{name:`trash`})})]})]})},wr=e=>{let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString()},Tr=({entry:e,reminderMonths:t,onUpdate:n,showLabel:r,focusLabel:i=!1})=>{let{readOnly:a}=Z(),o=e=>!a&&n(e),s=J[e.kind].secret;return H(`div`,{class:`entry-body`,children:[H(rr,{entry:e,update:o,showLabel:r,focusLabel:i}),s===`words`&&H(ir,{entry:e,update:o}),(s===`key`||s===`token`)&&H(ur,{entry:e,update:o}),s===`codes`&&H(dr,{entry:e,update:o}),s===`fields`&&H(vr,{entry:e,update:o}),Xe(e.kind)?H(gr,{entry:e,update:o}):H(hr,{entry:e,update:o}),s!==`fields`&&H(vr,{entry:e,update:o}),H(_r,{entry:e,update:o,reminderMonths:t}),H(yr,{entry:e,update:o}),H(`footer`,{class:`editor-footer muted small`,children:[`Added `,wr(e.addedAt),` · Updated `,wr(e.updatedAt)]})]})},Er=({entry:e,lock:t,reminderMonths:n,onUpdate:r,onDelete:i,onDuplicate:a,onEditing:o,onBack:s,focusLabel:c})=>{let l=Z().readOnly||t===`locked`,u=V(null);return B(()=>{c&&u.current?.focus()},[]),H(`article`,{class:`editor`,"aria-label":e.label||`Untitled entry`,children:[H(`header`,{class:`editor-header`,children:[H(`button`,{type:`button`,class:`icon-button back-button`,"aria-label":`Back to list`,title:`Back`,onClick:s,children:H(U,{name:`back`})}),H(`input`,{ref:u,class:`input title-input`,value:e.label,placeholder:yn(hn[e.kind]),"aria-label":`Label`,readOnly:l,onInput:e=>!l&&r({label:e.currentTarget.value})}),H(`span`,{class:`badge badge-${e.kind}`,children:hn[e.kind]}),H(Cr,{entry:e,onUpdate:r,onDelete:i,onDuplicate:a,onEditing:o})]}),H(`div`,{class:`editor-body`,children:H(Sr,{lock:t,onEditing:o,children:H(Tr,{entry:e,reminderMonths:n,onUpdate:r,showLabel:!1})})})]})},Dr=[[`all`,`All`],[`crypto`,`Crypto`],...Je.map(e=>[e,gn[e]]),[`favorites`,`Favorites`],[`attention`,`Backup check due`],[`expiring`,`Expiring or expired`],[`archived`,`Archived`]],Or=new Intl.Collator(void 0,{numeric:!0,sensitivity:`base`}),kr=(e,t)=>{if(!t)return!0;let n=[e.label,e.description,e.chain,e.wallet,e.service,e.account,e.notes,e.derivationPath,e.fingerprint,e.publicInfo,...e.tags,...e.customFields.flatMap(e=>e.hidden?[e.label]:[e.label,e.value]),...e.backups.map(e=>e.location)].join(` `).toLowerCase();return t.toLowerCase().split(/\s+/).every(e=>n.includes(e))},Ar=(e,t,n,r,i)=>e.filter(e=>t===`archived`?e.archived:!e.archived).filter(e=>{switch(t){case`all`:case`archived`:return!0;case`crypto`:return Xe(e.kind);case`favorites`:return e.favorite;case`attention`:return wt(e,i);case`expiring`:return Et(e);default:return e.kind===t}}).filter(e=>kr(e,r.trim())).sort((e,t)=>e.favorite===t.favorite?n===`label`?!e.label==!t.label?Or.compare(e.label,t.label):e.label?-1:1:n===`created`?(t.createdOn||``).localeCompare(e.createdOn||``):t.updatedAt.localeCompare(e.updatedAt):e.favorite?-1:1),jr=Je,Mr={none:``,kind:``,chain:`No chain or service`,wallet:`No wallet or account`,tag:`Untagged`},Nr=(e,t)=>{if(t===`none`)return[{key:`all`,label:``,entries:e}];let n=e=>t===`kind`?e.kind:t===`chain`?(e.chain||e.service).trim():t===`wallet`?(e.wallet||e.account).trim():(e.tags[0]??``).trim(),r=new Map;for(let i of e){let e=n(i),a=`${t}:${e.toLowerCase()}`,o=r.get(a);o||(o={key:a,label:t===`kind`?gn[e]:e||Mr[t],entries:[]},r.set(a,o)),o.entries.push(i)}let i=[...r.values()];if(t===`kind`)return i.sort((e,t)=>jr.indexOf(e.entries[0].kind)-jr.indexOf(t.entries[0].kind));let a=e=>e.key.endsWith(`:`);return i.sort((e,t)=>Number(a(e))-Number(a(t))||Or.compare(e.label,t.label))},Pr=e=>({order:e.flatMap(e=>e.entries.map(e=>e.id)),groupOf:new Map(e.flatMap(e=>e.entries.map(t=>[t.id,e.key]))),labelOf:new Map(e.map(e=>[e.key,e.label]))}),Fr=(e,t)=>{let n=new Map(t.order.map((e,t)=>[e,t])),r=new Map(e.flatMap(e=>e.entries.map(t=>[t.id,e.key]))),i=new Map(e.map(e=>[e.key,e.label])),a=e.flatMap(e=>e.entries).sort((e,t)=>(n.get(e.id)??-1)-(n.get(t.id)??-1)),o=new Map;for(let e of a){let n=t.groupOf.get(e.id)??r.get(e.id),a=o.get(n);a||(a={key:n,label:t.labelOf.get(n)??i.get(n)??``,entries:[]},o.set(n,a)),a.entries.push(e)}return[...new Set([...t.labelOf.keys(),...e.map(e=>e.key)])].flatMap(e=>o.get(e)??[])},Ir=({entry:e})=>{let t=At(()=>rn(e.scheme,e.words),[e.scheme,e.words.join(` `)]);return!t||t.status===`incomplete`||t.status===`unchecked`?null:t.status===`valid`?H(`span`,{class:`pill pill-ok`,title:t.message,children:[H(U,{name:`check`,size:12}),` checksum`]}):H(`span`,{class:`pill pill-error`,title:t.message,children:[H(U,{name:`alert`,size:12}),` check words`]})},Lr=({entry:e})=>{let t=Tt(e);return t===null||!Et(e)?null:t<0?H(`span`,{class:`pill pill-error`,title:`Expired ${e.expiresOn}`,children:`expired`}):H(`span`,{class:`pill pill-warn`,title:`Expires ${e.expiresOn}`,children:t===0?`expires today`:`expires in ${t} day${t===1?``:`s`}`})},Rr=({entry:e,reminderMonths:t,idPrefix:n})=>{let r=(Xe(e.kind)?[e.chain,e.wallet,e.kind===`mnemonic`?`${e.words.length} words`:``]:[hn[e.kind],e.service,e.account]).filter(Boolean).join(` · `);return H(C,{children:[H(`span`,{class:`entry-icon badge-${e.kind}`,title:hn[e.kind],children:H(U,{name:_n[e.kind]})}),H(`span`,{class:`entry-main`,children:[H(`span`,{class:`entry-title`,id:n&&`${n}-title`,children:[e.favorite&&H(U,{name:`star`,size:12,fill:`currentColor`,class:`star`}),e.label||H(`em`,{class:`muted`,children:yn(hn[e.kind])})]}),r&&H(`span`,{class:`entry-meta`,id:n&&`${n}-meta`,children:r}),H(`span`,{class:`entry-pills`,id:n&&`${n}-pills`,children:[e.kind===`mnemonic`&&H(Ir,{entry:e}),e.passphrase&&H(`span`,{class:`pill`,children:`+ passphrase`}),e.archived&&H(`span`,{class:`pill`,children:`archived`}),H(Lr,{entry:e}),wt(e,t)&&H(`span`,{class:`pill pill-warn`,children:e.backups.length?`backup check due`:`no backup recorded`}),e.tags.map(e=>H(`span`,{class:`pill`,children:e},e))]})]}),e.createdOn&&H(`span`,{class:`entry-date`,children:e.createdOn})]})},zr=({group:e,bare:t,collapsed:n,onToggle:r,children:i})=>{let a=`group-${e.key.replace(/[^a-z0-9]/gi,`-`)}`;return!e.label||t?H(`section`,{class:`group bare`,children:H(`div`,{id:a,children:i})}):H(`section`,{class:`group ${n?`collapsed`:``}`,children:[H(`h2`,{class:`group-heading`,children:H(`button`,{type:`button`,class:`group-toggle`,"aria-expanded":!n,"aria-controls":a,onClick:r,children:[H(U,{name:`chevron`,size:14,class:`chevron`}),H(`span`,{children:e.label}),H(`span`,{class:`count`,children:e.entries.length})]})}),!n&&H(`div`,{id:a,children:i})]})},Br=({groups:e,collapsedGroups:t,selectedId:n,reminderMonths:r,onSelect:i,onToggleGroup:a})=>H(`div`,{class:`entry-list`,children:e.map(o=>H(zr,{group:o,bare:e.length===1,collapsed:t.has(o.key)&&e.length>1,onToggle:()=>a(o.key),children:H(`ul`,{class:`entry-rows`,"aria-label":o.label||`Entries`,children:o.entries.map(e=>H(`li`,{children:H(`button`,{type:`button`,class:`entry-item ${e.id===n?`selected`:``}`,"aria-current":e.id===n,onClick:()=>i(e.id),children:H(Rr,{entry:e,reminderMonths:r})})},e.id))})},o.key))}),Vr=(e,t)=>{let n=Object.keys(e);return n.length===Object.keys(t).length&&n.every(n=>Object.is(e[n],t[n]))},Hr=(e=>class extends w{shouldComponentUpdate(e){return!Vr(this.props,e)}render(t){return x(e,t)}})(({entry:e,lock:t,open:n,reminderMonths:r,isNew:i,onToggle:a,...o})=>{let s=V(null);B(()=>{i&&s.current?.scrollIntoView({block:`nearest`})},[i]);let c=`entry-${e.id}`;return H(`li`,{ref:s,class:`card-entry ${n?`open`:``}`,children:[H(`div`,{class:`card-header`,children:[H(`button`,{type:`button`,class:`card-toggle`,"aria-expanded":n,"aria-controls":c,"aria-labelledby":`${c}-title`,"aria-describedby":`${c}-meta ${c}-pills`,onClick:()=>a(e.id),children:[H(U,{name:`chevron`,size:14,class:`chevron`}),H(Rr,{entry:e,reminderMonths:r,idPrefix:c})]}),n&&H(Cr,{entry:e,...o})]}),n&&H(`div`,{class:`card-body`,id:c,children:H(Sr,{lock:t,onEditing:o.onEditing,children:H(Tr,{entry:e,reminderMonths:r,onUpdate:o.onUpdate,showLabel:!0,focusLabel:i})})})]})}),Ur=({groups:e,expanded:t,collapsedGroups:n,reminderMonths:r,newId:i,lockFor:a,onToggle:o,onToggleGroup:s,handlersFor:c})=>H(`div`,{class:`stack`,children:e.map(l=>H(zr,{group:l,bare:e.length===1,collapsed:n.has(l.key)&&e.length>1,onToggle:()=>s(l.key),children:H(`ul`,{class:`cards`,"aria-label":l.label||`Entries`,children:l.entries.map(e=>H(Hr,{entry:e,lock:a(e.id),open:t.has(e.id),reminderMonths:r,isNew:e.id===i,onToggle:o,...c(e.id)},e.id))})},l.key))}),Wr=({label:e,icon:t,kind:n,buttonClass:r=`button small`,children:i})=>{let[a,o]=z(!1),s=V(null),c=V(null);return B(()=>{if(!a)return;let e=e=>{s.current?.contains(e.target)||o(!1)};return document.addEventListener(`pointerdown`,e),()=>document.removeEventListener(`pointerdown`,e)},[a]),H(`div`,{class:`popover-wrap`,ref:s,onKeyDown:e=>{e.key===`Escape`&&a&&(e.stopPropagation(),o(!1),c.current?.focus())},onFocusOut:e=>{let t=e.relatedTarget;t&&!s.current?.contains(t)&&o(!1)},children:[H(`button`,{type:`button`,ref:c,class:r,"aria-expanded":a,"aria-label":e,title:e,onClick:()=>o(!a),children:[H(U,{name:t}),` `,H(`span`,{class:`button-text`,children:e})]}),a&&H(`div`,{class:`popover popover-${n}`,children:i(()=>o(!1))})]})},Gr=[`crypto`,`keys`,`secrets`],Kr=({icon:e,label:t,onClick:n,disabled:r})=>H(`button`,{type:`button`,class:`button small`,"aria-label":t,title:t,onClick:n,disabled:r,children:[H(U,{name:e}),` `,H(`span`,{class:`button-text`,children:t})]}),qr=e=>{let t=e.view.layout===`stacked`;return H(`div`,{class:`toolbar`,children:[H(`div`,{class:`toolbar-row`,children:[H(`div`,{class:`search`,children:[H(U,{name:`search`}),H(`input`,{class:`input`,type:`search`,placeholder:`Search labels, tags, notes`,"aria-label":`Search`,value:e.query,onInput:t=>e.onQuery(t.currentTarget.value),spellcheck:!1})]}),H(`select`,{class:`input filter`,"aria-label":`Filter`,value:e.filter,onChange:t=>e.onFilter(t.currentTarget.value),children:Dr.map(([t,n])=>H(`option`,{value:t,children:[n,t===`attention`&&e.dueCount?` (${e.dueCount})`:``]}))}),!e.readOnly&&H(Wr,{label:`Add`,icon:`plus`,kind:`menu`,buttonClass:`button small primary add-button`,children:t=>Gr.map(n=>H(`div`,{role:`group`,"aria-label":Ye[n],class:`menu-group`,children:[H(`div`,{class:`menu-heading`,"aria-hidden":`true`,children:Ye[n]}),Je.filter(e=>J[e].group===n).map(n=>H(`button`,{type:`button`,class:`menu-item`,onClick:()=>{t(),e.onAdd(n)},children:[H(U,{name:_n[n]}),` `,hn[n]]}))]}))})]}),H(`div`,{class:`toolbar-row`,children:[H(`span`,{class:`muted small count`,role:`status`,children:e.shown===e.total?`${e.total} ${e.total===1?`entry`:`entries`}`:`${e.shown} of ${e.total} entries`}),H(`span`,{class:`spacer`}),t&&H(C,{children:[H(Kr,{icon:`expand`,label:`Expand all`,onClick:e.onExpandAll,disabled:e.view.singleExpand||e.shown===0}),H(Kr,{icon:`collapse`,label:`Collapse all`,onClick:e.onCollapseAll,disabled:e.shown===0})]}),H(Wr,{label:`View`,icon:`sliders`,kind:`dialog`,children:()=>H(`div`,{class:`view-options`,children:[H(`fieldset`,{children:[H(`legend`,{children:`Layout`}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`layout`,checked:t,onChange:()=>e.onView({layout:`stacked`})}),` Expandable cards`]}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`layout`,checked:!t,onChange:()=>e.onView({layout:`split`})}),` List + editor side by side`]})]}),H(`fieldset`,{children:[H(`legend`,{children:`Density`}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`density`,checked:e.view.density===`comfortable`,onChange:()=>e.onView({density:`comfortable`})}),` `,`Comfortable`]}),H(`label`,{class:`check`,children:[H(`input`,{type:`radio`,name:`density`,checked:e.view.density===`compact`,onChange:()=>e.onView({density:`compact`})}),` Compact`]})]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Group by`}),H(`select`,{class:`input`,value:e.view.groupBy,onChange:t=>e.onView({groupBy:t.currentTarget.value}),children:vn.map(([e,t])=>H(`option`,{value:e,children:t}))})]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Sort`}),H(`select`,{class:`input`,value:e.view.sort,onChange:t=>e.onView({sort:t.currentTarget.value}),children:[H(`option`,{value:`updated`,children:`Recently updated`}),H(`option`,{value:`label`,children:`Label`}),H(`option`,{value:`created`,children:`Date created`})]})]}),t&&H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:e.view.singleExpand,onChange:t=>e.onView({singleExpand:t.currentTarget.checked})}),` Open one entry at a time`]})]})}),H(Kr,{icon:`settings`,label:`Settings`,onClick:e.onSettings}),e.hasPassword&&H(Kr,{icon:`lock`,label:`Lock`,onClick:e.onLock}),H(Kr,{icon:`eyeOff`,label:`Hide all`,onClick:e.onHideAll})]})]})},Jr=6e5,Yr=16,Xr=12,Zr=Ue,Qr=1,$r=e=>G(`${Ze}|${Qr}|PBKDF2-SHA256|${e}|AES-256-GCM`),ei=async(e,t=q(Yr),n=Jr)=>{let r=await crypto.subtle.importKey(`raw`,K(G(e.normalize(`NFC`))),`PBKDF2`,!1,[`deriveKey`]);return{key:await crypto.subtle.deriveKey({name:`PBKDF2`,hash:`SHA-256`,salt:K(t),iterations:n},r,{name:`AES-GCM`,length:256},!1,[`encrypt`,`decrypt`]),salt:t,iterations:n}},ti=async(e,t)=>{let n=q(Xr),r=await crypto.subtle.encrypt({name:`AES-GCM`,iv:K(n),additionalData:K($r(t.iterations))},t.key,K(G(JSON.stringify(e))));return{kdf:`PBKDF2-SHA256`,iterations:t.iterations,salt:Ve(t.salt),cipher:`AES-256-GCM`,iv:Ve(n),ciphertext:Ve(new Uint8Array(r))}},ni=class extends Error{constructor(){super(`Wrong password, or the vault data is damaged.`)}},ri=class extends Error{constructor(){super(`The vault data in this note is damaged. Restore an earlier version from note history.`)}},ii=e=>{try{return He(e)}catch{throw new ri}},ai=class extends Error{constructor(){super(`This browser cannot decrypt vaults here: encryption needs a secure (https) page. Open the note in the Standard Notes app or at app.standardnotes.com.`)}},oi=async(e,t)=>{let n=ii(e.iv),r=ii(e.ciphertext),i;try{i=await crypto.subtle.decrypt({name:`AES-GCM`,iv:K(n),additionalData:K($r(e.iterations))},t.key,K(r))}catch{throw new ni}try{return _t(JSON.parse(Re(new Uint8Array(i))))}catch{throw new ri}},si=async(e,t)=>{if(!Zr())throw new ai;let n=await ei(t,ii(e.salt),e.iterations);return{vault:await oi(e,n),vaultKey:n}},ci=(e,t)=>e.salt===Ve(t.salt)&&e.iterations===t.iterations,li=`keyfold-viewer.html`,ui=`Encrypted backup of a Keyfold vault (https://github.com/nickstruglia/standard-notes-keyfold). To read it without Standard Notes, open ${li} (keep a copy next to this file; it is also at https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/${li}) in a browser and choose this file; it works offline. To restore it, create a new Standard Notes note, change the note type to Keyfold, choose "Restore a backup file" and pick this file, then enter the backup password. `+et(`the password chosen when the backup was made`),di=(e=nt())=>`keyfold-backup-${e}.json`,fi=async(e,t,n=Jr)=>{let r=new Date().toISOString(),i=await ti({...e,settings:{...e.settings,lastExportedAt:r}},await ei(t,void 0,n));return{text:JSON.stringify({app:Ze,version:1,readme:ui,exportedAt:r,encryption:i},null,1)+` +`,fileName:di(),exportedAt:r,entries:e.entries.length}},pi=e=>{let t=e.settings.lastExportedAt;return t?e.entries.filter(e=>e.updatedAt>t||e.addedAt>t).length:e.entries.length},mi=e=>e===0?`Never`:e<60?`${e} seconds`:`${e/60} minute${e===60?``:`s`}`,hi=({value:e,options:t,format:n,onChange:r,disabled:i})=>H(`select`,{class:`input`,value:String(e),disabled:i,onChange:e=>r(Number(e.currentTarget.value)),children:[...new Set([...t,e])].sort((e,t)=>e-t).map(e=>H(`option`,{value:String(e),children:n(e)}))}),gi=new Set([`1234567890`,`12345678910`,`0123456789`,`1111111111`,`qwertyuiop`,`asdfghjkl;`,`password12`,`password123`,`password1!`,`password123!`,`iloveyou12`,`letmein123`,`welcome123`,`abcdefghij`,`qwerty1234`,`1q2w3e4r5t`,`q1w2e3r4t5`,`zaq12wsxcde`,`passw0rd123`,`administrator`,`trustno1234`,`football123`,`baseball12`]),_i=e=>{if(gi.has(e.toLowerCase()))return{bits:0,label:`Very common`,tone:`error`};let t=(/[a-z]/.test(e)?26:0)+(/[A-Z]/.test(e)?26:0)+(/[0-9]/.test(e)?10:0)+(/[^a-zA-Z0-9]/.test(e)?33:0),n=new Set(e).size,r=Math.round(Math.min(e.length,n*2)*Math.log2(Math.max(t,1)));return r<50?{bits:r,label:`Weak`,tone:`error`}:r<75?{bits:r,label:`Fair`,tone:`warn`}:{bits:r,label:`Strong`,tone:`ok`}},vi=10,yi={set:`Set password`,change:`Change password`,remove:`Remove password`,export:`Encrypt backup`},bi=({mode:e,onSubmit:t,onCancel:n})=>{let r=e===`change`||e===`remove`,i=e===`export`,a=kt(r),o=kt(!r),[s,c]=z(``),[l,u]=z(``),[d,f]=z(``),[p,m]=z(!1),[h,g]=z(!1),_={strength:Ee(),mismatch:Ee()},[v,y]=z(!1),[b,x]=z(``),S=_i(l),w=S.tone===`error`,T=e!==`remove`,E=d!==``&&d!==l,D=(!r||s.length>0)&&(!T||l.length>=vi&&l===d&&p&&(!w||h));return H(`form`,{class:`password-form`,onSubmit:async e=>{if(e.preventDefault(),D&&!v){y(!0),x(``);try{await t(s,l)}catch(e){x(e instanceof Error?e.message:String(e)),y(!1)}}},children:[r&&H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Current vault password`}),H(`input`,{class:`input`,type:`password`,autocomplete:`current-password`,value:s,onInput:e=>c(e.currentTarget.value),ref:a})]}),T&&H(C,{children:[H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:i?`Backup password`:`New vault password`}),H(`input`,{class:`input`,type:`password`,autocomplete:`new-password`,value:l,onInput:e=>u(e.currentTarget.value),ref:o,"aria-describedby":l?_.strength:void 0}),l&&H(`span`,{id:_.strength,class:`hint status-${S.tone}`,children:[S.label,` (~`,S.bits,` bits).`,` `,l.lengthf(e.currentTarget.value),"aria-invalid":E,"aria-describedby":E?_.mismatch:void 0}),E&&H(`span`,{id:_.mismatch,class:`hint status-error`,role:`alert`,children:`Passwords do not match.`})]}),w&&l.length>=vi&&H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:h,onChange:e=>g(e.currentTarget.checked)}),H(`span`,{children:i?`Use this weak password anyway. Anyone who finds the backup file could guess it quickly.`:`Use this weak password anyway. Someone with access to your Standard Notes account could guess it quickly.`})]}),e===`change`&&H(`p`,{class:`small status-warn`,children:[H(U,{name:`alert`}),` Older versions of this note in Standard Notes' note history still open with the old password. If it leaked, delete those revisions too.`]}),H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:p,onChange:e=>m(e.currentTarget.checked)}),H(`span`,{children:i?`I understand that if I forget this password, no one (not Standard Notes, not the developer) can open this backup.`:`I understand that if I forget this password, no one (not Standard Notes, not the developer) can recover the secrets in this note.`})]})]}),b&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` `,b]}),H(`div`,{class:`row`,children:[H(`button`,{type:`submit`,class:`button ${e===`remove`?`danger`:`primary`}`,disabled:!D||v,children:v?i?`Encrypting…`:`Working…`:yi[e]}),H(`button`,{type:`button`,class:`button`,onClick:n,disabled:v,children:`Cancel`})]})]})},xi=e=>`${(e/1024).toFixed(+(e<10240))} KB`,Si=({vault:e,mobileApp:t,onExport:n,onExported:r,onCopy:i})=>{let{toast:a}=Z(),[o,s]=z(!1),[c,l]=z(null),u=Ce(()=>{if(!c)return null;let e=new Blob([c.text],{type:`application/json`});return{url:URL.createObjectURL(e),size:e.size}},[c]);B(()=>{if(u)return()=>{setTimeout(()=>URL.revokeObjectURL(u.url),6e4)}},[u]);let d=V(null),f=V(null);B(()=>(t?f:d).current?.focus(),[u]);let p=e.settings.lastExportedAt,m=p?pi(e):0,h=Zr()?mt(e)?`This vault was saved by a newer version of Keyfold. Update Keyfold first, so the backup leaves nothing out.`:e.entries.length===0?`There is nothing to back up yet.`:``:`Your browser does not provide WebCrypto here, so a backup cannot be encrypted.`,g=async()=>{c&&(await i(c.text)?(r(c),a(`Backup copied. Paste it into a text file or another app; only its password opens it.`,`success`)):a(`Could not copy the backup: clipboard access was blocked.`,`error`))},_=c&&u&&H(`a`,{ref:d,class:`button ${t?``:`primary`}`,href:u.url,download:c.fileName,onClick:()=>r(c),children:[H(U,{name:`download`}),` Save file`]}),v=H(`button`,{ref:f,type:`button`,class:`button ${t?`primary`:``}`,onClick:g,children:[H(U,{name:`copy`}),` Copy as text`]});return H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`download`}),` Backup file`]}),H(`p`,{class:`small`,children:`Save an encrypted copy of this vault outside Standard Notes, for example on a flash drive, so you can still read it if Standard Notes is ever unavailable. The Keyfold offline viewer opens it in any browser, with no account and no internet connection.`}),H(`p`,{class:`muted small`,children:[p?`Last backup file: ${bn(p)}.`:`No backup file made yet.`,m>0&&` ${m} ${m===1?`entry was`:`entries were`} added or changed since.`]}),c&&u?H(`div`,{class:`backup-ready`,children:[H(`p`,{class:`status status-ok`,role:`status`,children:[H(U,{name:`check`}),` Encrypted `,c.entries,` `,c.entries===1?`entry`:`entries`,` into `,c.fileName,` (`,xi(u.size),`).`]}),H(`div`,{class:`row`,children:[t?v:_,t?_:v,H(`button`,{type:`button`,class:`button`,onClick:()=>l(null),children:`Done`})]}),(t||Mt())&&H(`p`,{class:`small`,children:[t?`The Standard Notes phone app may not save files from plugins. `:``,`If Save file does nothing, copy the text and paste it into a file or another app, or make the backup on a computer.`]}),H(`p`,{class:`muted small`,children:`Keep it somewhere other than Standard Notes, with the offline viewer next to it, and make a new one after adding or changing keys.`})]}):o?H(C,{children:[H(`p`,{class:`small`,children:`Choose a password for this backup. It can be your vault password or a different one, as long as you will still remember it in years.`}),H(bi,{mode:`export`,onSubmit:async(e,t)=>{l(await n(t)),s(!1)},onCancel:()=>s(!1)})]}):H(C,{children:[h&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` `,h]}),H(`div`,{class:`row`,children:[H(`button`,{type:`button`,class:`button primary`,disabled:!!h,onClick:()=>s(!0),children:[H(U,{name:`download`}),` Make a backup file`]}),H(`a`,{class:`button`,href:`https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/${li}`,target:`_blank`,rel:`noopener noreferrer`,children:`Get the offline viewer`})]})]})]})},Ci=({vault:e,settings:t,hasPassword:n,onChange:r,onSetPassword:i,onChangePassword:a,onRemovePassword:o,onExport:s,onExported:c,onCopyBackup:l,mobileApp:u,onLock:d,onClose:f})=>{let{readOnly:p}=Z(),[m,h]=z(null);return H(`article`,{class:`editor settings`,children:[H(`header`,{class:`editor-header`,children:[H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Close settings`,title:`Back`,onClick:f,children:H(U,{name:`back`})}),H(`h2`,{children:`Vault settings`})]}),H(`div`,{class:`editor-body`,children:[H(`p`,{class:`muted small`,children:`Settings are saved in this note, so every device uses the same ones.`}),H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`eye`}),` Privacy`]}),H(`div`,{class:`row`,children:[H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Hide revealed secrets after`}),H(hi,{value:t.autoHideSeconds,options:[0,10,30,60,120,300],format:mi,disabled:p,onChange:e=>r({autoHideSeconds:e})})]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Clear clipboard after`}),H(hi,{value:t.clipboardClearSeconds,options:[0,10,20,30,60,120],format:mi,disabled:p,onChange:e=>r({clipboardClearSeconds:e})})]})]}),H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:t.hideOnBlur,disabled:p,onChange:e=>r({hideOnBlur:e.currentTarget.checked})}),H(`span`,{children:`Hide revealed secrets when the editor loses focus`})]}),H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:t.privacyScreen,disabled:p,onChange:e=>r({privacyScreen:e.currentTarget.checked})}),H(`span`,{children:`Privacy screen: blur the whole vault while the editor is not focused`})]}),H(`label`,{class:`check`,children:[H(`input`,{type:`checkbox`,checked:t.lockSavedEntries,disabled:p,onChange:e=>r({lockSavedEntries:e.currentTarget.checked})}),H(`span`,{children:`Open saved entries locked, so nothing changes by accident while scrolling. Use Edit on an entry to change it.`})]})]}),H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`shield`}),` Backup reminders`]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Flag entries whose backups were not checked within`}),H(hi,{value:t.backupReminderMonths,options:[0,3,6,12,24],format:e=>e===0?`Off`:`${e} months`,disabled:p,onChange:e=>r({backupReminderMonths:e})})]})]}),H(Si,{vault:e,mobileApp:u,onExport:s,onExported:c,onCopy:l}),H(`section`,{class:`section`,children:[H(`h3`,{children:[H(U,{name:`lock`}),` Vault password`]}),H(`p`,{class:`small`,children:`Standard Notes already end-to-end encrypts this note. A vault password adds a second layer: the note stays unreadable even to someone using your unlocked Standard Notes account, until the password is entered.`}),H(`p`,{class:`muted small`,children:[`AES-256-GCM, key derived with PBKDF2-SHA256 (`,Jr.toLocaleString(),` iterations). The key is kept only in memory while the vault is unlocked.`]}),!n&&H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` Older versions of this note in Standard Notes' note history are not re-encrypted. To keep no unprotected copy, set the password on a new, empty vault note before adding secrets, or delete the old revisions.`]}),Zr()?m?H(bi,{mode:m,onSubmit:async(e,t)=>{m===`set`&&await i(t),m===`change`&&await a(e,t),m===`remove`&&await o(e),h(null)},onCancel:()=>h(null)}):n?H(C,{children:[H(`p`,{class:`status status-ok`,children:[H(U,{name:`check`}),` This vault is password protected.`]}),H(`label`,{class:`field`,children:[H(`span`,{class:`field-label`,children:`Lock automatically after inactivity`}),H(hi,{value:t.autoLockMinutes,options:[0,1,2,5,10,15,30,60],format:e=>e===0?`Never`:`${e} minute${e===1?``:`s`}`,disabled:p,onChange:e=>r({autoLockMinutes:e})})]}),H(`div`,{class:`row`,children:[H(`button`,{type:`button`,class:`button primary`,onClick:d,children:[H(U,{name:`lock`}),` Lock now`]}),H(`button`,{type:`button`,class:`button`,disabled:p,onClick:()=>h(`change`),children:`Change password`}),H(`button`,{type:`button`,class:`button danger`,disabled:p,onClick:()=>h(`remove`),children:`Remove password`})]})]}):H(`button`,{type:`button`,class:`button primary`,disabled:p,onClick:()=>h(`set`),children:[H(U,{name:`lock`}),` Set a vault password`]}):H(`p`,{class:`status status-warn`,children:[H(U,{name:`alert`}),` Your browser does not provide WebCrypto here, so a vault password is not available.`]})]}),H(`section`,{class:`section`,children:[H(`h3`,{children:`About`}),H(`p`,{class:`small`,children:[`Keyfold `,`1.0.31 (77e7bd8)`,`, from `,`https://standardnotes.github.io/plugins/cdn/dist/static/io.github.nickstruglia.keyfold/dist/`,`. Open source (MIT):`,` `,H(`a`,{href:`https://github.com/nickstruglia/standard-notes-keyfold`,target:`_blank`,rel:`noopener noreferrer`,children:`github.com/nickstruglia/standard-notes-keyfold`}),`. Its Content Security Policy blocks all outgoing connections, images and fonts from other sites; only your Standard Notes theme's stylesheets load.`]}),H(`details`,{class:`notices`,children:[H(`summary`,{class:`small`,children:`Third-party notices`}),H(`p`,{class:`small`,children:`Monero seeds are checked against the Monero English wordlist, used under this licence:`}),H(`pre`,{class:`small`,children:Lt})]})]})]})]})},wi=e=>new Promise((t,n)=>{let r=new FileReader;r.onload=()=>t(String(r.result??``)),r.onerror=()=>n(r.error),r.readAsText(e)}),Ti=({offlineViewer:e,onOpen:t})=>{let[n,r]=z(``),[i,a]=z(``),[o,s]=z(!1),c=V(null),l=kt(),u=(e,n)=>{let r=yt(e).kind;if(r===`empty`)return a(n===`file`?`This file is empty.`:`Paste the text first.`);if(r===`foreign`)return a(n===`file`?`This file is not a Keyfold backup or note.`:`This is not the text of a Keyfold note. Copy all of it, from the first { to the last }, without editing.`);t(e)},d=async e=>{if(e){if(a(``),e.size>20971520)return a(`This file is too large to be a Keyfold backup.`);try{u(await wi(e),`file`)}catch{a(`Could not read this file.`)}}};return H(`div`,{class:`app`,children:H(`div`,{class:`screen ${o?`dragging`:``}`,onDragOver:e=>{e.preventDefault(),s(!0)},onDragLeave:e=>{e.currentTarget===e.target&&s(!1)},onDrop:e=>{e.preventDefault(),s(!1),d(e.dataTransfer?.files[0])},children:H(`form`,{class:`card open-note`,onSubmit:e=>{e.preventDefault(),a(``),u(n,`paste`)},children:[H(U,{name:`lock`,size:32}),H(`h2`,{children:e?`Keyfold offline viewer`:`Open a Keyfold backup or note`}),H(`p`,{class:`small`,children:[`Open a Keyfold backup file, or paste the text of a Keyfold note. It opens read-only. Nothing is saved, and this page cannot send anything anywhere`,e?`, so it works offline`:``,`.`]}),H(`input`,{ref:c,type:`file`,hidden:!0,"aria-label":`Backup file`,onChange:e=>{let t=e.currentTarget;d(t.files?.[0]).finally(()=>{t.value=``})}}),H(`button`,{ref:l,type:`button`,class:`button primary`,onClick:()=>c.current?.click(),children:[H(U,{name:`file`}),` Choose backup file`]}),!Mt()&&H(`p`,{class:`muted small`,children:`or drop it on this page`}),i&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` `,i]}),H(`details`,{class:`paste-note`,children:[H(`summary`,{children:`Paste a note's text instead`}),H(`p`,{class:`small`,children:`In Standard Notes, change the note type to Plain text, then select all and copy, without editing.`}),H(`textarea`,{class:`input mono`,rows:8,value:n,"aria-label":`Note text`,placeholder:`{ "app": "keyfold", ... }`,onInput:e=>r(e.currentTarget.value),autocomplete:`off`,spellcheck:!1}),H(`button`,{type:`submit`,class:`button`,disabled:!n.trim(),children:`Open read-only`})]}),location.protocol!==`file:`&&H(`a`,{class:`small`,href:`./keyfold-viewer.html`,download:`keyfold-viewer.html`,children:`Save this viewer as a single file, to keep next to your backups`}),!e&&H(`a`,{class:`small`,href:`./`,children:`Back to the demo`})]})})})},Ei=({mobileApp:e,vaultHasPassword:t,onRestore:n,onCancel:r})=>{let[i,a]=z(``),[o,s]=z(null),[c,l]=z(``),[u,d]=z(!1),[f,p]=z(``),[m,h]=z(!1),g=V(null),_=V(null),v=kt(!e);B(()=>{o&&_.current?.focus()},[o]);let y=async(e,t)=>{d(!0),p(``);try{await n(e,t)}catch(e){p(e instanceof Error?e.message:String(e)),d(!1)}},b=(e,t)=>{p(``);let n=yt(e);switch(n.kind){case`empty`:return p(t===`file`?`This file is empty.`:`Paste the text first.`);case`foreign`:return p(t===`file`?`This file is not a Keyfold backup.`:`This is not the text of a Keyfold backup or note. Copy all of it, from the first { to the last }, without editing.`);case`newer`:return p(`This was made by a newer version of Keyfold. Update the plugin in Standard Notes (Preferences → Plugins), then try again.`);case`unsupported`:return p(`Its encryption uses settings this copy of Keyfold cannot read, or the file is damaged.`);case`plain`:y(e,``);return;case`encrypted`:return s({text:e,exportedAt:n.exportedAt})}},x=async e=>{if(e){if(p(``),e.size>20971520)return p(`This file is too large to be a Keyfold backup.`);try{b(await wi(e),`file`)}catch{p(`Could not read this file.`)}}},S=f&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` `,f]});if(o){let e=o.exportedAt?`Backup password`:`Vault password`;return H(`div`,{class:`screen`,children:H(`form`,{class:`card restore-backup`,onSubmit:e=>{e.preventDefault(),c&&!u&&y(o.text,c)},children:[H(U,{name:`lock`,size:32}),H(`h2`,{children:o.exportedAt?`Encrypted backup`:`Encrypted vault`}),H(`p`,{class:`small`,children:[o.exportedAt?`Made ${bn(o.exportedAt)}. Enter the password chosen when the backup was made.`:`Enter the vault password of the note this text came from.`,` `,t?`This vault keeps its own password.`:`The restored vault keeps this password. You can change it in Settings.`]}),!Zr()&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` Encryption needs a secure (https) connection. Open the note in the Standard Notes app or at app.standardnotes.com.`]}),H(`input`,{ref:_,class:`input`,type:`password`,autocomplete:`current-password`,placeholder:e,"aria-label":e,value:c,onInput:e=>l(e.currentTarget.value)}),S,H(`div`,{class:`row`,children:[H(`button`,{type:`submit`,class:`button primary`,disabled:!c||u,children:u?`Restoring…`:`Restore`}),H(`button`,{type:`button`,class:`button`,disabled:u,onClick:()=>{s(null),l(``),p(``)},children:`Back`})]})]})})}return H(`div`,{class:`screen ${m?`dragging`:``}`,onDragOver:e=>{e.preventDefault(),h(!0)},onDragLeave:e=>{e.currentTarget===e.target&&h(!1)},onDrop:e=>{e.preventDefault(),h(!1),x(e.dataTransfer?.files[0])},children:H(`form`,{class:`card restore-backup`,onSubmit:e=>{e.preventDefault(),u||b(i,`paste`)},children:[H(U,{name:`file`,size:32}),H(`h2`,{children:`Restore a backup`}),H(`p`,{class:`small`,children:`Choose a Keyfold backup file, or paste its text. Its entries are restored into this note, which is empty.`}),H(`input`,{ref:g,type:`file`,hidden:!0,"aria-label":`Backup file`,onChange:e=>{let t=e.currentTarget;x(t.files?.[0]).finally(()=>{t.value=``})}}),H(`button`,{ref:v,type:`button`,class:`button primary`,disabled:u,onClick:()=>g.current?.click(),children:[H(U,{name:`file`}),` Choose backup file`]}),!Mt()&&H(`p`,{class:`muted small`,children:`or drop it here`}),e&&H(`p`,{class:`small`,children:`The Standard Notes phone app may not let plugins open files. If nothing happens, paste the text instead.`}),S,H(`details`,{class:`paste-note`,open:e,children:[H(`summary`,{children:`Paste the text instead`}),H(`textarea`,{class:`input mono`,rows:6,value:i,"aria-label":`Backup text`,placeholder:`{ "app": "keyfold", ... }`,onInput:e=>a(e.currentTarget.value),autocomplete:`off`,spellcheck:!1}),H(`button`,{type:`submit`,class:`button`,disabled:!i.trim()||u,children:`Continue`})]}),H(`button`,{type:`button`,class:`button`,disabled:u,onClick:r,children:`Cancel`})]})})},Di=({onUnlock:e,autoFocus:t,exportedAt:n})=>{let r=n?`Backup password`:`Vault password`,i=Zr(),a=kt(t&&i),[o,s]=z(``),[c,l]=z(!1),[u,d]=z(``);return H(`div`,{class:`screen`,children:H(`form`,{class:`card lock-card`,onSubmit:async t=>{if(t.preventDefault(),o&&!c){l(!0),d(``);try{await e(o)}catch(e){d(e instanceof Error?e.message:String(e)),l(!1)}}},children:[H(U,{name:`lock`,size:32}),H(`h2`,{children:n?`Encrypted backup`:`Vault locked`}),H(`p`,{class:`muted small`,children:n?`Made ${bn(n)}. Enter the password chosen when the backup was made.`:`This note has an extra vault password. Standard Notes cannot recover it for you.`}),!i&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` This page cannot decrypt vaults: encryption needs a secure (https) connection. Open the note in the Standard Notes app or at app.standardnotes.com.`]}),H(`input`,{class:`input`,type:`password`,autocomplete:`current-password`,placeholder:r,"aria-label":r,value:o,disabled:!i,onInput:e=>s(e.currentTarget.value),ref:a}),u&&H(`p`,{class:`status status-error`,role:`alert`,children:[H(U,{name:`alert`}),` `,u]}),H(`button`,{type:`submit`,class:`button primary`,disabled:!o||c,children:c?`Unlocking…`:`Unlock`})]})})},Oi=({length:e,readOnly:t,onConvert:n})=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(U,{name:`alert`,size:32}),H(`h2`,{children:`This note already has other content`}),H(`p`,{class:`small`,children:[`It holds `,e.toLocaleString(),` characters that are not a Keyfold vault. Nothing has been changed.`]}),H(`p`,{class:`small`,children:`To keep the note as it is, switch it back to another editor in Standard Notes. Or convert it: the existing text is kept, line breaks included, in a hidden field of a new "Imported note" entry.`}),H(`button`,{type:`button`,class:`button primary`,disabled:t,onClick:n,children:`Convert to a vault`})]})}),ki=({version:e})=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(U,{name:`alert`,size:32}),H(`h2`,{children:`Saved by a newer version`}),H(`p`,{class:`small`,children:[`This vault uses format version `,e,`, which this copy of Keyfold does not understand yet. Nothing has been changed. Update the plugin in Standard Notes (Preferences → Plugins) to open it.`]})]})}),Ai=()=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(U,{name:`alert`,size:32}),H(`h2`,{children:`Vault encryption not recognized`}),H(`p`,{class:`small`,children:`This is a Keyfold vault, but its password protection uses settings this copy of Keyfold cannot read, or the data is damaged. Nothing has been changed. Update the plugin in Standard Notes (Preferences → Plugins), or restore an earlier version from note history.`})]})}),ji=({slow:e})=>H(`div`,{class:`screen`,children:H(`div`,{class:`card`,children:[H(`p`,{class:`muted`,children:`Connecting to Standard Notes…`}),e&&H(`p`,{class:`small muted`,children:`Still waiting. If Standard Notes asks to activate Keyfold, choose Continue; otherwise, close and reopen the note.`})]})}),Mi=({dialog:e,onClose:t})=>{let[n]=z(()=>document.activeElement),r=kt();return B(()=>()=>{n?.isConnected&&n.focus()},[]),B(()=>{let e=e=>e.key===`Escape`&&t(!1);return document.addEventListener(`keydown`,e),()=>document.removeEventListener(`keydown`,e)},[t]),H(`div`,{class:`overlay`,role:`presentation`,onClick:e=>e.target===e.currentTarget&&t(!1),onKeyDown:e=>{if(e.key!==`Tab`)return;let t=Array.from(e.currentTarget.querySelectorAll(`button`)),n=t[0],r=t[t.length-1];e.shiftKey&&document.activeElement===n?(e.preventDefault(),r.focus()):!e.shiftKey&&document.activeElement===r&&(e.preventDefault(),n.focus())},children:H(`div`,{class:`card dialog`,role:`alertdialog`,"aria-modal":`true`,"aria-labelledby":`dialog-title`,"aria-describedby":`dialog-message`,children:[H(`h2`,{id:`dialog-title`,children:e.title}),H(`p`,{id:`dialog-message`,class:`small`,children:e.message}),H(`div`,{class:`row end`,children:[H(`button`,{type:`button`,class:`button`,onClick:()=>t(!1),ref:r,children:`Cancel`}),H(`button`,{type:`button`,class:`button ${e.danger?`danger`:`primary`}`,onClick:()=>t(!0),children:e.confirmLabel??`OK`})]})]})})},Ni=({toasts:e,onDismiss:t})=>H(`div`,{class:`toasts`,role:`status`,"aria-live":`polite`,children:e.map(e=>H(`div`,{class:`toast toast-${e.tone}`,children:[H(`span`,{children:e.message}),e.action&&H(`button`,{type:`button`,class:`button small`,onClick:()=>{e.action.run(),t(e.id)},children:e.action.label}),H(`button`,{type:`button`,class:`icon-button`,"aria-label":`Dismiss`,onClick:()=>t(e.id),children:H(U,{name:`x`,size:14})})]},e.id))}),Pi=e=>{let t=document.activeElement,n=t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement?t:null,r=n?[n.selectionStart,n.selectionEnd]:null,i=document.createElement(`textarea`);i.value=e,i.setAttribute(`readonly`,``),i.style.position=`fixed`,i.style.opacity=`0`,document.body.appendChild(i),i.select(),i.setSelectionRange(0,e.length);let a=!1;try{a=document.execCommand(`copy`)}catch{a=!1}if(i.remove(),t?.focus?.({preventScroll:!0}),n&&r&&r[0]!==null&&r[1]!==null)try{n.setSelectionRange(r[0],r[1])}catch{}return a},Fi=async e=>{if(Pi(e))return!0;try{if(navigator.clipboard?.writeText)return await navigator.clipboard.writeText(e),!0}catch{}return!1},Ii=()=>Pi(` `),Li=async()=>{if(Ii())return!0;try{if(navigator.clipboard?.writeText)return await navigator.clipboard.writeText(``),!0}catch{}return!1},Ri=2e3,zi=class{host;onError;delayMs;maxWaitMs;version=0;ready=null;timer;inflight=Promise.resolve();unsentSince=null;readyVersion=0;pending=[];lastText=``;constructor(e,t,n=300,r=1e3){this.host=e,this.onError=t,this.delayMs=n,this.maxWaitMs=r}schedule(e){let t=++this.version;this.unsentSince??=Date.now();let n=async()=>{if(t===this.version)try{let n=await e();if(t!==this.version)return;this.ready=n,this.readyVersion=t,clearTimeout(this.timer);let r=this.unsentSince??Date.now(),i=Math.max(0,Math.min(this.delayMs,r+this.maxWaitMs-Date.now()));this.timer=setTimeout(()=>this.flush(),i)}catch(e){t===this.version&&this.onError(e)}};this.inflight=this.inflight.then(n)}flush(){clearTimeout(this.timer),this.timer=void 0;let e=this.ready;e&&(this.ready=null,this.readyVersion===this.version&&(this.unsentSince=null),this.remember(e.text),this.host.save(e.text,e.preview))}hasUnsent(){return this.unsentSince!==null}async settle(){await this.inflight,this.flush()}cancel(){this.version++,clearTimeout(this.timer),this.timer=void 0,this.ready=null,this.unsentSince=null}isEcho(e){let t=Date.now();this.pending=this.pending.filter(e=>t-e.att.text===e);return n===-1?e!==``&&e===this.lastText:(this.pending.splice(0,n),!0)}forget(){this.cancel(),this.pending=[]}noteSeen(e){this.lastText=e}remember(e){this.lastText=e,this.pending.push({text:e,at:Date.now()}),this.pending.length>20&&this.pending.shift()}},Bi=e=>e instanceof Error?e.message:String(e),Vi=H(`datalist`,{id:`bip39-words`,children:It.map(e=>H(`option`,{value:e}))}),Hi=H($n,{}),Ui=`The note changed while this was running. Please try again.`,Wi=({host:e})=>{let[t,n]=z({name:`connecting`}),[r,i]=z(rt),[a,o]=z(!1),[s,c]=z(!1),[l,u]=z(0),[d,f]=z(()=>document.hasFocus()),[p,m]=z(!1),[h,g]=z({type:`list`}),[_,v]=z(``),[y,b]=z(`all`),[x,S]=z(()=>new Set),[w,T]=z(()=>new Set),[E,D]=z({}),[O,ee]=z({}),[te,k]=z(null),[ne,re]=z([]),[ie,ae]=z(null),[oe,se]=z(!1),[ce,le]=z(()=>new Set),A=V(r),j=V(null),ue=V(!1),M=V(0),de=V(0),fe=V(0),N=V(null),pe=we(e=>re(t=>t.filter(t=>t.id!==e)),[]),P=we((e,t=`info`,n,r=4e3)=>{let i=++fe.current;return re(r=>{let a=[...r,{id:i,message:e,tone:t,action:n}];for(;a.length>4;){let e=a.findIndex(e=>!e.action&&e.id!==i);a.splice(e===-1?0:e,1)}return a}),setTimeout(()=>pe(i),r),i},[]),F=Ce(()=>new zi(e,e=>P(`Could not save: ${Bi(e)}`,`error`,void 0,8e3)),[e]),I=async e=>{let t=j.current;return t?{text:xt(await ti(e,t)),preview:St(null)}:{text:bt(e),preview:St(e)}},me=e=>{A.current=e,i(e)},he=mt(r),L=a||he||t.name!==`ready`,ge=V(L);ge.current=L;let _e=V(a);_e.current=a;let ve=()=>{let e=M.current;return()=>{if(e!==M.current)throw Error(Ui);if(ge.current)throw Error(`This note is read-only right now.`)}},ye=()=>{j.current=null,F.cancel(),me(rt()),u(e=>e+1),g({type:`list`}),S(new Set),le(new Set),D({}),k(null),re([]),ae(e=>(e?.resolve(!1),null))},be=we(e=>{if(ge.current)return!1;let t=e(A.current);return me(t),F.schedule(()=>I(t)),!0},[F]);B(()=>{e.subscribe(async e=>{if(o(e.locked),e.metadataOnly||F.isEcho(e.text))return;let t=F.hasUnsent();F.cancel(),F.noteSeen(e.text);let r=++M.current,i=r===1,a=yt(e.text),s=()=>t&&P(`A newer version arrived from another device or note history and replaced your last few keystrokes.`,`error`,void 0,8e3);switch(a.kind){case`empty`:case`plain`:{let e=ue.current;j.current&&ye(),ue.current=!1,c(!1),me(a.kind===`plain`?a.vault:rt()),n({name:`ready`}),e&&!i?P(`This vault is no longer password protected: the note was changed on another device or restored from history. Set a password again in Settings if this was not you.`,`error`,void 0,6e4):s();return}case`encrypted`:{c(!0),ue.current=!0;let e=j.current;if(e&&ci(a.blob,e))try{let t=await oi(a.blob,e);if(r!==M.current)return;F.cancel(),me(t),n({name:`ready`}),s();return}catch{}if(r!==M.current)return;j.current&&ye(),me(rt()),n({name:`locked`,blob:a.blob,autoFocus:i||document.hasFocus(),exportedAt:a.exportedAt});return}case`foreign`:case`newer`:case`unsupported`:j.current&&ye(),ue.current=!1,c(!1),n(a.kind===`foreign`?{name:`foreign`,text:a.text}:a.kind===`newer`?{name:`newer`,version:a.version}:{name:`unsupported`});return}})},[e,F]),B(()=>{let e=setTimeout(()=>m(!0),5e3);return()=>clearTimeout(e)},[]);let R=r.settings,xe=V(R);xe.current=R,B(()=>{let e=()=>F.flush(),t=()=>{F.flush(),f(!1),xe.current.hideOnBlur&&u(e=>e+1)},n=()=>f(!0),r=()=>document.visibilityState===`hidden`&&F.flush();return window.addEventListener(`blur`,t),window.addEventListener(`focus`,n),window.addEventListener(`pagehide`,e),window.addEventListener(`beforeunload`,e),document.addEventListener(`visibilitychange`,r),()=>{window.removeEventListener(`blur`,t),window.removeEventListener(`focus`,n),window.removeEventListener(`pagehide`,e),window.removeEventListener(`beforeunload`,e),document.removeEventListener(`visibilitychange`,r)}},[F]);let Se=we(async(e=!1)=>{e&&N.current&&Ii()&&(N.current.blockedToast&&pe(N.current.blockedToast),N.current=null,de.current++),document.activeElement instanceof HTMLElement&&document.activeElement.blur(),await F.settle();let t=yt(F.lastText);t.kind===`encrypted`?(ye(),n({name:`locked`,blob:t.blob,autoFocus:e||document.hasFocus(),exportedAt:t.exportedAt})):(c(!1),e&&P(`This note is not password protected, so it cannot be locked.`,`error`))},[F]);B(()=>{if(!s||t.name!==`ready`||!R.autoLockMinutes)return;let e=Date.now(),n=()=>e=Date.now(),r=[`pointerdown`,`keydown`,`input`,`wheel`,`touchstart`];r.forEach(e=>window.addEventListener(e,n,{passive:!0}));let i=()=>{Date.now()-e>=R.autoLockMinutes*6e4&&Se()},a=setInterval(i,5e3);return document.addEventListener(`visibilitychange`,i),window.addEventListener(`pageshow`,i),window.addEventListener(`focus`,i),()=>{r.forEach(e=>window.removeEventListener(e,n)),clearInterval(a),document.removeEventListener(`visibilitychange`,i),window.removeEventListener(`pageshow`,i),window.removeEventListener(`focus`,i)}},[s,t.name,R.autoLockMinutes,Se]);let Te=async e=>{if(t.name!==`locked`)return;let r=M.current,{vault:i,vaultKey:a}=await si(t.blob,e);if(r!==M.current){let e=yt(F.lastText);if(e.kind!==`encrypted`||!ci(e.blob,a))throw Error(Ui);let t=M.current;if(i=await oi(e.blob,a),t!==M.current)throw Error(Ui)}if(j.current=a,me(i),n({name:`ready`}),a.iterations<6e5){let t=ve(),n=await ei(e);try{t()}catch{return}j.current=n,F.schedule(()=>I(A.current))}},Ee=async e=>{await F.settle();let t=yt(F.lastText);if(t.kind!==`encrypted`)throw Error(`The vault is not password protected.`);await si(t.blob,e)},De=async e=>{let t=ve(),n=await ei(e);t(),j.current=n,ue.current=!0,c(!0),F.schedule(()=>I(A.current)),P(`Vault password set. The note is now encrypted with it.`,`success`)},Oe=async(e,t)=>{let n=ve();await Ee(e);let r=await ei(t);n(),j.current=r,F.schedule(()=>I(A.current)),P(`Vault password changed.`,`success`)},ke=async e=>{let t=ve();await Ee(e),t(),j.current=null,ue.current=!1,c(!1),F.schedule(()=>I(A.current)),P(`Vault password removed. Standard Notes encryption still protects the note.`,`success`)};B(()=>{r.entries.length>0&&se(!1)},[r.entries.length]);let Ae=async(e,t)=>{let n=ve(),r=yt(e),i=j.current,a,o=i;if(r.kind===`plain`)a=r.vault;else if(r.kind===`encrypted`){let e=await si(r.blob,t);a=e.vault,o??=e.vaultKey.iterations<6e5?await ei(t):e.vaultKey}else throw Error(`This is not a Keyfold backup.`);if(mt(a))throw Error(`This was made by a newer version of Keyfold. Update the plugin in Standard Notes (Preferences → Plugins), then try again.`);if(n(),A.current.entries.length>0)throw Error(`Entries were added to this note meanwhile. Restore into a new, empty note.`);j.current=o,ue.current=o!==null,c(o!==null),me(a),se(!1),F.schedule(()=>I(a));let s=`${a.entries.length} ${a.entries.length===1?`entry`:`entries`}`;P(i?`Restored ${s}. The vault keeps its own password.`:o?`Restored ${s}. The vault keeps the password you entered; you can change it in Settings.`:`Restored ${s}. This vault has no password of its own; you can set one in Settings.`,`success`,void 0,8e3)},je=e=>{if(mt(A.current))throw Error(`Update Keyfold before making a backup of this vault.`);return fi(A.current,e)},Me=async e=>await Fi(e)?(de.current++,N.current?.blockedToast&&pe(N.current.blockedToast),N.current=null,!0):!1,Ne=we(e=>{let t=xe.current.clipboardClearSeconds,n=++de.current;N.current?.blockedToast&&pe(N.current.blockedToast),N.current=t?{id:n}:null;let r=Mt(),i=t?`${e} copied. The clipboard is cleared after ${t}s, on your next click or tap here if the browser requires one. It stays copied if you leave this note first.`:`${e} copied.`;if(P(r?`${i} Your keyboard's clipboard history may keep its own copy.`:i,`success`,void 0,r?8e3:6e3),!t)return;let a=()=>{N.current?.blockedToast&&pe(N.current.blockedToast),N.current?.id===n&&(N.current=null),r?P(`Clipboard cleared. Delete it from your keyboard's clipboard history too.`,`info`,void 0,6e3):P(`Clipboard cleared.`,`info`,void 0,3e3)};setTimeout(async()=>{if(n!==de.current)return;if(await Li()){a();return}let e=[`click`,`touchend`,`pointerup`],t=!1,r=()=>e.forEach(e=>window.removeEventListener(e,i,!0)),i=()=>{if(!t){if(n!==de.current)return r();Ii()&&(t=!0,r(),a())}};e.forEach(e=>window.addEventListener(e,i,!0));let o=P(`Waiting for a click or tap to clear the clipboard.`,`info`,{label:`Clear now`,run:i},2e4);N.current?.id===n&&(N.current.blockedToast=o)},t*1e3)},[P]),Pe=we(async(e,t)=>{e&&(await Fi(e)?Ne(t):P(`Could not copy ${t.toLowerCase()}: clipboard access was blocked.`,`error`))},[Ne]);B(()=>{let e=e=>{e.target?.closest?.(`[data-secret]`)&&Ne(`Selection`)};return document.addEventListener(`copy`,e,!0),document.addEventListener(`cut`,e,!0),()=>{document.removeEventListener(`copy`,e,!0),document.removeEventListener(`cut`,e,!0)}},[Ne]);let Fe=we(e=>new Promise(t=>ae({...e,resolve:t})),[]),Ie=Ce(()=>({settings:R,readOnly:L,hideEpoch:l,copy:Pe,toast:P,confirm:Fe,sectionOpen:(e,t)=>E[e]??t,setSectionOpen:(e,t)=>D(n=>({...n,[e]:t}))}),[R,L,l,Pe,P,Fe,E]),W={layout:R.layout,density:R.density,singleExpand:R.singleExpand,groupBy:R.groupBy,sort:R.sort,...O},Le=e=>{ee(t=>({...t,...e})),be(t=>({...t,settings:{...t.settings,...e}}))},G=W.singleExpand,Re=we(e=>{k(null),S(t=>{if(t.has(e)){let n=new Set(t);return n.delete(e),n}return G?new Set([e]):new Set(t).add(e)})},[G]),ze=we(e=>T(t=>{let n=new Set(t);return n.delete(e)||n.add(e),n}),[]),Be=e=>{b(`all`),v(``),T(new Set),k(e),S(t=>W.singleExpand?new Set([e]):new Set(t).add(e)),g({type:`entry`,id:e}),le(t=>new Set(t).add(e))},Ve=(e,t)=>le(n=>{let r=new Set(n);return t?r.add(e):r.delete(e),r}),He=e=>{let t=it(e);be(e=>({...e,entries:[t,...e.entries]})),Be(t.id)},Ue=(e,t)=>{be(n=>({...n,entries:n.entries.map(n=>n.id===e?{...n,...t,updatedAt:new Date().toISOString()}:n)}))&&t.archived===!0&&P(`Archived. It is under the "Archived" filter.`,`info`,{label:`Undo`,run:()=>Ue(e,{archived:!1})},6e3)},K=e=>{let t=A.current.entries.find(t=>t.id===e);if(!t)return;let n=new Date().toISOString(),r={...JSON.parse(JSON.stringify(t)),id:qe(),label:t.label?`${t.label} (copy)`:``,archived:!1,addedAt:n,updatedAt:n};be(e=>({...e,entries:[r,...e.entries]})),Be(r.id)},We=async e=>{let t=A.current.entries.findIndex(t=>t.id===e),n=A.current.entries[t];n&&await Fe({title:`Delete this entry?`,message:`"${n.label||`Untitled`}" will be removed from this note. You can undo right after, and Standard Notes keeps note history.`,confirmLabel:`Delete`,danger:!0})&&A.current.entries.some(t=>t.id===e)&&(be(t=>({...t,entries:t.entries.filter(t=>t.id!==e)}))?(g({type:`list`}),S(t=>{let n=new Set(t);return n.delete(e),n}),P(`Deleted "${n.label||`Untitled`}".`,`info`,{label:`Undo`,run:()=>{A.current.entries.some(e=>e.id===n.id)||be(e=>{let r=[...e.entries];return r.splice(Math.min(t,r.length),0,n),{...e,entries:r}})}},1e4)):P(`Nothing was deleted: the note is read-only right now.`,`error`))},Ge=e=>be(t=>({...t,settings:{...t.settings,...e}})),Ke=async e=>{let t=M.current;if(!await Fe({title:`Convert this note?`,message:`The existing text is moved into a hidden field of a new "Imported note" entry, and the note becomes a vault.`,confirmLabel:`Convert`})||t!==M.current||_e.current)return;let r=rt();r.entries.push(it(`other`,{label:`Imported note`,customFields:[{id:qe(),label:`Imported text`,value:e,hidden:!0,multiline:!0}]})),me(r),n({name:`ready`}),c(j.current!==null),F.schedule(()=>I(r))},q=h.type===`entry`?r.entries.find(e=>e.id===h.id)??null:null,J=r.entries.filter(e=>wt(e,R.backupReminderMonths)).length,Ye=W.layout===`stacked`?x.size>0:q!==null,Xe=[W.layout,W.sort,W.groupBy,y,_,W.layout===`stacked`?``:q?.id].join(`|`),Ze=V(null),Qe=Ye&&Ze.current?.key===Xe?Ze.current.snapshot:null,$e=Ar(r.entries,y,W.sort,_,R.backupReminderMonths);if(Qe){let e=new Set($e.map(e=>e.id));$e=[...$e,...r.entries.filter(t=>!e.has(t.id)&&Qe.groupOf.has(t.id))]}let et=Nr($e,W.groupBy);Qe&&(et=Fr(et,Qe)),Ze.current={key:Xe,snapshot:Pr(et)};let tt=V({updateEntry:Ue,deleteEntry:We,duplicateEntry:K,setEntryEditing:Ve});tt.current={updateEntry:Ue,deleteEntry:We,duplicateEntry:K,setEntryEditing:Ve};let Y=V(new Map),nt=e=>{let t=Y.current.get(e);return t||(t={onUpdate:t=>tt.current.updateEntry(e,t),onDelete:()=>tt.current.deleteEntry(e),onDuplicate:()=>tt.current.duplicateEntry(e),onEditing:t=>tt.current.setEntryEditing(e,t)},Y.current.set(e,t)),t},X=e=>R.lockSavedEntries?ce.has(e)?`editing`:`locked`:`off`,at=W.layout===`stacked`;B(()=>{le(e=>{let t=e=>at?x.has(e):h.type===`entry`&&h.id===e,n=new Set([...e].filter(t));return n.size===e.size?e:n})},[x,h,at]);let ot=H(`div`,{class:`empty`,children:[H(U,{name:`shield`,size:28}),H(`p`,{children:H(`strong`,{children:`No keys yet.`})}),H(`p`,{class:`small muted`,children:`Keep crypto seed phrases and wallet keys here, and also SSH, PGP and API keys, recovery codes and any other secret. Each one folds into a single line until you open it, and secrets stay hidden until you reveal them.`}),!L&&H(C,{children:[H(`p`,{class:`small`,children:`What do you want to add first?`}),H(`div`,{class:`kind-choices`,role:`group`,"aria-label":`Add your first entry`,children:Je.map(e=>H(`button`,{type:`button`,class:`button small`,onClick:()=>He(e),children:[H(U,{name:_n[e]}),` `,hn[e]]}))}),H(`p`,{class:`small muted`,children:`Add more of any type later with the Add (+) button.`}),H(`p`,{class:`small`,children:H(`button`,{type:`button`,class:`link-button`,onClick:()=>se(!0),children:`Restore a backup file`})})]})]}),st=r.entries.length>0&&r.entries.every(e=>e.archived)&&y!==`archived`?H(`p`,{class:`empty small muted`,children:[`Every entry is archived.`,` `,H(`button`,{type:`button`,class:`link-button`,onClick:()=>b(`archived`),children:`Show archived entries`})]}):H(`p`,{class:`empty small muted`,children:`No entries match.`}),ct;switch(t.name){case`connecting`:ct=H(ji,{slow:p});break;case`locked`:ct=H(Di,{onUnlock:Te,autoFocus:t.autoFocus,exportedAt:t.exportedAt});break;case`foreign`:ct=H(Oi,{length:t.text.length,readOnly:a,onConvert:()=>Ke(t.text)});break;case`newer`:ct=H(ki,{version:t.version});break;case`unsupported`:ct=H(Ai,{});break;case`ready`:{let t=H(qr,{query:_,onQuery:v,filter:y,onFilter:b,dueCount:J,shown:$e.length,total:r.entries.filter(e=>y===`archived`?e.archived:!e.archived).length,readOnly:L,onAdd:He,view:W,onView:Le,onExpandAll:()=>{T(new Set),S(new Set($e.map(e=>e.id)))},onCollapseAll:()=>{k(null),S(new Set)},onSettings:()=>g({type:`settings`}),hasPassword:s,onLock:()=>Se(!0),onHideAll:()=>{u(e=>e+1),le(new Set)}});ct=h.type===`settings`?H(`main`,{class:`detail full`,children:H(Ci,{vault:r,settings:R,hasPassword:s,onChange:Ge,onSetPassword:De,onChangePassword:Oe,onRemovePassword:ke,onExport:je,onExported:e=>Ge({lastExportedAt:e.exportedAt}),onCopyBackup:Me,mobileApp:e.inMobileApp(),onLock:()=>Se(!0),onClose:()=>g({type:`list`})})}):W.layout===`stacked`?H(C,{children:[t,H(`main`,{class:`detail full`,children:r.entries.length===0?ot:$e.length===0?st:H(Ur,{groups:et,expanded:x,collapsedGroups:w,reminderMonths:R.backupReminderMonths,newId:te,lockFor:X,onToggle:Re,onToggleGroup:ze,handlersFor:nt})})]}):H(C,{children:[t,H(`div`,{class:`layout ${q?`has-detail`:``}`,children:[H(`aside`,{class:`sidebar`,children:r.entries.length===0?ot:$e.length===0?st:H(Br,{groups:et,collapsedGroups:w,selectedId:q?.id??null,reminderMonths:R.backupReminderMonths,onSelect:e=>{k(null),g({type:`entry`,id:e})},onToggleGroup:ze})}),H(`main`,{class:`detail`,children:q?H(Er,{entry:q,lock:X(q.id),reminderMonths:R.backupReminderMonths,focusLabel:q.id===te,onBack:()=>{k(null),g({type:`list`})},...nt(q.id)},q.id):H(`div`,{class:`placeholder muted`,children:[H(U,{name:`shield`,size:36}),H(`p`,{children:`Select an entry, or add a new one.`})]})})]})]}),oe&&r.entries.length===0&&!L&&(ct=H(Ei,{mobileApp:e.inMobileApp(),vaultHasPassword:s,onRestore:Ae,onCancel:()=>se(!1)}))}}return H(Dt.Provider,{value:Ie,children:[H(`div`,{class:`app ${W.density} ${R.privacyScreen&&!d&&t.name===`ready`?`privacy`:``}`,children:[e.mode===`demo`&&H(`div`,{class:`banner banner-warn`,role:`note`,children:[H(U,{name:`alert`}),` Demo mode: not connected to Standard Notes, nothing is saved. Do not type real secrets here. To install, add `,H(`code`,{children:new URL(`ext.json`,location.href).href}),` in Standard Notes → Preferences → Plugins.`,` `,`Lost access to Keyfold? `,H(`a`,{href:`#open`,onClick:()=>setTimeout(()=>location.reload()),children:`Open a backup or note read-only`}),`.`]}),e.mode===`viewer`&&H(`div`,{class:`banner`,role:`note`,children:[H(U,{name:`lock`}),` Read-only viewer: nothing you open here is saved or sent anywhere.`,H(`button`,{type:`button`,class:`link-button`,onClick:()=>location.reload(),children:`Close`})]}),he&&t.name===`ready`&&H(`div`,{class:`banner`,role:`note`,children:[H(U,{name:`alert`}),` This vault was saved by a newer version of Keyfold, so it is read-only here. Update the plugin in Standard Notes (Preferences → Plugins) to edit it.`]}),a&&e.mode!==`viewer`&&t.name===`ready`&&H(`div`,{class:`banner`,role:`note`,children:[H(U,{name:`lock`}),` "Prevent editing" is on for this note. You can still reveal and copy secrets.`]}),ct,R.privacyScreen&&!d&&t.name===`ready`&&H(`button`,{type:`button`,class:`privacy-cover`,onClick:()=>{window.focus(),f(!0)},children:[H(U,{name:`eyeOff`,size:28}),H(`span`,{children:Mt()?`Tap to show the vault`:`Click to show the vault`})]})]}),Hi,Vi,ie&&H(Mi,{dialog:ie,onClose:e=>{ie.resolve(e),ae(null)}}),H(Ni,{toasts:ne,onDismiss:e=>re(t=>t.filter(t=>t.id!==e))})]})},Gi=()=>typeof crypto.randomUUID==`function`?crypto.randomUUID():Array.from(crypto.getRandomValues(new Uint8Array(16)),e=>e.toString(16).padStart(2,`0`)).join(``),Ki=e=>e&&/^https?:\/\//.test(e)?e:`*`,qi=`https://app.standardnotes.com/components/assets/`,Ji=e=>{if(/^https?:\/\//i.test(e)||/^data:text\/css[;,]/i.test(e))return e;let t=/\/components\/assets\/([a-z0-9][a-z0-9.-]*)\/([\w.-]+(?:\/[\w.-]+)*\.css)$/i.exec(e);if(t&&!t[0].includes(`..`))return`${qi}${t[1]}/${t[2]}`},Yi=2e3,Xi=[`Shift`,`Alt`,`Control`,`Meta`,`AltGraph`],Zi=class{win;sessionKey;origin;environment;queue=[];callbacks=new Map;themeLoads=new WeakMap;themeGeneration=0;constructor(e=window){this.win=e,e.addEventListener(`message`,this.onMessage),e.addEventListener(`click`,this.onClick),e.addEventListener(`keydown`,this.onKey),e.addEventListener(`keyup`,this.onKey),setTimeout(this.reveal,Yi)}get inMobileApp(){return this.environment===`native-mobile-web`||this.environment===`mobile`}streamContextItem(e){this.send(`stream-context-item`,{},t=>t?.item&&e(t.item),!0)}saveItem(e,t){this.send(`save-items`,{items:[e]},()=>t?.())}send(e,t,n,r=!1){if(!this.sessionKey){this.queue.push({action:e,data:t,callback:n,keep:r});return}let i={action:e,data:t,messageId:Gi(),sessionKey:this.sessionKey,api:`component`};n&&this.callbacks.set(i.messageId,{callback:n,keep:r});let a=this.environment===`mobile`?JSON.stringify(i):i;this.win.parent.postMessage(a,Ki(this.origin))}onMessage=e=>{if(e.source!==this.win.parent||this.win.parent===this.win)return;let t;try{t=typeof e.data==`string`?JSON.parse(e.data):e.data}catch{return}if(t&&typeof t==`object`)switch(t.action){case`component-registered`:if(this.sessionKey||!t.sessionKey)return;this.sessionKey=t.sessionKey,this.origin=e.origin,this.environment=t.data?.environment,this.activateThemes(t.data?.activeThemeUrls),this.send(`themes-activated`,{});for(let e of this.queue.splice(0))this.send(e.action,e.data,e.callback,e.keep);return;case`themes`:this.activateThemes(t.data?.themes);return;case`reply`:{let e=t.original?.messageId,n=e?this.callbacks.get(e):void 0;if(!n)return;n.keep||this.callbacks.delete(e),n.callback(t.data);return}}};onClick=()=>{this.sessionKey&&this.send(`click`,{})};onKey=e=>{if(!this.sessionKey)return;let t=Xi.includes(e.key),n=e.type===`keyup`&&t;(!e.getModifierState?.(`AltGraph`)||t)&&(e.ctrlKey||e.metaKey||e.key===`Control`||e.key===`Meta`||n)&&(e.type===`keydown`&&(e.ctrlKey||e.metaKey)&&e.key.toLowerCase()===`s`&&e.preventDefault(),this.send(e.type===`keydown`?`key-down`:`key-up`,{key:e.key,code:e.code,ctrlKey:e.ctrlKey,metaKey:e.metaKey,shiftKey:e.shiftKey,altKey:e.altKey}))};activateThemes(e){let t=Array.isArray(e)?e.filter(e=>typeof e==`string`):[],n=[...new Set(t.map(Ji).filter(e=>!!e))],r=this.win.document,i=[...r.querySelectorAll(`link[data-sn-theme]`)],a=[];for(let e of n){let t=i.find(t=>t.getAttribute(`href`)===e);if(t){a.push(this.themeLoads.get(t)??Promise.resolve());continue}let n=r.createElement(`link`),o=new Promise(e=>{n.onload=n.onerror=e});this.themeLoads.set(n,o),a.push(o),n.rel=`stylesheet`,n.href=e,n.setAttribute(`data-sn-theme`,``),r.head.appendChild(n)}let o=++this.themeGeneration;Promise.all(a).then(()=>{if(o===this.themeGeneration){for(let e of i)n.includes(e.getAttribute(`href`)??``)||e.remove();this.updateColorScheme(),this.reveal()}})}updateColorScheme(){let e=this.win.document,t=/^rgba?\(([^)]*)\)/.exec(this.win.getComputedStyle(e.body).backgroundColor)?.[1].split(/[\s,/]+/).map(Number);if(!t||t.length<3||t[3]===0)return;let n=.2126*t[0]+.7152*t[1]+.0722*t[2];e.documentElement.style.colorScheme=n<128?`dark`:`light`}reveal=()=>{this.win.document.documentElement.classList.remove(`theme-pending`)}},Qi=e=>e.content?.appData?.[`org.standardnotes.sn`]?.locked===!0,$i=`authentication`,ea=e=>{e.content?.noteType===$i&&(e.content.noteType=`unknown`)},ta=()=>{let e=new Zi(window),t=null;return{mode:`standardnotes`,inMobileApp:()=>e.inMobileApp,subscribe(n){e.streamContextItem(e=>{t=e,n({text:e.content?.text??``,locked:Qi(e),metadataOnly:e.isMetadataUpdate===!0})})},save(n,r){let i=t;i&&(i.content.text=n,i.content.preview_plain=r,i.content.preview_html=``,ea(i),e.saveItem(i))}}},na=e=>{let t=e;return{mode:`demo`,inMobileApp:()=>!1,subscribe(e){queueMicrotask(()=>e({text:t,locked:!1,metadataOnly:!1}))},save(e){t=e}}},ra=e=>({mode:`viewer`,inMobileApp:()=>!1,subscribe(t){queueMicrotask(()=>t({text:e,locked:!0,metadataOnly:!1}))},save(){}}),ia=()=>{try{return window.parent!==window}catch{return!0}},aa=e=>e.split(` `),oa=e=>{let t=new Uint8Array(4+e.length);return new DataView(t.buffer).setUint32(0,e.length),t.set(e,4),t},sa=(...e)=>{let t=new Uint8Array(e.reduce((e,t)=>e+t.length,0)),n=0;for(let r of e)t.set(r,n),n+=r.length;return t},ca=()=>{let e=sa(oa(G(`ssh-ed25519`)),oa(q(32)));return{privateKey:`-----BEGIN OPENSSH PRIVATE KEY-----\n${Ve(sa(G(`openssh-key-v1\0`),oa(G(`aes256-ctr`)),oa(G(`bcrypt`)),oa(q(24)),new Uint8Array([0,0,0,1]),oa(e),oa(q(144)))).match(/.{1,70}/g).join(` +`)}\n-----END OPENSSH PRIVATE KEY-----`,publicKey:`ssh-ed25519 ${Ve(e)} demo@example`}},la=(e,t=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`)=>Array.from(q(e),e=>t[e%t.length]).join(``),ua=e=>{let t=new Date;return t.setDate(t.getDate()+e),t.toISOString().slice(0,10)},da=()=>{let e=ca(),t=rt();return t.entries.push(it(`mnemonic`,{label:`Example: cold storage`,description:`Public BIP39 test vector. Do not send funds to it.`,chain:`Bitcoin`,wallet:`Coldcard`,tags:[`example`,`long-term`],favorite:!0,words:aa(`legal winner thank year wave sausage worth useful legal winner thank yellow`),passphrase:`example passphrase`,passphraseHint:`Example hint only`,derivationPath:`m/84'/0'/0'`,createdOn:`2021-03-14`,backups:[{id:`b1`,location:`Steel plate in home safe`,verifiedOn:nt()}]}),it(`mnemonic`,{label:`Example: multisig key 2 of 3`,chain:`Bitcoin`,wallet:`Trezor`,tags:[`example`,`multisig`],words:aa(`letter advice cage absurd amount doctor acoustic avoid letter advice cage above`),derivationPath:`m/48'/0'/0'/2'`,createdOn:`2022-08-02`,backups:[{id:`b2`,location:`Bank deposit box`,verifiedOn:`2025-01-10`}]}),it(`mnemonic`,{label:`Example: DeFi hot wallet`,chain:`Ethereum`,wallet:`MetaMask`,tags:[`example`],words:aa(`${`abandon `.repeat(23)}art`),derivationPath:`m/44'/60'/0'/0/0`,createdOn:`2023-11-20`}),it(`privateKey`,{label:`Example: paper wallet`,description:`WIF test vector from the Bitcoin wiki.`,chain:`Bitcoin`,tags:[`example`],secret:`5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ`,createdOn:`2013-04-01`}),it(`sshKey`,{label:`Example: deploy key`,description:`Random bytes in OpenSSH format, not a working key.`,service:`github.com`,account:`git`,tags:[`example`],secret:e.privateKey,passphrase:`example passphrase`,publicInfo:e.publicKey,expiresOn:ua(365)}),it(`apiKey`,{label:`Example: CI token`,description:`Random characters in GitHub token format, not a real token.`,service:`GitHub`,account:`release workflow`,tags:[`example`],secret:`ghp_${la(36)}`,expiresOn:ua(12)}),it(`recoveryCodes`,{label:`Example: exchange 2FA backup codes`,service:`Kraken`,account:`you@example.com`,tags:[`example`],secret:Array.from({length:8},()=>`${la(4,`0123456789`)}-${la(4,`0123456789`)}`).join(` +`)})),t.entries.forEach((e,t)=>e.updatedAt=new Date(Date.now()-t*6e4).toISOString()),bt(t)},fa=document.documentElement.hasAttribute(`data-viewer`),pa=!fa&&ia();document.documentElement.classList.toggle(`standalone`,!pa),pa||document.documentElement.classList.remove(`theme-pending`);var ma=document.getElementById(`app`);pa?M(H(Wi,{host:ta()}),ma):fa||location.hash===`#open`?M(H(Ti,{offlineViewer:fa,onOpen:e=>M(H(Wi,{host:ra(e)}),ma)}),ma):M(H(Wi,{host:na(da())}),ma)})();