Feat v0.6.3 dead code sweep #38

Merged
xcaliber merged 10 commits from feat/v0.6.3-dead-code-sweep into main 2026-03-31 12:37:48 +00:00
4 changed files with 0 additions and 756 deletions
Showing only changes of commit 705aa08642 - Show all commits

View File

@@ -1,676 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Switchboard Core — Dev Gallery</title>
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/sw-primitives.css">
<link rel="stylesheet" href="css/sw-shell.css">
<style>
body { overflow: auto; padding: 0; }
.dev-root { height: 100vh; display: flex; flex-direction: column; }
.dev-nav { display: flex; gap: 0; border-bottom: 1px solid var(--border); background: var(--bg-surface); flex-shrink: 0; padding: 0 1rem; }
.dev-nav button {
padding: 0.6rem 1.2rem; background: none; border: none; border-bottom: 2px solid transparent;
color: var(--text-2); font-family: var(--font); font-size: 0.85rem; font-weight: 500; cursor: pointer;
}
.dev-nav button:hover { color: var(--text); }
.dev-nav button.active { color: var(--accent); border-bottom-color: var(--accent); }
.dev-page { flex: 1; overflow: auto; }
.gallery { max-width: 800px; margin: 0 auto; padding: 2rem; }
.gallery h1 { font-size: 1.5rem; margin-bottom: 0.25rem; }
.gallery .subtitle { color: var(--text-2); margin-bottom: 2rem; font-size: 0.9rem; }
.section { margin-bottom: 2.5rem; }
.section h2 {
font-size: 0.85rem; font-weight: 600; text-transform: uppercase;
letter-spacing: 0.5px; color: var(--text-3); margin-bottom: 0.75rem;
padding-bottom: 0.5rem; border-bottom: 1px solid var(--border);
}
.row { display: flex; gap: 0.75rem; align-items: center; flex-wrap: wrap; margin-bottom: 0.75rem; }
.col { display: flex; flex-direction: column; gap: 0.75rem; }
.spacer { height: 0.5rem; }
.shell-demo { height: 100%; }
.shell-demo .sw-shell { height: 100%; }
</style>
</head>
<body>
<div id="app"></div>
<script type="module">
(async () => {
try {
const { h, render } = await import('./js/sw/vendor/preact.module.js');
const hooksModule = await import('./js/sw/vendor/hooks.module.js?v=2');
const { default: htm } = await import('./js/sw/vendor/htm.module.js');
const html = htm.bind(h);
const { useState, useEffect, useRef, useMemo, useCallback } = hooksModule;
window.preact = { h, render };
window.hooks = hooksModule;
window.html = html;
const { Button } = await import('./js/sw/primitives/button.js');
const { Spinner } = await import('./js/sw/primitives/spinner.js');
const { Avatar } = await import('./js/sw/primitives/avatar.js');
const { FormField } = await import('./js/sw/primitives/form-field.js');
const { Tooltip } = await import('./js/sw/primitives/tooltip.js');
const { Banner } = await import('./js/sw/primitives/banner.js');
const { Dialog } = await import('./js/sw/primitives/dialog.js');
const { toast, ToastContainer } = await import('./js/sw/primitives/toast.js');
const { Menu } = await import('./js/sw/primitives/menu.js');
const { Drawer } = await import('./js/sw/primitives/drawer.js');
const { Tabs } = await import('./js/sw/primitives/tabs.js');
const { Dropdown } = await import('./js/sw/primitives/dropdown.js');
const { AppShell } = await import('./js/sw/shell/app-shell.js');
const { UserMenu } = await import('./js/sw/shell/user-menu.js');
const { SurfaceViewport } = await import('./js/sw/shell/surface-viewport.js');
const { DialogStack } = await import('./js/sw/shell/dialog-stack.js');
const { confirm } = await import('./js/sw/primitives/confirm.js');
const { prompt } = await import('./js/sw/primitives/prompt.js');
// ── SDK Boot ────────────────────────────
const { boot } = await import('./js/sw/sdk/index.js');
await boot().catch(e => console.warn('SDK boot (no backend):', e));
const sw = window.sw;
// ── SDK Demo Page ───────────────────────
function SDKPage() {
const [authState, setAuthState] = useState(null);
const [apiResult, setApiResult] = useState(null);
const [permInput, setPermInput] = useState('model.use');
const [canResult, setCanResult] = useState(null);
const [eventLog, setEventLog] = useState([]);
const [emitLabel, setEmitLabel] = useState('test.event');
const logRef = useRef([]);
// Subscribe to all events for live log
useEffect(() => {
const unsub = sw.on('*', (payload, meta) => {
const entry = { ts: new Date().toLocaleTimeString(), label: meta.event, local: meta.local };
logRef.current = [entry, ...logRef.current].slice(0, 20);
setEventLog([...logRef.current]);
});
return unsub;
}, []);
function refreshAuth() {
setAuthState({
isAuthenticated: sw.auth.isAuthenticated,
user: sw.auth.user,
permissions: [...sw.auth.permissions],
teams: sw.auth.teams,
policies: sw.auth.policies,
});
}
useEffect(() => { refreshAuth(); }, []);
async function testApi() {
try {
const res = await sw.api.channels.list();
setApiResult({ ok: true, data: res });
} catch (e) {
setApiResult({ ok: false, error: e.message });
}
}
function testCan() {
setCanResult(sw.can(permInput));
}
const monoStyle = 'font-family: var(--font-mono, monospace); font-size: 0.8rem; background: var(--bg-1); padding: 0.75rem; border-radius: 6px; overflow: auto; max-height: 200px; white-space: pre-wrap; word-break: break-all; color: var(--text-2);';
return html`
<div class="gallery">
<h1>SDK Demo</h1>
<p class="subtitle">Layer 1 — SDK modules (v0.37.3)</p>
<!-- Auth State -->
<div class="section">
<h2>sw.auth</h2>
<div class="row" style="margin-bottom:0.5rem">
<${Button} variant="secondary" size="sm" onClick=${refreshAuth}>Refresh<//>
</div>
<div style=${monoStyle}>${JSON.stringify(authState, null, 2)}</div>
</div>
<!-- API Test -->
<div class="section">
<h2>sw.api</h2>
<div class="row" style="margin-bottom:0.5rem">
<${Button} variant="secondary" size="sm" onClick=${testApi}>sw.api.channels.list()<//>
</div>
${apiResult && html`
<div style=${monoStyle}>
${apiResult.ok
? JSON.stringify(apiResult.data, null, 2)
: 'Error: ' + apiResult.error}
</div>
`}
</div>
<!-- RBAC Test -->
<div class="section">
<h2>sw.can()</h2>
<div class="row">
<input class="sw-input" style="width:180px" value=${permInput}
onInput=${e => setPermInput(e.target.value)} />
<${Button} variant="secondary" size="sm" onClick=${testCan}>Check<//>
${canResult !== null && html`
<span style="font-weight:600; color: ${canResult ? 'var(--success)' : 'var(--danger)'}">
${canResult ? 'ALLOWED' : 'DENIED'}
</span>
`}
</div>
<div class="row" style="margin-top:0.5rem">
<span style="color:var(--text-3); font-size:0.8rem">
sw.isAdmin: ${String(sw.isAdmin)}
</span>
</div>
</div>
<!-- Theme -->
<div class="section">
<h2>sw.theme</h2>
<div class="row">
<span style="color:var(--text-2); font-size:0.85rem">
mode: ${sw.theme.mode} · resolved: ${sw.theme.current}
</span>
</div>
<div class="row">
<${Button} variant="secondary" size="sm" onClick=${() => sw.theme.set('light')}>Light<//>
<${Button} variant="secondary" size="sm" onClick=${() => sw.theme.set('dark')}>Dark<//>
<${Button} variant="secondary" size="sm" onClick=${() => sw.theme.set('system')}>System<//>
</div>
</div>
<!-- Events -->
<div class="section">
<h2>sw.on / sw.emit</h2>
<div class="row" style="margin-bottom:0.5rem">
<input class="sw-input" style="width:180px" value=${emitLabel}
onInput=${e => setEmitLabel(e.target.value)} />
<${Button} variant="secondary" size="sm"
onClick=${() => sw.emit(emitLabel, { demo: true }, { localOnly: true })}>Emit<//>
</div>
<div style=${monoStyle + ' max-height:160px;'}>
${eventLog.length === 0 ? '(listening for events...)' :
eventLog.map(e => `${e.ts} ${e.local ? 'L' : 'R'} ${e.label}`).join('\n')}
</div>
</div>
<!-- Pipe -->
<div class="section">
<h2>sw.pipe</h2>
<div style=${monoStyle}>${JSON.stringify(sw.pipe.list(), null, 2)}</div>
</div>
<!-- Namespaces -->
<div class="section">
<h2>sw.api namespaces</h2>
<div style=${monoStyle}>${Object.keys(sw.api).filter(k => typeof sw.api[k] === 'object').join(', ')}</div>
</div>
</div>
`;
}
// ── Shell Demo Page ──────────────────────
function ShellPage() {
const [confirmResult, setConfirmResult] = useState(null);
const [promptResult, setPromptResult] = useState(null);
return html`
<div class="gallery">
<h1>Shell Demo</h1>
<p class="subtitle">Layer 2 — Application shell (v0.37.4)</p>
<!-- UserMenu -->
<div class="section">
<h2>UserMenu</h2>
<div class="row">
<${UserMenu} />
<${UserMenu} placement="down-left" />
</div>
<p style="color:var(--text-3); font-size:0.8rem; margin-top:0.5rem">
RBAC-gated flyout. Without backend, shows all items for demo.
</p>
</div>
<!-- Imperative Confirm -->
<div class="section">
<h2>sw.confirm()</h2>
<div class="row">
<${Button} variant="secondary" onClick=${async () => {
const ok = await sw.confirm('Delete this item?', { destructive: true });
setConfirmResult(ok);
}}>Confirm (destructive)<//>
<${Button} variant="secondary" onClick=${async () => {
const ok = await sw.confirm('Proceed with this action?');
setConfirmResult(ok);
}}>Confirm (normal)<//>
${confirmResult !== null && html`
<span style="font-weight:600; color: ${confirmResult ? 'var(--success)' : 'var(--danger)'}">
Result: ${String(confirmResult)}
</span>
`}
</div>
</div>
<!-- Imperative Prompt -->
<div class="section">
<h2>sw.prompt()</h2>
<div class="row">
<${Button} variant="secondary" onClick=${async () => {
const val = await sw.prompt('Enter a name:', { defaultValue: 'untitled' });
setPromptResult(val);
}}>Prompt<//>
${promptResult !== null && html`
<span style="font-weight:600; color:var(--text-2)">
Result: ${JSON.stringify(promptResult)}
</span>
`}
</div>
</div>
<!-- Surface Viewport -->
<div class="section">
<h2>SurfaceViewport</h2>
<p style="color:var(--text-3); font-size:0.8rem; margin-bottom:0.5rem">
UserMenu is placed by the surface (top-right), not the shell.
</p>
<div style="border:1px dashed var(--border); border-radius:var(--radius, 6px); height:200px; position:relative; overflow:hidden;">
<${SurfaceViewport} surface=${html`
<div style="padding:1rem; color:var(--text-2); height:100%;">
<p>Mock surface content. The shell provides the viewport; the surface owns everything inside.</p>
<div style="position:absolute; top:0.5rem; right:0.5rem;">
<${UserMenu} placement="down-left" />
</div>
</div>
`} />
</div>
</div>
<!-- App component tree -->
<div class="section">
<h2>App Component Tree</h2>
<div style="font-family:var(--font-mono, monospace); font-size:0.8rem; color:var(--text-2); background:var(--bg-1); padding:0.75rem; border-radius:6px; white-space:pre;">${
`<App>
<AppShell banner message footer>
<SurfaceViewport surface={...} />
</AppShell>
<ToastContainer />
<DialogStack />
</App>`
}</div>
</div>
</div>
`;
}
// ── Surfaces Demo Page ────────────────────
function SurfacesPage() {
return html`
<div class="gallery">
<h1>Surfaces Demo</h1>
<p class="subtitle">v0.37.5 — Login + Settings surfaces</p>
<div class="section">
<h2>Login Surface</h2>
<p style="color:var(--text-3); font-size:0.85rem; margin-bottom:0.75rem">
The login surface is a standalone page (not embedded in AppShell).
It renders at /login with its own layout: Hero panel + Auth panel.
</p>
<div style="font-family:var(--font-mono, monospace); font-size:0.8rem; color:var(--text-2); background:var(--bg-1); padding:0.75rem; border-radius:6px; white-space:pre;">${
`<LoginSurface>
<Hero />
<AuthPanel>
authMode === 'builtin':
<LoginForm /> — sw.auth.login()
<RegisterForm /> — sw.api.auth.register()
authMode === 'oidc' | 'mtls':
<SSOPanel />
</AuthPanel>
</LoginSurface>`
}</div>
<p style="color:var(--text-3); font-size:0.8rem; margin-top:0.5rem">
Files: src/js/sw/surfaces/login/
</p>
</div>
<div class="section">
<h2>Settings Surface</h2>
<p style="color:var(--text-3); font-size:0.85rem; margin-bottom:0.75rem">
Full Preact surface with left nav + section routing.
Core sections (General, Appearance, Profile, Teams, Models, Providers,
Personas, Roles, Usage) are native Preact components.
Deferred sections use BridgeSection wrappers.
</p>
<div style="font-family:var(--font-mono, monospace); font-size:0.8rem; color:var(--text-2); background:var(--bg-1); padding:0.75rem; border-radius:6px; white-space:pre;">${
`<SettingsSurface>
<Topbar />
<Nav>
General, Appearance, Models, Personas, Profile,
Teams, Workflows, Tasks, Git Keys, Data & Privacy
[BYOK] Providers, Roles, Usage
</Nav>
<Content>
section === 'general' → <GeneralSection />
section === 'appearance' → <AppearanceSection />
section === 'profile' → <ProfileSection />
section === 'teams' → <TeamsSection />
section === 'models' → <ModelsSection />
section === 'providers' → <ProvidersSection />
section === 'personas' → <PersonasSection />
section === 'roles' → <RolesSection />
section === 'usage' → <UsageSection />
section === 'tasks' etc → <BridgeSection /> (old JS)
</Content>
</SettingsSurface>`
}</div>
<p style="color:var(--text-3); font-size:0.8rem; margin-top:0.5rem">
Files: src/js/sw/surfaces/settings/
</p>
</div>
</div>
`;
}
function PrimitivesPage() {
const [dialogOpen, setDialogOpen] = useState(false);
const [drawerOpen, setDrawerOpen] = useState(false);
const [menuOpen, setMenuOpen] = useState(false);
const [activeTab, setActiveTab] = useState('tab1');
const [dropVal, setDropVal] = useState('opt2');
const [loading, setLoading] = useState(false);
const menuAnchor = useRef(null);
return html`
<div class="gallery">
<h1>Primitives Gallery</h1>
<p class="subtitle">Layer 0 — Preact + htm components (v0.37.2)</p>
<!-- Buttons -->
<div class="section">
<h2>Button</h2>
<div class="row">
<${Button} variant="primary">Primary<//>
<${Button} variant="secondary">Secondary<//>
<${Button} variant="danger">Danger<//>
<${Button} variant="ghost">Ghost<//>
</div>
<div class="row">
<${Button} size="sm">Small<//>
<${Button} size="md">Medium<//>
<${Button} size="lg">Large<//>
</div>
<div class="row">
<${Button} disabled>Disabled<//>
<${Button} loading=${true}>Loading<//>
</div>
</div>
<!-- Spinner -->
<div class="section">
<h2>Spinner</h2>
<div class="row">
<${Spinner} size="sm" />
<${Spinner} size="md" />
<${Spinner} size="lg" />
</div>
</div>
<!-- Avatar -->
<div class="section">
<h2>Avatar</h2>
<div class="row">
<${Avatar} name="Jane Doe" size="sm" />
<${Avatar} name="Jane Doe" size="md" />
<${Avatar} name="Jane Doe" size="lg" />
<${Avatar} name="X" size="md" />
<${Avatar} src="https://i.pravatar.cc/48" name="Photo" size="lg" />
</div>
</div>
<!-- FormField -->
<div class="section">
<h2>FormField</h2>
<div class="col" style="max-width:320px">
<${FormField} label="Username" required>
<input class="sw-input" placeholder="Enter username" />
<//>
<${FormField} label="Email" error="Invalid email address">
<input class="sw-input" value="bad@" />
<//>
<${FormField} label="Bio" hint="Optional, max 200 chars">
<textarea class="sw-input" rows="2" placeholder="Tell us about yourself" />
<//>
</div>
</div>
<!-- Tooltip -->
<div class="section">
<h2>Tooltip</h2>
<div class="row">
<${Tooltip} content="Top tooltip">
<${Button} variant="secondary">Hover me (top)<//>
<//>
<${Tooltip} content="Bottom tooltip" position="bottom">
<${Button} variant="secondary">Bottom<//>
<//>
<${Tooltip} content="Right tooltip" position="right">
<${Button} variant="secondary">Right<//>
<//>
</div>
</div>
<!-- Banner -->
<div class="section">
<h2>Banner</h2>
<div class="col">
<${Banner} text="Informational banner message" variant="info" />
<${Banner} text="Warning: maintenance scheduled" variant="warn" dismissible />
<${Banner} text="Error: service unavailable" variant="error" />
<${Banner} text="Successfully deployed v0.37.2" variant="success" dismissible />
</div>
</div>
<!-- Tabs -->
<div class="section">
<h2>Tabs</h2>
<${Tabs}
tabs=${[
{ label: 'General', value: 'tab1' },
{ label: 'Appearance', value: 'tab2' },
{ label: 'Notifications', value: 'tab3' },
{ label: 'Disabled', value: 'tab4', disabled: true },
]}
active=${activeTab}
onChange=${setActiveTab}
/>
<div style="padding: 1rem 0; color: var(--text-2); font-size: 0.9rem">
Active tab: ${activeTab}
</div>
</div>
<!-- Dropdown -->
<div class="section">
<h2>Dropdown</h2>
<div class="row">
<div style="width:220px">
<${Dropdown}
options=${[
{ label: 'Claude Sonnet', value: 'opt1' },
{ label: 'Claude Opus', value: 'opt2' },
{ label: 'Claude Haiku', value: 'opt3' },
{ label: 'GPT-4o', value: 'opt4' },
{ label: 'Disabled', value: 'opt5', disabled: true },
]}
value=${dropVal}
onChange=${setDropVal}
searchable
/>
</div>
</div>
</div>
<!-- Menu -->
<div class="section">
<h2>Menu</h2>
<div class="row">
<${Button} ref=${menuAnchor} variant="secondary"
onClick=${() => setMenuOpen(!menuOpen)}>
Open Menu
<//>
<${Menu}
open=${menuOpen}
anchor=${menuAnchor.current}
items=${[
{ label: 'Settings', action: 'settings', icon: '\u2699' },
{ label: 'Profile', action: 'profile', icon: '\ud83d\udc64' },
{ divider: true },
{ label: 'Submenu', children: [
{ label: 'Option A', action: 'a' },
{ label: 'Option B', action: 'b' },
]},
{ divider: true },
{ label: 'Disabled', action: 'x', disabled: true },
{ label: 'Sign Out', action: 'logout' },
]}
onSelect=${(action) => { toast.info('Selected: ' + action); }}
onClose=${() => setMenuOpen(false)}
/>
</div>
</div>
<!-- Dialog -->
<div class="section">
<h2>Dialog</h2>
<div class="row">
<${Button} onClick=${() => setDialogOpen(true)}>Open Dialog<//>
</div>
<${Dialog}
open=${dialogOpen}
title="Example Dialog"
onClose=${() => setDialogOpen(false)}
actions=${[
{ label: 'Cancel', variant: 'secondary', onClick: () => setDialogOpen(false) },
{ label: 'Confirm', variant: 'primary', onClick: () => { setDialogOpen(false); toast.success('Confirmed!'); } },
]}
>
<p>This is a modal dialog with focus trapping, Escape to close, and backdrop click to dismiss.</p>
<//>
</div>
<!-- Drawer -->
<div class="section">
<h2>Drawer</h2>
<div class="row">
<${Button} variant="secondary" onClick=${() => setDrawerOpen(true)}>Open Drawer<//>
</div>
<${Drawer}
open=${drawerOpen}
title="Settings"
onClose=${() => setDrawerOpen(false)}
>
<p style="color: var(--text-2)">Slide-in panel for settings, admin sections, etc.</p>
<div class="spacer" />
<${FormField} label="Display Name">
<input class="sw-input" value="Jane Doe" />
<//>
<//>
</div>
<!-- Toast -->
<div class="section">
<h2>Toast</h2>
<div class="row">
<${Button} variant="secondary" onClick=${() => toast.success('Operation successful')}>Success<//>
<${Button} variant="secondary" onClick=${() => toast.error('Something went wrong')}>Error<//>
<${Button} variant="secondary" onClick=${() => toast.warn('Check your settings')}>Warning<//>
<${Button} variant="secondary" onClick=${() => toast.info('New message received')}>Info<//>
</div>
</div>
</div>
`;
}
const VARIANTS = ['info', 'warn', 'error', 'success'];
function ShellControls({ bannerOn, setBannerOn, bannerVariant, setBannerVariant, bannerText, setBannerText,
msgOn, setMsgOn, msgVariant, setMsgVariant, msgText, setMsgText,
footerOn, setFooterOn }) {
return html`
<div style="display:flex; align-items:center; gap:0.75rem; padding:0.4rem 0; flex-wrap:wrap;">
<${Button} variant=${bannerOn ? 'primary' : 'secondary'} size="sm"
onClick=${() => setBannerOn(!bannerOn)}>Banner<//>
${bannerOn && html`
<${Dropdown} options=${VARIANTS.map(v => ({ label: v, value: v }))}
value=${bannerVariant} onChange=${setBannerVariant} />
<input class="sw-input" style="width:140px" placeholder="text..."
value=${bannerText} onInput=${e => setBannerText(e.target.value)} />
`}
<${Button} variant=${msgOn ? 'primary' : 'secondary'} size="sm"
onClick=${() => setMsgOn(!msgOn)}>Message<//>
${msgOn && html`
<${Dropdown} options=${VARIANTS.map(v => ({ label: v, value: v }))}
value=${msgVariant} onChange=${setMsgVariant} />
<input class="sw-input" style="width:140px" placeholder="text..."
value=${msgText} onInput=${e => setMsgText(e.target.value)} />
`}
<${Button} variant=${footerOn ? 'primary' : 'secondary'} size="sm"
onClick=${() => setFooterOn(!footerOn)}>Footer<//>
</div>
`;
}
function DevRoot() {
const [page, setPage] = useState('primitives');
const [bannerOn, setBannerOn] = useState(false);
const [msgOn, setMsgOn] = useState(false);
const [footerOn, setFooterOn] = useState(false);
const [bannerVariant, setBannerVariant] = useState('info');
const [msgVariant, setMsgVariant] = useState('info');
const [bannerText, setBannerText] = useState('');
const [msgText, setMsgText] = useState('');
const banner = bannerOn ? { text: bannerText || 'Banner', variant: bannerVariant } : null;
const msg = msgOn ? { text: msgText || 'Message', variant: msgVariant } : null;
return html`
<${AppShell}
banner=${banner}
message=${msg}
footer=${footerOn ? html`Switchboard Core · Layer 1 Shell` : null}
>
<div class="dev-root">
<nav class="dev-nav">
<button class=${page === 'primitives' ? 'active' : ''} onClick=${() => setPage('primitives')}>Primitives</button>
<button class=${page === 'shell' ? 'active' : ''} onClick=${() => setPage('shell')}>Shell</button>
<button class=${page === 'sdk' ? 'active' : ''} onClick=${() => setPage('sdk')}>SDK</button>
<button class=${page === 'surfaces' ? 'active' : ''} onClick=${() => setPage('surfaces')}>Surfaces</button>
<div style="flex:1" />
<${ShellControls} ...${{
bannerOn, setBannerOn, bannerVariant, setBannerVariant, bannerText, setBannerText,
msgOn, setMsgOn, msgVariant, setMsgVariant, msgText, setMsgText,
footerOn, setFooterOn
}} />
</nav>
<div class="dev-page">
${page === 'primitives' && html`<${PrimitivesPage} />`}
${page === 'shell' && html`<${ShellPage} />`}
${page === 'sdk' && html`<${SDKPage} />`}
${page === 'surfaces' && html`<${SurfacesPage} />`}
</div>
</div>
<//>
<${ToastContainer} />
<${DialogStack} />
`;
}
render(html`<${DevRoot} />`, document.getElementById('app'));
} catch(e) { console.error('DEV:', e); }
})();
</script>
</body>
</html>

View File

@@ -37,9 +37,6 @@ const SHELL_FILES = [
'./css/sw-notes-surface.css',
// JS — debug tooling (v0.37.18: repl.js absorbed into Preact debug components)
'./js/debug.js',
// Vendor
'./vendor/marked.min.js',
'./vendor/purify.min.js',
// Static assets
'./favicon.svg',
'./favicon-light.svg',

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long