Commit Graph

169 Commits

Author SHA1 Message Date
Jeff Emmett 0f3eb45ffa feat(canvas): register social shapes in shape registry for cross-rApp sharing
Import, define, and register folk-social-thread, folk-social-campaign,
and folk-social-newsletter in canvas.html so they're available on any
canvas across rSpaces, rSchedule, rFlows, etc.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 20:12:27 -07:00
Jeff Emmett cd6317fd06 fix(canvas): mobile toolbar positioning — anchor to bottom-right, clear zoom icon
- Keep side toolbar at bottom: 8px in both open and collapsed states
  so the minimize/maximize toggle stays in the same spot
- Shift bottom-toolbar left (left: 56px) to clear the corner-tools
  zoom icon and prevent overlap with the selector tool

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 18:09:26 -07:00
Jeff Emmett dce608ae1b fix: cache-bust sw.js registration + no-cache header for SW/manifest
- Add ?v=4 to all SW registration URLs to bypass stale CF CDN cache
- Set Cache-Control: no-cache for sw.js and manifest.json so future
  SW updates are never blocked by CDN caching

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 18:02:14 -07:00
Jeff Emmett 8d4e1fd0ff fix(mi,canvas): filter disabled modules from MI assistant and eliminate app-switcher flash
MI now loads space doc to filter module list, capabilities, and fallback
by enabledModules. Canvas fetches /api/modules and space modules in
parallel via Promise.all, calling setModules once with filtered list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 17:26:07 -07:00
Jeff Emmett 0d7c6d08b3 fix(canvas): mobile touch — first touch moves, long-press selects, extra-long opens context menu
Three-tier touch interaction on mobile canvas:
- Immediate drag on finger movement (8px threshold)
- Long press (500ms) selects shape with haptic feedback
- Extra long press (1000ms) opens context menu
- Cancel timers on movement or two-finger gesture

Skip pointerdown selection for touch events in canvas.html,
handle via touch-select custom event from folk-shape instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 16:58:11 -07:00
Jeff Emmett 4a75c64a18 feat(rdesign): rich landing page, Scribus canvas tool, icon update
- Replace minimal rDesign landing with full rl-* pattern (hero, features,
  how-it-works, capabilities, open source, data protection, CTA)
- Add Scribus button to Create toolbar group in canvas (folk-design-agent)
- Export FolkDesignAgent from lib/index.ts, register in canvas.html
- Update module icon from 🎯 to 🎨 (matches favicon + MODULE_META)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 16:51:31 -07:00
Jeff Emmett 6b81f808f5 feat(canvas): mobile toolbar flush, zoom icon toggle, SW update banner
- Mobile toolbar collapsed position now flush with bottom-toolbar (bottom: 8px)
- Toolbar defaults to collapsed on mobile (<768px)
- Zoom expand/minimize uses distinct icons (magnifier +/-) instead of CSS rotation
- SW update banner on all pages: "New version available — Tap to update"
  - Detects controllerchange + updatefound events
  - Purple gradient bar, dismissible, reloads on tap
  - Added to both shell.ts (module pages) and canvas.html (standalone)
- folk-rapp: filter picker/switcher by enabled modules
- server/shell: react to modules-changed event for runtime module toggling
- collab-presence: minor overlay updates

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 16:34:48 -07:00
Jeff Emmett 1a422f06ac feat(canvas): add first-time forgotten shapes explainer tooltip
Shows a one-time onboarding tooltip when users first encounter a faded
(forgotten) shape. Explains right-click to remember/forget permanently,
the Hide Forgotten toggle in profile menu, and highlights the Collective
Memory graph as a prototype feature. Persisted via localStorage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 16:09:05 -07:00
Jeff Emmett 496dff3c7f feat(rtrips): add in-module AI planner with split-view chat + canvas export
"Plan with AI" now opens a split-view within rTrips instead of redirecting
to the canvas. Left panel: chat with model selector. Right panel: generated
trip cards (destinations, itineraries, budgets, packing lists) with
accept/discard flow. Demo mode provides realistic mock responses for Japan,
Europe, and beach queries. Accepted items export to canvas via sessionStorage
+ #trip-import hash handler.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 18:21:40 -07:00
Jeff Emmett 3f496d9fc6 feat(rnotes,canvas): comments in demo mode, emoji reactions, reminders + inline picker modal
- rNotes comments now work in demo mode via in-memory thread storage
- Added emoji reactions (7-emoji palette) and date reminders on comment threads
- Reminders integrate with rSchedule API for persistent notifications
- Canvas toolbar: split Note into "Blank Note" (always available) and "From rNotes" (picker)
- Replaced browser prompt()-based pickFromList with showPickerModal (dark-themed, searchable, keyboard nav)
- Updated pickTrip, destination, and booking handlers to use the new modal

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 17:53:06 -07:00
Jeff Emmett 1ae0609f14 perf(canvas): batch bulk forget into single Automerge transaction
The bulk forget dialog was freezing because each shape triggered a
separate Automerge change, IndexedDB write, and WebSocket sync. New
bulkForget() method batches all shapes into one transaction with DOM
updates applied immediately for responsiveness.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 17:52:11 -07:00
Jeff Emmett cefc1aa5b7 fix(collab): rename Solo/Share to Online/Offline, use EncryptID usernames
Swap toggle labels to Online/Offline (more intuitive). Resolve canvas
peer usernames from encryptid_session instead of rspace-username fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 17:45:55 -07:00
Jeff Emmett 1cbee3e4d1 fix(canvas): absolute drag positioning + remove Move Here drop ghosts
Replace movementX/Y delta accumulation with absolute mouse-to-shape offset
tracking for drift-free drag. Remove drop suggestion overlay system entirely.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 17:42:50 -07:00
Jeff Emmett eea3443cba feat(canvas): collective forgetting UX + memory graph view
Rename all "Delete" labels to "Forget permanently" to align with the
three-state memory model (present → forgotten → deleted). Add explainer
blurb in memory panel. New Collective Memory graph view — force-directed
bubble chart showing shape remembrance scores sized by how many members
still remember each shape, with click-to-navigate.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 17:31:46 -07:00
Jeff Emmett 8f1ad52557 feat(collab): unify header & tab-row — shared people-panel across all rApps
Canvas now uses the same rstack-collab-overlay component as all other
rApps instead of its own custom #people-online-badge. Header restructured
to match renderShell() layout (history/settings in dropdown-wraps on left).
Bridge API (updatePeer/removePeer/setConnState/clearPeers) lets canvas
feed CommunitySync peers into the shared component.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 11:46:26 -07:00
Jeff Emmett 79f16925aa fix(canvas): remove TS cast from inline script (Vite builds as JS)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 19:25:18 -07:00
Jeff Emmett aa4a200f32 feat(history): add "Revert to this point" button in Time Machine panel
Forward Automerge change that overwrites content fields with snapshot data,
preserving meta and full history. Also fixes pre-existing TS errors in
folk-flow-river (undefined exitX) and test-full-loop (StepResult type).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 19:08:15 -07:00
Jeff Emmett 6bda676680 fix(canvas): add missing comment-bell HTML tag to canvas header
The JS import and define() were added but the actual
<rstack-comment-bell> element was missing from canvas.html's
header HTML (which is separate from server/shell.ts).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 17:21:38 -07:00
Jeff Emmett 6cb82f3098 fix(canvas): register rstack-comment-bell in canvas.html imports
Canvas.html has its own component import list separate from shell.js.
The comment bell was missing, so the custom element never initialized.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 16:32:24 -07:00
Jeff Emmett 6ec9f5ec61 fix(canvas): prevent drag/snap/selection on shape content interactions
FolkShape now uses stopImmediatePropagation for pointerdown on non-drag
targets (scrollable content, inputs, buttons) so canvas selection and
snap listeners don't fire. Canvas capture-phase listener now checks
composedPath to only track actual drag targets (host, handles, headers).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 16:15:43 -07:00
Jeff Emmett afd2a5a40b fix(canvas): persistent drawing tools + online/offline label + drag fixes
Drawing/shape tools (pencil, line, rect, circle) now stay active for
multiple strokes instead of resetting to selector after each use.
Renamed collab overlay badge from "Solo/Share" to "Offline/Online".
Prevent canvas drag when interacting with image-gen and prompt content.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 16:03:15 -07:00
Jeff Emmett cb92a7f6d8 feat(rtrips): AI trip planner — canvas tools + "Plan with AI" button
Register 5 trip-specific tools (destination, itinerary, booking, budget,
packing list) in canvas-tools.ts so Gemini can create trip shapes.
Add public toolsEnabled/systemPrompt properties to folk-prompt with
persistence. Add #trip-planner hash handler to canvas.html that auto-
creates a pre-configured AI prompt. Add "Plan with AI" gradient button
to rTrips list and detail views.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 14:32:28 -07:00
Jeff Emmett f5de97c60c feat(ux): move comment button to header bar with unresolved badge
Move the "Leave Comment" button from the bottom canvas toolbar to the
top header bar as <rstack-comment-bell>, positioned left of the
notification bell. Shows a red badge with unresolved comment pin count.
Wires canvas via comment-pin-activate/comment-pins-changed custom events.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 14:02:27 -07:00
Jeff Emmett 38053eee34 fix(notes): prevent deletion while editing, fix layout, add semantic zoom
- Fix Delete/Backspace deleting the note shape when editing text inside
  it. The canvas keydown handler now uses composedPath() to detect
  inputs inside Shadow DOM (textarea, title input). Also fixes Space
  key and Ctrl+Z being intercepted by canvas while typing.
- Stop all keydown propagation from the editor/title inputs to prevent
  arrow keys from moving the shape while editing.
- Fix layout: replace calc(100%-36px) with proper flex layout. Header,
  toolbar, footer are flex-shrink:0; editor fills remaining space.
  Fixes headers being cut off and weird sizing.
- Add semantic zoom: icon-only (<0.3x), summary (0.3-0.7x), full
  editor (>0.7x). Reads --canvas-scale CSS custom property set by
  updateCanvasTransform().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 13:48:08 -07:00
Jeff Emmett 83fa874147 fix(ux): show offline only on actual disconnection, add resync tooltip
- Badge now reflects real connection state: "N online", "Reconnecting…", or "Offline"
- Removed manual online/offline toggle (was confusing — showed both states)
- Panel Solo/Share toggle remains for cursor visibility preference
- Hover tooltip on badge when offline: "changes saved locally, will resync"
- Panel shows offline/reconnecting notice banner when disconnected
- Removed unused #people-conn-status element and CSS

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 13:39:08 -07:00
Jeff Emmett b91233092b fix(ux): move people-online badge into sub-tab header bar
- Move people badge + panel from fixed position to inline in .rstack-tab-row
- Badge sits right of the layer toggle icon with a subtle separator
- Panel drops down from badge position instead of floating fixed
- Online/Offline toggle replaces Solo/Multi labels for clarity
- Badge shows "Offline" with gray dot when in offline mode
- Mobile: hide text label, show dots only
- Tab bar gets flex:1 + min-width:0 to share row space

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 13:29:45 -07:00
Jeff Emmett d458a00550 fix(ux): instant bulk-delete dialog + post-login space routing
Bulk delete dialog: switch from click to pointerdown for instant
touch response, raise z-index above all overlays, add hover/active
feedback and keyboard support.

Post-login routing: reload page when logging in on a non-demo space
so access gates clear and CRDT sync reconnects with auth. Silently
provisions personal space in background.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 13:21:03 -07:00
Jeff Emmett 34a7a4e37e fix(canvas): mobile toolbar to right, persistent lock badge, reminder auth
- Move mobile toolbar to right side to avoid zoom bar overlap
- Toolbar panel opens leftward, bottom toolbar offsets flipped
- Add [locked] attribute reflection on folk-shape for external CSS
- Persistent 🔒 badge on locked shapes visible when unselected
- Add Authorization header to calendar reminder POST request

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 20:13:15 -07:00
Jeff Emmett e2c6275308 fix(canvas): comment pin tool state management + shape detection bug
- Fix elementFromPoint using canvas-relative coords instead of viewport
  coords for shape detection during pin placement
- Use shape data from Automerge doc for offset calculation (more reliable)
- Add exitCommentMode() to deactivate pin placement when switching tools
- Integrate comment mode into syncBottomToolbar active state
- Escape key closes popover and exits comment mode
- Mutual exclusion between comment/draw/connect/pending tool modes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 19:28:51 -07:00
Jeff Emmett 07e3c7348c feat(canvas): add Figma-style comment pin system
Overlay markers at canvas or shape-relative coords with threaded
comments, @mention notifications, and rSchedule reminder integration.
Toolbar "Leave Comment" button (/) next to Note tool.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 18:47:03 -07:00
Jeff Emmett 2c0fbb76ac fix(canvas): add auth headers to API fetches + deduplicate sync events
- Add Authorization header to fetchTripData, fetchTripDetail, and
  fetchNotesData to prevent 401 errors on private spaces
- Add #initialSyncFired flag to CommunitySync so the "synced" event
  only fires once per connection cycle instead of on every debounce gap

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 16:28:58 -07:00
Jeff Emmett 2de61cd7ad feat(rcal): move zoom/legend below calendar, add multi-day event spans
- Reorder layout: nav → calendar → legend → zoom bars → bottom bar
- Add "Calendar Legend" heading above source badges
- Fix getEventsForDate() to support multi-day range checking
- Render colored span bars across day cells for multi-day events
- Make showAccountModal/isSignedIn public on rstack-identity
- Tour final step triggers identity setup flow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 15:10:39 -07:00
Jeff Emmett ac402c29e9 feat(canvas): replace repulsion with snap guides + drop suggestion
Remove ambient repulsion loop (shapes drifting apart at 60fps). Add
Figma-style snap alignment guides during drag with magnetic stickiness,
and ghost drop suggestion when shapes overlap after drop.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 14:28:32 -07:00
Jeff Emmett 4b08a02851 fix(seed): prevent demo data re-seeding after user deletes content
Added a `seeded` flag to Automerge doc metadata across 6 modules
(rcal, rnotes, rtasks, rvote, rbnb, rvnb). Once demo data is seeded,
deleting all content no longer triggers re-seeding on next page load.

Also removed rcal's per-request seedDemoIfEmpty() call from the route
handler — onInit + seedTemplate already handle initial seeding.

fix(canvas): prevent bulk delete dialog from stacking

The Delete key repeat was creating multiple overlays, making the dialog
appear unclosable. Added a guard to prevent duplicate dialogs, and
Escape key support to dismiss.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 14:24:51 -07:00
Jeff Emmett fe7157ffe1 fix(shell): position settings/history panels below their buttons
Both panels now use position:fixed with JS-computed coordinates from
getBoundingClientRect(), ensuring they open directly below their
respective header buttons and right-aligned to the button edge.
History panel clamps left edge to prevent off-screen overflow.

Also adds missing click handlers for settings-btn and history-btn
in canvas.html (previously only wired in shell.ts module pages).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 13:59:44 -07:00
Jeff Emmett e0f0426e59 fix(canvas): limit separation dynamics to rApps/embeds, not drawings/slides
- Add folk-shape to pushExemptTags so wb drawings (pencil, rect, circle,
  line) are exempt from repulsion and can overlap other shapes freely
- Skip wb-drawing elements in repulsion loop and free-position placement
- Locked shapes are not pushed by repulsion (full push goes to unlocked neighbor)
- getExistingShapeRects uses pushExemptTags instead of hardcoded arrow check

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 13:25:27 -07:00
Jeff Emmett 842ac4d67e feat(canvas): eraser works on all shapes, add lock icon for shapes
- Eraser now targets any folk-shape (not just wb-drawing), erasing whatever it touches
- Added lock property to folk-shape: locked shapes can't be moved, resized, or erased
- Lock state persisted via Automerge sync (toJSON/applyData/fromData)
- Lock icon appears beside calendar icon when shape(s) selected, toggles lock on click

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 13:19:54 -07:00
Jeff Emmett e56b4fe89c fix(canvas): hide feed toggle on mobile corner tools
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 22:31:58 -07:00
Jeff Emmett 9b0a672c7b feat(canvas): add Ctrl+Z undo / Ctrl+Shift+Z redo for shape operations
Local inverse-change stack that records before-snapshots of each mutation
and applies forward Automerge changes to restore state on undo. Batches
rapid same-shape changes (<500ms) so drags produce a single undo entry.
Supports create, move/resize, forget, remember, and hard-delete operations.
Max 50 entries, redo stack clears on new changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 22:31:22 -07:00
Jeff Emmett 15f7e759d1 fix(canvas): map shape interaction + reminder widget dismissal
Map viewer: disable MapLibre interactions when inside a folk-shape
until editing mode (double-click). Prevents map panning when trying
to select/move the shape on canvas.

Reminder widget: dismiss on Escape key and when clicking elsewhere
on canvas (deselecting shapes). Clean up schedule icon when shape
is deleted.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 20:44:28 -07:00
Jeff Emmett d5e822ec7c fix(canvas): remove duplicate settings/history button handlers
Canvas.html had its own addEventListener calls for settings-btn and
history-btn, but the shell script already wires these. Both handlers
fired on click, causing double-toggle (open then immediately close).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 20:39:32 -07:00
Jeff Emmett 355b53ee17 fix(canvas): hide toolbar items for disabled modules
Inject enabledModules into client, tag 25 module-specific toolbar buttons
with data-requires-module, and filter out disabled items (plus empty groups)
at page init. Spaces with all modules enabled are unaffected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 20:36:10 -07:00
Jeff Emmett ee1a791aea fix(canvas): move offline status to people badge, toolbar minimize to bottom, zoom to bottom-right
- Offline/reconnecting indicator now shows inside the "N online" people
  badge instead of the shell header (hidden on canvas via CSS override)
- Toolbar collapse/minimize button moved from top to bottom of toolbar
  stack so it sits where the last tool icon was
- Zoom controls moved from bottom-left to bottom-right; on mobile they
  sit above the bottom toolbar to avoid overlap

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 18:22:39 -07:00
Jeff Emmett 36e76449fa fix(canvas): prevent horizontal overflow on mobile
- Add overflow:hidden on html element for canvas-layout pages
- Bottom toolbar: constrain to viewport with right:8px, horizontal
  scroll for overflow buttons, flex-shrink:0 on items
- Context menu: clamp position to viewport bounds
- Modal panels: use min() for min-width to respect small screens

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 18:17:27 -07:00
Jeff Emmett 448b68eb62 feat(tour): replace static welcome popup with guided feature tour
Replaces the "Welcome to rSpace" popup with a 6-step interactive tour
that spotlights key UI features (app switcher, MI bar, spaces, identity,
canvas, tabs/tools). Skippable at any time via button, Escape, or
clicking the backdrop. Navigable with Back/Next buttons and arrow keys.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 16:42:20 -07:00
Jeff Emmett 77f2e9ae56 fix(rpubs): allow public PDF generation + fix zine auto-spawn
- Add publicWrite to rpubs module (PDF gen is computational, not a write)
- Fix zine auto-spawn: wait for community-sync-ready event instead of
  fragile 800ms timeout

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 22:20:08 -07:00
Jeff Emmett c23d7eb65b fix(canvas): reminder widget expands from schedule icon position
Instead of popping up at fixed top-right, the reminder mini-calendar
now appears at the 📅 icon's location and scales out from it.
Icon hides while widget is open, reappears on close.
Viewport-clamped to prevent off-screen overflow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 21:54:50 -07:00
Jeff Emmett 92df7d332d fix(canvas): only show reminder calendar on icon click, not on shape select/drag
Remove the auto-opening calendar on shape selection and the drag-to-calendar
compact mode. The 📅 icon on selected shapes remains as the entry point.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 11:15:18 -07:00
Jeff Emmett 9b81ba70b6 feat(shell): add share button to global header with QR, copy link, email invite
Extract canvas inline share panel into reusable <rstack-share-panel> web component
and add it to the shell header between notification bell and settings gear. Canvas
now uses the component too, removing ~230 lines of inline HTML/CSS/JS.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:51:21 -07:00
Jeff Emmett 05b8e2676a fix(canvas): mobile toolbar uses collapse instead of FAB overlay
Replace the floating action button toggle with the same collapse/expand
behavior as desktop. Toolbar sits as a compact icon column on the left,
panels open to the right, and corner tools move to bottom-right.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:30:20 -07:00